我试图在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;
}
}
}
这是Window的一个:
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);
}
}
我不知道错误可能在哪里,也许是在循环中......我不知道。
问题是我如何修理它可以使用键盘移动船? 这个太空入侵者是一个家庭作业,我有义务使用KeyListener ......我怎样才能使它有效?
答案 0 :(得分: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.
}
答案 1 :(得分:0)
查看您的关键事件处理程序:
@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
(可能是“移动”)方法使用另一个变量velocidad
。它完全忽略了v!
删除变量v并使用velocidad
。
此外,你只能在你的敌舰上召唤movimiento
,而不是在你的玩家的船上!很自然,它永远不会移动。