DNX
DNX

Reputation: 31

Java keyReleased worked fine but keyPressed lost control

I am recently making a game and I met a problem. When I pressed the WASD keys, sometimes there were no responds, however when I pressed left arrow key or right arrow key it worked well. Also, I tried to use System.out.println() in both KeyPressed and keyReleased to debug and I noticed that when there were no responds, there was no printed`` message in keyPressed but in keyReleased. This problem really confused me.

I use JFrame for the game and I only add a Canvas into JFrame. And I added keyListener for both JFrame and Canvas(I tried to remove one of them and requestFocus but the problem still not solved).

Here is a piece of code.
For the keyPressed:

@Override
public void keyPressed(KeyEvent e) {
    //When keyPressed lost control, this line did not even work
    System.out.println("key pressed");
    if(e.getKeyCode() == KeyEvent.VK_A){
        left = true;
    }
    else if(e.getKeyCode() == KeyEvent.VK_D){
        right = true;
    }
    else if(e.getKeyCode() == KeyEvent.VK_SPACE){
        jump();
    }
    else if(e.getKeyCode() == KeyEvent.VK_LEFT){
        attackLeft = true;
    }
    else if(e.getKeyCode() == KeyEvent.VK_RIGHT){
        attackRight = true;
    }
    else if(e.getKeyCode() == KeyEvent.VK_R) init();
    else if(e.getKeyCode() == KeyEvent.VK_Q) System.exit(0);
}

For the keyReleased:

@Override
public void keyReleased(KeyEvent e) {
    //This line will output the message every time I released even
    //if keyPressed did not work.
    System.out.println("Key released");
    if(e.getKeyCode() == KeyEvent.VK_A) left = false;
    else if(e.getKeyCode() == KeyEvent.VK_D) right = false;
    else if(e.getKeyCode() == KeyEvent.VK_LEFT) attackLeft = false;
    else if(e.getKeyCode() == KeyEvent.VK_RIGHT) attackRight = false;
}

Sample output when keyPressed did not worked:

Key pressed
Key released
Key pressed
Key released
Key released
Key released
Key released
Key released
Key released
Key released
Key released
Key released

Upvotes: 0

Views: 273

Answers (1)

guleryuz
guleryuz

Reputation: 2734

you may prefer switching from Canvas to JPanel and make a proper use of getActionMap().put(...) and getInputMap().put(...) of your panel (and override paintComponent method)

you also should have a look at here

a simple example may look like this

public class Example2 extends JPanel {

    public Example2() {
        super(new BorderLayout());

        JPanel canvas = new JPanel();

        Action action = new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
                System.out.println(e.getActionCommand());
            }
        };

        InputMap im = canvas.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);

        im.put(KeyStroke.getKeyStroke('w'), "wasd");
        im.put(KeyStroke.getKeyStroke('a'), "wasd");
        im.put(KeyStroke.getKeyStroke('s'), "wasd");
        im.put(KeyStroke.getKeyStroke('d'), "wasd");

        canvas.getActionMap().put("wasd", action);

        add(canvas, BorderLayout.CENTER);

    }

    private static void createAndShowGUI() {
        JFrame frame = new JFrame();
        frame.setContentPane(new Example2());
        frame.setSize(200, 200);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }

}

Upvotes: 0

Related Questions