1

i'm using the keyboard class from the LWJGL and am currently using

if(Keyboard.isKeyDown(Keyboard.KEY_A))
{
   //move left
}
else if(Keyboard.isKeyDown(Keyboard.KEY_D))
{
   //move right
}

if i have the 'a' key down then the 'd' key it will move right but if i have the 'd' key down then the 'a' key it will still continue to move right due to the "else" part.

i've tried it without the else and just letting them both run but if both keys are press there is no movement

im looking for a piece of code that allows me to only take the input from the last key that was pressed.

i also need to be able to move up and down (using 'w' and 's') so the solution can't stop other keys from working, only 'a' or 'd'.

thanks. Alex.

Alex Musk
  • 160
  • 11
  • Let me get this straight, you want the following... holding A then D moves right, holding D then A moves left? – obataku Aug 08 '12 at 21:36
  • not quite, i need it so that it only moves in the direction that the last key is for ('a' left, 'd' right) so that if both are held down it knows which one was pressed last and does that keys function – Alex Musk Aug 08 '12 at 21:48
  • Use [`Keyboard.getEventKeyState`](http://www.lwjgl.org/javadoc/org/lwjgl/input/Keyboard.html#getEventKeyState()) to determine the current event, followed by [`Keyboard.getEventKey`](http://www.lwjgl.org/javadoc/org/lwjgl/input/Keyboard.html#getEventKey()) to determine which key this is. Then, you need to make sure you disable repeat events via [`Keyboard.enableRepeatEvents`](http://www.lwjgl.org/javadoc/org/lwjgl/input/Keyboard.html#enableRepeatEvents(boolean)). Maintain state for the current movement, changing based on these events, and every tick move accordingly. – obataku Aug 08 '12 at 21:56
  • I, as a gamer, prefer when games use the "no movement" strategy you described (by removing the else). Minecraft, which also uses LWJGL, makes your character stand still if you press both A and D at the same time. This is the most intuitive solution IMO because i figure the two keys should cancel eachother out. Just my 2 cents... – Jesse Webb Aug 08 '12 at 22:19

2 Answers2

1

Use Keyboard.getEventKeyState to determine the current event, followed by Keyboard.getEventKey to determine which key this is. Then, you need to make sure you disable repeat events via Keyboard.enableRepeatEvents. Maintain state for the current movement, changing based on these events, and every tick move accordingly. Something like the following, as quick sketch:

Keyboard.enableRepeatEvents(false);
...
/* in your game update routine */
final int key = Keyboard.getEventKey();
final boolean pressed = Keyboard.getEventKeyState();
final Direction dir = Direction.of(key);
if (pressed) {
  movement = dir;
} else if (movement != Direction.NONE && movement == dir) {
  movement = Direction.NONE;
}
...
/* later on, use movement to determine which direction to move */

In the above example, Direction.of returns the appropriate direction for the pressed key,

enum Direction {
  NONE, LEFT, RIGHT, DOWN, UP;

  static Direction of(final int key) {
    switch (key) {
      case Keyboard.KEY_A:
        return Direction.LEFT;
      case Keyboard.KEY_D:
        return Direction.RIGHT;
      case Keyboard.KEY_W:
        return Direction.UP;
      case Keyboard.KEY_S:
        return Direction.DOWN;
      default:
        return Direction.NONE;
    }
  }
}
obataku
  • 29,212
  • 3
  • 44
  • 57
  • 1
    works as long as you set the variable inside a while(Keyboard.next()) loop, thanks. – Alex Musk Aug 08 '12 at 23:05
  • @AlexMusk no problem. PS, since you appear newer here, please don't forget to mark the answer [accepted](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) which helped most in solving the problem. – obataku Aug 08 '12 at 23:16
0

Idk if this is still going to help you, but you could lock the key that was first pressed until it is let up. I'd suggest putting this variable outside of the methods (if I remember correctly, it's called a field) so it can be accessed through any class and isn't reinstantiated every time update is called. That would look something like this:

boolean isHorizontalLocked = false;
String lockedKey = null;

After that, write something like this in the update method:

if (!isHorizontalLocked) {
   if (input.isKeyDown("KEY_A")) {
       isHorizontalLocked = true;
       lockedKey = "A";
   }
   else if (input.isKeyDown("KEY_D")) {
       isHorizontalLocked = true;
       lockedKey = "D";
   }
   else {
       isHorizontalLocked = false;
   }
}
else if (isHorizontalLocked) {
   if (lockedKey == "A") {
       if (input.isKeyDown("KEY_A")) {
          //move left
       }
       if (!input.isKeyDown("KEY_A")) {
          lockedKey = null;
          isHorizontalLocked = false;
       }
   }
   else if (lockedKey == "D") {
       if (input.isKeyDown("KEY_D")) {
          //move right
       }
       if (!input.isKeyDown("KEY_D")) {
          lockedKey = null;
          isHorizontalLocked = false;
       }
   }
}

I think this should work, but if anyone finds an error, let me know and I'll fix it.