1

I'm trying to get the controls working for a 2D game written in Java. However, I'm encountering an odd bug in movement. Whenever I'm trying to use the up and left controls while firing (space bar), or down and right while firing, the game is unable to detect the pressing of the space bar. Below are the relevant code excerpts:

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

And

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
mKorbel
  • 109,525
  • 20
  • 134
  • 319

1 Answers1

3

Whenever I'm trying to use the up and left controls while firing (space bar), or down and right while firing, the game is unable to detect the pressing of the space bar.

KeyEvents are only generated for the last key pressed. If you want to handle multiple keys being pressed at the same time then you need to:

  1. keep track of a key that has been pressed/released
  2. use a Swing Timer to schedule the animation.

Then whenever the timer fires you check which keys are currently pressed and the do the action for that key.

camickr
  • 321,443
  • 19
  • 166
  • 288