2013-04-07 131 views
1

我试图让用Java编写的2D游戏的控件工作。但是,我遇到了一个奇怪的运动错误。每当我试图在发射时使用向上和向左控件(空格键),或者在发射时向下和向右使用游戏时,游戏无法检测到按下空格键。下面是相关的代码摘录:Java 2D游戏开发:多键输入

import java.awt.Image; 
import java.awt.event.KeyEvent; 
import java.util.ArrayList; 
import javax.swing.ImageIcon; 

public class Player { 
    private String playerPath = "images/craft.png"; 
    private int x, y, dx, dy; 
    private Image image; 
    private ArrayList missiles; 
    private final int CRAFT_SIZE = 20; 

    public Player() { 
     ImageIcon ii = new ImageIcon(playerPath); 
     image = ii.getImage(); 
     missiles = new ArrayList(); 
     x = 20; 
     y = 20; 
    } 
    public void keyPressed(KeyEvent e) { 
     int key = e.getKeyCode(); 
     if (key == KeyEvent.VK_SPACE) { 
      fire(); 
     } 
     if (key == KeyEvent.VK_LEFT) { 
      dx = -1; 
     } 
     if (key == KeyEvent.VK_RIGHT) { 
      dx = 1; 
     } 
     if (key == KeyEvent.VK_UP) { 
      dy = -1; 
     } 
     if (key == KeyEvent.VK_DOWN) { 
      dy = 1; 
     } 
    } 
    public void keyReleased(KeyEvent e) { 
     int key = e.getKeyCode(); 
     if (key == KeyEvent.VK_LEFT) { 
      dx = 0; 
     } 
     if (key == KeyEvent.VK_RIGHT) { 
      dx = 0; 
     } 
     if (key == KeyEvent.VK_UP) { 
      dy = 0; 
     } 
     if (key == KeyEvent.VK_DOWN) { 
      dy = 0; 
     } 
    } 
    public void fire() { 
     missiles.add(new Projectile(x + CRAFT_SIZE, y + CRAFT_SIZE/2)); 
    } 
}//end class Player 

而且

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Toolkit; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyAdapter; 
import java.awt.event.KeyEvent; 
import java.util.ArrayList; 
import javax.swing.JPanel; 
import javax.swing.Timer; 

public class Game extends JPanel implements ActionListener { 
    private Player player; 
    private Timer timer; 

    private int winHeight; 
    private int winWidth; 
    private final int UP = KeyEvent.VK_UP; 
    private final int DOWN = KeyEvent.VK_DOWN; 
    private final int LEFT = KeyEvent.VK_LEFT; 
    private final int RIGHT = KeyEvent.VK_RIGHT; 
    private final int SPACE = KeyEvent.VK_SPACE; 

    public Game(int w, int h) { 
     addKeyListener(new TAdapter()); 
     setBackground(Color.BLACK); 
     addKeyListener(new TAdapter()); 
     setFocusable(true); 
     setDoubleBuffered(true); 

     player = new Player(); 

     winHeight = h; 
     winWidth = w; 

     timer = new Timer(5, this); 
     timer.start(); 
    } 

    @Override 
    public void paint(Graphics g) { 
     super.paint(g); 

     Graphics2D g2d = (Graphics2D) g; 
     g2d.drawImage(player.getImage(), player.getX(), player.getY(), this); 

     ArrayList proj = player.getMissiles(); 

     for (Object p : proj) { 
      Projectile b = (Projectile) p; 
      g2d.drawImage(b.getImage(), b.getX(), b.getY(), this); 
     } 

     Toolkit.getDefaultToolkit().sync(); 
     g.dispose(); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 

     // Update projectile locations 
     ArrayList ms = player.getMissiles(); 

     for (int i = 0; i < ms.size(); i++) { 
      Projectile p = (Projectile) ms.get(i); 
      if (p.getX() <= winWidth) { 
       p.move(); 
      } else { 
       ms.remove(p); 
      } 
     } 
     player.move(); 
     repaint(); 
    } 

    private class TAdapter extends KeyAdapter { 
     @Override 
     public void keyReleased(KeyEvent e) { 
      player.keyReleased(e); 
     } 

     @Override 
     public void keyPressed(KeyEvent e) { 
      player.keyPressed(e); 
     } 
    }// end class TAdapter 
}// end class Game 

回答

3

每当我试图同时发射(空格键),或向下和向右,而发射使用起来就走了控制,游戏无法检测到空格键的按下。

KeyEvents仅在按下最后一个键时生成。如果你想处理被压在同一时间多个键,那么你需要:

  1. 已按下某个键的跟踪/发布
  2. 使用一个Swing计时器来安排动画。

然后,每当定时器启动时,您检查哪些键当前被按下,并执行该键的操作。

+0

另请参阅此[示例](http://stackoverflow.com/a/14001011/230513)。 – trashgod 2013-04-07 20:42:47