How to listen multiple Key presses?

Hello Forum!
Im having issues!

In my game, the player controls a snake, but i cant make it move right and up at the same time, or down and left, etc;;;

It can only go one direction at a time…
I researched a lot, but couldnt make it work.


 @Override
    public void keyPressed(KeyEvent e) {
        
        boolean setaPraCima = false;
        boolean setaPraBaixo = false;
        boolean setaPraDireita = false;
        boolean setaPraEsquerda = false;
        
        //System.out.println("Pressed : Key Code :: " + e.getKeyCode() + " == " + e.getKeyChar());
        if (e.getKeyCode() == 38) { // Seta pra cima 
            setaPraCima = true;
            gameUpdate.moveSnakeUp();
        } else
            if (e.getKeyCode() == 40)
            {
                setaPraBaixo = true;
                gameUpdate.moveSnakeDown();
            }else
                if(e.getKeyCode() == 39)
                {
                    setaPraDireita = true;
                    gameUpdate.moveSnakeRight();
                } else
                    if(e.getKeyCode() == 37)
                    {
                        setaPraEsquerda = true;
                        gameUpdate.moveSnakeLeft();
              
                    }
       
        gameUpdate.GameUpdate();

    }

Remove the ELSE.

I would change the way you’re responding to key events by not implementing any game logic within the event listeners. Your program really shouldn’t be driven by these event methods, as you will only receive one event a time. You also don’t want to be updating the game entities every time an event is received - this leaves the program at the mercy of how rapidly the player can hammer the keyboard.

An alternative is to do only one simple thing during key event handlers, and that’s register the fact that a key has been pressed (or released). The idea is that you have a boolean variable for each key that you’re interested in. Or an array of booleans if you want to capture lots of different keystrokes. You then listen for keyDown and keyUp events. When a keyDown is received, set the variable to true. When a keyUp is received, set the variable for that key to false.

Your main program loop then only has to check the state of these variables to see what is being pressed and act accordingly. Your game loop (which runs in its own thread) might do something along these lines:


while (not finished)
  1. figure out what the player wants to do by looking at these key variables
  2. calculate what the game entities want to do, by applying AI logic
  3. update the scene, checking for collisions etc
  4. render everything

Thanks for the answers m8’s;

I just made the game update in the control because i waas learning how to make it render in screen.
This time, im making the thread to do the gameloop.

Also,I took of the else too for a test, and it still happened.

I tried something like this :

“An alternative is to do only one simple thing during key event handlers, and that’s register the fact that a key has been pressed (or released). The idea is that you have a boolean variable for each key that you’re interested in. Or an array of booleans if you want to capture lots of different keystrokes. You then listen for keyDown and keyUp events. When a keyDown is received, set the variable to true. When a keyUp is received, set the variable for that key to false.”

But it didnt work… I made a list and worked on it, and was a mess!!!
Do you have any implementation example ,please?

Ty guys!!

This is a very basic keyboard handler class that you can use to listen for multiple key presses. It will respond to the first 128 key codes as defined in the KeyEvent class. If you need to respond to codes above this range, just increase the array size accordingly. You can see all of the codes here:
http://docs.oracle.com/javase/6/docs/api/constant-values.html#java.awt.event.KeyEvent.CHAR_UNDEFINED

And now for Keyboard.java:


import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class Keyboard {

    private static boolean[] pressed = new boolean[128];

    public static boolean isPressed(int key) {
        return pressed[key];
    }
 
   public static KeyListener listener = new KeyAdapter() {

        @Override
        public void keyPressed(KeyEvent e) {
            int code = e.getKeyCode();
            if (code < pressed.length) {
                pressed

= true;
}
}

    @Override
    public void keyReleased(KeyEvent e) {
        int code = e.getKeyCode();
        if (code < pressed.length) {
            pressed
 = false;
            }
        }
    };
}

The class defines a static member which is the listener, and can be added to your JPanel (or Applet) as follows:

panel.addKeyListener(KeyBoard.listener);

Checking if a key has been pressed in your thread is as easy as:


if (Keyboard.isKeyPressed(KeyEvent.VK_LEFT)) {
    ...
}
if (Keyboard.isKeyPressed(KeyEvent.VK_DOWN)) {
    ...
}

One known limitation of this code is that if a key is pressed and released before your main game loop thread has a chance to read its state, then it will be missed. I have a solution to this, but have edited it out just to make the example a lot simpler to follow. It isn’t such a big deal.


Here’s the listener that I use. I got it from Notch.


public class Input implements KeyListener {

	public List<Key> keys = new ArrayList<Key>();
	
	public Key up = new Key();
	public Key down = new Key();
	public Key left = new Key();
	public Key right = new Key();
	public Key exit = new Key();
	
	public Input(Main game) {
		game.addKeyListener(this);
	}
	
	@Override
	public void keyPressed(KeyEvent e) {
		toggle(e, true);
	}

	@Override
	public void keyReleased(KeyEvent e) {
		toggle(e, false);
	}

	@Override
	public void keyTyped(KeyEvent e) { }
	
	private void toggle(KeyEvent e, boolean pressed) {
		if (e.getKeyCode() == KeyEvent.VK_UP) up.toggle(pressed);
		if (e.getKeyCode() == KeyEvent.VK_DOWN) down.toggle(pressed);
		if (e.getKeyCode() == KeyEvent.VK_LEFT) left.toggle(pressed);
		if (e.getKeyCode() == KeyEvent.VK_RIGHT) right.toggle(pressed);
		if (e.getKeyCode() == KeyEvent.VK_ESCAPE) exit.toggle(pressed);
	}
	
	public void releaseAll() {
		for (Key key : keys) key.down = false;
	}
	
	
	public class Key {
		public boolean down;
		
		public Key() {
			keys.add(this);
		}
		
		public void toggle(boolean pressed) {
			if (pressed != down) down = pressed;
		}
	}
}

IT WORKED!
Like a charm!!!

I love you xD