简体   繁体   English

Java:Space Invaders游戏中的KeyListener问题

[英]Java: Problems with KeyListener in a Space Invaders game

I'm trying to implement a KeyListener in a Space Invaders game in Java to move the ship (by now, it's just a red rectangle). 我试图在Java的Space Invaders游戏中实现KeyListener来移动飞船(到目前为止,它只是一个红色矩形)。

I think it's fine implemented, but i can't make it works. 我认为可以很好地实现,但是我无法使其正常工作。

Here is the ship's one: 这是船上的:

import java.awt.Color;  
import java.awt.Graphics;  

public class Nave{

int x, y;
int AnchoNave = 40, AltoNave = 40;  // WIDTH_SHIP and HIGH_SHIP
Finestra f;                         // WINDOW
int velocidad = 4, v = 0;           // VELOCITY
Joc j;

Nave(Finestra f, int x, int y){
    this.f = f;
    this.x = x;
    this.y = y;
}

void pintaNave(Graphics g){

    g.setColor(Color.RED);
    g.drawRect(x, y, AnchoNave, AltoNave);
    g.setColor(Color.RED);
    g.fillRect(x, y, AnchoNave, AltoNave);

}

void movimiento(){  // this is not in the loop now.

    x+=velocidad;
    if (x>f.AMPLE-AnchoNave-10){
        x=0;
    }  

}  

}

Here is the Window's one: 这是窗口的一个:

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.*;
import javax.swing.JFrame;

public class Finestra extends JFrame implements ActionListener,  KeyListener{

Image im;
Graphics g;
int AMPLE=600,ALT=500;     // WIDTH and HIGH
Joc j;

Nave nave;                 // Nave = SHIP
int velocidad = 10;        // VELOCITY

public static void main(String[] args) {
    new Finestra();        // Finestra = WINDOW
}

Finestra(){

    super("-+- Space Invaders -+-");
    setVisible(true);
    setSize(AMPLE,ALT);
    im=this.createImage(AMPLE, ALT);
    g=im.getGraphics();
    j=new Joc(this);
    j.playing();
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setResizable(false);

    addKeyListener(this);
    setFocusable(true);
    setFocusTraversalKeysEnabled(false);
}

public void update(Graphics g) {
    paint(g);
}

public void paint(Graphics g) { 
    g.drawImage(im, 0,0, null); 
}


@Override
public void actionPerformed(ActionEvent e) {
    j.nave.x =j.nave.x + j.nave.v;
    repaint();  
}  

@Override
public void keyPressed(KeyEvent e) {
    int tecla = e.getKeyCode();
    if (tecla == KeyEvent.VK_RIGHT)
        j.nave.v = +10;
    if (tecla == KeyEvent.VK_LEFT)
        j.nave.v = -10;
    }

@Override
public void keyReleased(KeyEvent e) {
    j.nave.v = 0;
}

@Override
public void keyTyped(KeyEvent e) {}

}

And finally this is the class that contains the loop of the game: 最后,这是包含游戏循环的类:

import java.awt.Color;
import java.awt.Graphics;

public class Joc{


Finestra f;                 // WINDOW
Enemigos c1[];              // ENEMIES
Nave nave;                  // SHIP

Joc(Finestra f){            // JOC = GAME
    this.f=f;
}
void playing() {
    initicalitzaJoc();
    do {
        moviments();           // MOVEMENTS
        detectaColisions();    // COLLISION DETECTION
        pintarPantalla(f.g);   // PAINT SCREEN
        f.repaint();

        try {
            Thread.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }           
    }while(true);
}

private void detectaColisions() { 
} 

private void moviments() {  
    for(int i=0;i<c1.length;i++)
        c1[i].movimiento(); 
}

private void initicalitzaJoc() {        

    c1 = new Enemigos[15];                 // ENEMIES

    for (int i=0; i<5; i++)
        c1[i] = new Enemigos(f, 100+i*80, 100, 5);
    for (int i=5; i<10; i++)
        c1[i] = new Enemigos(f, 100+(i-5)*80, 150, 5);
    for (int i=10; i<15; i++)
        c1[i] = new Enemigos(f, 100+(i-10)*80, 200, 5);

    // Nave del jugador:                    // PLAYER'S SHIP
    nave = new Nave(f,300-40/2, 500-40-5);

}

void pintarPantalla(Graphics g) {   

    g.setColor(Color.WHITE);
    g.fillRect(0, 0, 600,500);

    for (int i=0; i<5; i++)         
        c1[i].pinta(g,1);;
    for (int i=5; i<10; i++)
        c1[i].pinta(g,3);
    for (int i=10; i<15; i++)
        c1[i].pinta(g,6);       

    nave.pintaNave(g);

}

}

I don't know where the mistake could be, maybe in the loop... i don't know. 我不知道错误可能在哪里,也许在循环中……我不知道。

The question is how can i fixed it to can move the ship using the keyboard? 问题是我该如何修复它才能使用键盘移动飞船? This Space Invaders is a homework, I'm obliged to use the KeyListener... How can I make it works ? 这个太空入侵者是一项家庭作业,我不得不使用KeyListener ...如何使它起作用?

I'have found the answer. 我找到了答案。

The problem was that the class "Finestra" ejecute the function "playing" (so the loop starts) before reading the keys. 问题在于,“ Finestra”类在读取键之前会释放“播放”功能(因此循环开始)。

It's enough chasing the order: 追订单就足够了:

Finestra(){

    super("-+- Space Invaders -+-");
    setVisible(true);
    setSize(AMPLE,ALT);
    im=this.createImage(AMPLE, ALT);
    g=im.getGraphics();
    j=new Joc(this);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setResizable(false);

    addKeyListener(this);
    setFocusable(true);
    setFocusTraversalKeysEnabled(false);
    System.out.println("hola");
    j.playing();  // enter the loop after reading the keys.
}

Looking at your key event handler: 查看您的关键事件处理程序:

@Override
public void keyPressed(KeyEvent e) {
  int tecla = e.getKeyCode();
  if (tecla == KeyEvent.VK_RIGHT)
    j.nave.v = +10;
  if (tecla == KeyEvent.VK_LEFT)
    j.nave.v = -10;
}

It changes a variable called 'v' on your ship (nave). 它会在您的飞船上更改一个名为“ v”的变量(nave)。

Then your movimiento (presumably 'move') method on your ship uses another variable, velocidad . 然后,您在movimiento (大概是“ move”)方法使用了另一个变量velocidad It completely ignores v! 它完全忽略了v!

Delete the variable v and just use velocidad . 删除变量v并仅使用velocidad

Also, you only ever call movimiento on your enemy ships, never on your player's ship! 而且,您只会在敌方船只上呼叫movimiento ,而不会在玩家的船只上呼叫movimiento So naturally, it never moves. 自然,它永远不会动。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM