Alex
Alex

Reputation: 667

Java: KeyListener not detected in game

For my assignment I have to add movement to a character in a game. The way this works is simple: If they press left they change the direction to left and if they press right they change to right right (the character is always moving).

The way this works is every half second or so the game calls an update() method where it redraws etc. It will then ask the character if they want to move in a new direction by calling updateMoveDirection() on the character.

I've tested it and this method is definitely being called regularly as expected. However, when I add a KeyListener to lookout for the left and right clicks then these are not detected. I think it has something to do with the focus of the class? However, since this class has no graphical element then I'm not sure how it can request focus?

public void updateMoveDirection() {
    KeyListener k = new KeyListener() {
        public void keyPressed(KeyEvent arg0) {
            System.out.println("KEY");
            if(arg0.equals(KeyEvent.VK_LEFT)){
                System.out.println("LEFT");

            }
            if(arg0.equals(KeyEvent.VK_RIGHT)){
                System.out.println("RIGHT");

            }

        }

        public void keyReleased(KeyEvent arg0) {
            // TODO Auto-generated method stub

        }

        public void keyTyped(KeyEvent arg0) {
            // TODO Auto-generated method stub

        }
    };
}

Upvotes: 1

Views: 60

Answers (1)

monty
monty

Reputation: 8775

I am not quiet sure how your game is setup. Usually it is enough to have one KeyListener attached to the JFrame, JWindow, JComponent or Canvas (or more generally the Swing class you use for drawing. The code above looks like you would try to add one KeyListener for every game object you want to be reacting to the input. Technically possible but not the besr approach.

But more likely your problem is a different one. Be aware that Java, for some reason, CAN have troubles to detect multiple pressed keys at once. Also, keypressed is called often as long it is pressed.

I would recommend:

  1. Create a class which implements the Keylistener interface and has access to the character and everything else you want to controll. Let's call that class InputController.
  2. Add the InputController as listener to the swing component.
  3. In the InputController use keyReleased and keyTyped instead of keyPressed
  4. Add a boolean member for each key (e.g. boolean isLeftDown) plus matching setter methods
  5. In the InputController you now can use the setters of the character to ser the values and in the update method check if they are down or not

Edit: Or you can place the booleans in the InputController and give the character access to it. Then it fits the "the update reads the input" more exactly

Upvotes: 1

Related Questions