Java 2D游戏开发:多键输入

时间:2013-04-07 16:57:06

标签: java swing jpanel java-2d keylistener

我正在努力让控件适用于用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

1 个答案:

答案 0 :(得分:3)

  

每当我试图在射击时使用向上和向左控制(空格键),或者在射击时向下和向右使用向上和向右,游戏都无法检测到按空格键。

仅为按下的最后一个键生成KeyEvents。如果您想同时处理多个键,则需要:

  1. 跟踪已按下/已释放的键
  2. 使用Swing Timer来安排动画。
  3. 然后每当计时器触发时,检查当前按下了哪些键,并为该键执行操作。