【问题标题】:Java: Problems with KeyListener in a Space Invaders gameJava:Space Invaders 游戏中的 KeyListener 问题
【发布时间】:2016-02-16 11:14:26
【问题描述】:

我正在尝试在 Java 中的 Space Invaders 游戏中实现 KeyListener 来移动飞船(现在,它只是一个红色矩形)。

我认为它实现得很好,但我无法让它工作。

这是那艘船的:

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;
    }  

}  

}

这是窗口的一个:

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) {}

}

最后这是包含游戏循环的类:

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);

}

}

我不知道错误可能出在哪里,也许在循环中……我不知道。

问题是我怎样才能固定它以使用键盘移动船? 这个 Space Invaders 是一个家庭作业,我不得不使用 KeyListener...我怎样才能让它工作?

【问题讨论】:

  • 没修好,没用。
  • “它不修复,它不起作用。” 哦,对,是的,我的意思是修复我建议的编辑。更多提示:1) 为了尽快获得更好的帮助,请发布minimal reproducible exampleShort, Self Contained, Correct Example。 2) 提示:添加@trashgod(或重要的@)以通知此人有新评论。 (我怀疑他们是否注意到了你必须使用KeyListener 进行家庭作业的编辑。)

标签: java swing keylistener actionevent


【解决方案1】:

我找到了答案。

问题是“Finestra”类在读取键之前退出了“播放”函数(因此循环开始)。

追订单就够了:

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.
}

【讨论】:

  • “我找到了答案。” 很高兴你把它整理好了。 :) 很好的一个,可以自行解决并通过修复报告。
【解决方案2】:

查看您的关键事件处理程序:

@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;
}

它会改变你船上(中殿)上一个名为“v”的变量。

那么你船上的movimiento(可能是'move')方法使用另一个变量velocidad。它完全忽略了 v!

删除变量 v 并使用 velocidad

另外,您只能在敌舰上调用movimiento,而不是在您玩家的舰船上!所以很自然,它永远不会移动。

【讨论】:

  • 谢谢,但它没有t work. The "movimiento" method just make the ship moves uncontrollably, thats 为什么我使用新变量“v”来控制新运动(事实上,“movimiento”不在循环中的 movimients 方法中)。
猜你喜欢
  • 2018-10-04
  • 1970-01-01
  • 2021-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-12
  • 1970-01-01
相关资源
最近更新 更多