Java-Gaming.org    
Featured games (91)
games approved by the League of Dukes
Games in Showcase (581)
games submitted by our members
Games in WIP (500)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  LWJGL blocking keys problem  (Read 2658 times)
0 Members and 1 Guest are viewing this topic.
Offline crzo

Senior Newbie





« Posted 2012-08-31 18:52:42 »

Hi JGO !

i have searched a long time for this kind of problem.
It occurs when i'm pressing a button and hold it (e.g. moving forward) and then pressing a another button (e.g. moving backward).
My program recognized the event from the second hit, but instead of moving the character / camera stops.
It only starts moving again when i'm pressing the second button again and hold it.

So maybe its a design mistake by my self?

Here is the event-loop for a lwjgl application:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
while (Keyboard.next())
  if (Keyboard.getEventKeyState())
    {
      if (Keyboard.getEventKey() == Keyboard.KEY_W)
        cam.setMovement(FirstPersonCamera.CameraMovement.FORWARD);

      if (Keyboard.getEventKey() == Keyboard.KEY_S)
        cam.setMovement(FirstPersonCamera.CameraMovement.BACKWARD);

      if (Keyboard.getEventKey() == Keyboard.KEY_A)
        cam.setMovement(FirstPersonCamera.CameraMovement.LEFT);

      if (Keyboard.getEventKey() == Keyboard.KEY_D)
        cam.setMovement(FirstPersonCamera.CameraMovement.RIGHT);
     
      //...other stuff here
   }
    else
      cam.setMovement(FirstPersonCamera.CameraMovement.NONE);


Can it be solve by using threads or smth. similiar?

Thanks so far :-)

Offline ra4king

JGO Kernel


Medals: 322
Projects: 2
Exp: 4 years


I'm the King!


« Reply #1 - Posted 2012-08-31 23:43:49 »

So you have the 'up' key held and you hit the 'down' key and the camera stops moving? Isn't that expected? Tongue

Offline crzo

Senior Newbie





« Reply #2 - Posted 2012-09-01 02:14:11 »

Hi,

well, i expect something like moving 'down', after i pressed the down button. It seems like an "input lock".
All i want is: always perform the specified action when the button is pressed and cancel the current action.

Hope this helps you :-)
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Best Username Ever

Junior Member





« Reply #3 - Posted 2012-09-01 03:31:17 »

You want to move in the direction of the last arrow key pressed. Thus you want to loop through every key event before calling setMovement. Set a lastKey variable to keep track of the last direction key pushed. If you release that last key, then you don't want to move, so unset the direction variable.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
while (Keyboard.next())
{
  int k = Keyboard.getEventKey();
  if (Keyboard.getEventKeyState())
  {
    switch(k)
    {
     case KeyBoard.KEY_W:
     case KeyBoard.KEY_A:
     case KeyBoard.KEY_S:
     case KeyBoard.KEY_D:
       lastDirKey = k;
    }
  }
  else
  {
    if(k == lastDirKey)
    {
      lastDirKey = 0;
    }
  }
}

switch(lastDirKey)
{
  case Keyboard.KEY_W:
    cam.setMovement(FirstPersonCamera.CameraMovement.FORWARD);
  case Keyboard.KEY_A:
    cam.setMovement(FirstPersonCamera.CameraMovement.LEFT);
  case Keyboard.KEY_S:
    cam.setMovement(FirstPersonCamera.CameraMovement.DOWN);
  case Keyboard.KEY_D:
    cam.setMovement(FirstPersonCamera.CameraMovement.RIGHT);    
}
Offline ra4king

JGO Kernel


Medals: 322
Projects: 2
Exp: 4 years


I'm the King!


« Reply #4 - Posted 2012-09-01 03:40:58 »

@OP
Pressing the down button with the up button already down doesn't release the up button. Your code should work. Have you tried putting SOP's to see if any key-release events are dispatched?

@Best Username Ever
Forgot 'case 0: cam.setMovement(FirstPersonCamera.CameraMovement.NONE)' in the second switch statement Smiley
However, there isn't much point in doing that since OP's code should work originally.

Offline Best Username Ever

Junior Member





« Reply #5 - Posted 2012-09-01 04:18:28 »

Oh. You're right about the case 0. I don't think his code works, though. Pressing W, pressing S, and releasing W will not make the camera move down. Releasing W cancels the S key that came later. Also pressing S then space, for example, would cancel the S key press.
Offline ra4king

JGO Kernel


Medals: 322
Projects: 2
Exp: 4 years


I'm the King!


« Reply #6 - Posted 2012-09-01 06:43:29 »

Oh the OP meant that if he released the first key after the second key, then the movement stops! The only way to fix that is to use polling, not event-based movement. Each tick you call Keyboard.isKeyPressed(int key) to check if that key is down and act accordingly.

Offline crzo

Senior Newbie





« Reply #7 - Posted 2012-09-01 13:18:32 »

Hi,

hehe almost Smiley

here is an example:

1) press 'W' and hold it  --> character moves forward
2) press 'A' and hold it  --> now, character moves leftward
3) release 'A' (only 'W' is now pressed) --> character stops moving, but 'W' is pressed, so i expect that he's moving forward

@Best Username Ever:
Thanks, but this workaround doesnt help with this problem.

@ra4king:
Each tick i tried to check Keyboard.isKeyPressed(int key), but this doesnt work neither =/

any other ideas?
Offline Best Username Ever

Junior Member





« Reply #8 - Posted 2012-09-01 16:54:07 »

In that case, you need to keep track of which keys are pressed. You can't use polling alone if you want that to work correctly because your if statements would have to be in a certain order and the final true if statement would override the rest. You should use a List/array to store direction keys at the end of the list as they're pressed and removed as they are released. Whatever is at the "top" of the list should be the direction you move in. Set movement to NONE if the list is empty.

Do you only want to move in the direction of the most recently pressed key or does it make sense to move in one of 8 (plus one/NONE) directions depending on which keys are pressed? A + W = FORWARD_LEFT, A + D + S = DOWN, A + D + S + W = NONE, etc.
Offline crzo

Senior Newbie





« Reply #9 - Posted 2012-09-01 17:26:51 »

Hi,

thanks :-) i think that should work with a "stack like" implementation.
i'll try it soon.

Do you only want to move in the direction of the most recently pressed key or does it make sense to move in one of 8 (plus one/NONE) directions depending on which keys are pressed? A + W = FORWARD_LEFT, A + D + S = DOWN, A + D + S + W = NONE, etc.

i would like to press max. 2 buttons and perform an action like "A + W = FORWARD_LEFT". i think i can do this by popping down two instead of one entries from my "button-pressed-stack" right?

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Best Username Ever

Junior Member





« Reply #10 - Posted 2012-09-01 17:48:58 »

Yep. That's one way. But the correct operation is peek, not pop. You don't want to remove them because then a "press W, press D, release D, press A" sequence would result in just left instead of forward/left.
Offline crzo

Senior Newbie





« Reply #11 - Posted 2012-09-01 17:50:15 »

yea you're right!   Grin

thank you very much  Smiley
Offline ra4king

JGO Kernel


Medals: 322
Projects: 2
Exp: 4 years


I'm the King!


« Reply #12 - Posted 2012-09-01 21:04:36 »

Why in the world is this getting more complicated than it should be >.>

Offline crzo

Senior Newbie





« Reply #13 - Posted 2012-09-01 21:12:27 »

Why in the world is this getting more complicated than it should be >.>

You think a "stack-like" implementation as a memory which key i pressed is far too complicated?
I tried it and it works just fine Smiley
Offline ra4king

JGO Kernel


Medals: 322
Projects: 2
Exp: 4 years


I'm the King!


« Reply #14 - Posted 2012-09-01 21:20:26 »

Unnecessarily complicated when polling is the best way:

1  
2  
3  
4  
5  
6  
7  
8  
9  
if(Keyboard.isKeyPressed(Keyboard.KEY_A))
   x -= speed;
if(Keyboard.isKeyPressed(Keyboard.KEY_D))
   x += speed;

if(Keyboard.isKeyPressed(Keyboard.KEY_W))
   y -= speed;
if(Keyboard.isKeyPressed(Keyboard.KEY_S))
   y += speed;

Offline crzo

Senior Newbie





« Reply #15 - Posted 2012-09-01 21:37:35 »

Sorry i dont get it.

Where do you usually put this code in an application?

i guess somewhere in the game-mainloop ?
Offline ra4king

JGO Kernel


Medals: 322
Projects: 2
Exp: 4 years


I'm the King!


« Reply #16 - Posted 2012-09-01 22:16:10 »

Yes, in your 'update' method.

Offline crzo

Senior Newbie





« Reply #17 - Posted 2012-09-01 23:13:37 »

And whats the difference between smth like this:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
//...

  //this is the main-gameloop
 public void run()
  {
    while (....)
    {
      //render stuff etc.
     
      double delta = //calc delta..
     updateLogic(delta);

      processKeyboard();
    }
  }

  public void updateLogic(double delta)
  {
     //compute x,y,z / centerX, centerY, centerZ / upX, upY, upZ of camera by using "movement-variable"
    cam.updatePosition(delta);
  }

  public void processKeyboard()
  {
     if(Keyboard.isKeyPressed(Keyboard.KEY_A))
       cam.setMovement(CameraMovements.LEFT); //set "movement-variable"
    else if(Keyboard.isKeyPressed(Keyboard.KEY_D))
       cam.setMovement(CameraMovements.RIGHT);
  }
//...


and...

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
//...

  public void updateLogic(double delta)
  {
     if(Keyboard.isKeyPressed(Keyboard.KEY_A))
       //directly compute x,y,z / centerX, centerY, centerZ / upX, upY, upZ of camera
    else if(Keyboard.isKeyPressed(Keyboard.KEY_D))
       //directly compute x,y,z / centerX, centerY, centerZ / upX, upY, upZ of camera
 }

//...


the only difference is that i compute the position of the camera straight in die updateLogic() method.

so how does ur code ensure not "stucking the movement" like i mentioned before?
Offline Best Username Ever

Junior Member





« Reply #18 - Posted 2012-09-01 23:47:19 »

There are a number of ways you can handle keyboard input in situations like this. One way is too track the order of events and let more recent events cancel old ones like the original poster describes. Another is to let two keys cancel each other out. (if A and not B - if B and not A) A third is to let one key override another based on priority. (if - else if - else)

Note that if you want to do the first method you need to track events. Polling won't work*. Personally, I prefer the second method because it's more intuitive to use. Arrow keys should cancel each other out like two equal forces pulling in opposite directions do. The camera should move at a consistent rate as long as the key is held down. R4king is correct about polling if you want the second or third method (just replace the else ifs with ifs to change between one type or the other.)

*Technically the keyboard is being polled no matter what form you get the data in, but polling at the same rate as your game's update cycle might be too slow to pick up quick key presses. It matters for other quick buttons presses, but not holding down a key to move around.

I assume you can combine the two methods in LWJGL, but even if that weren't the case I would still emulate polling a set of keys once per turn and write my own isArrowKeyPressed method. If you can get the simplicity of isKeyPressed without having to lose event information and if the "always perform the specified action when the button is pressed and cancel the current action" isn't essential, then definitely consider the other methods just for camera controls.
Offline sproingie
« Reply #19 - Posted 2012-09-02 04:55:59 »

Polling is ideal for movement, not so much for single presses.  The simple answer is just to do both: poll for movement, get events for clicks.
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

xsi3rr4x (64 views)
2014-04-15 18:08:23

BurntPizza (62 views)
2014-04-15 03:46:01

UprightPath (75 views)
2014-04-14 17:39:50

UprightPath (58 views)
2014-04-14 17:35:47

Porlus (76 views)
2014-04-14 15:48:38

tom_mai78101 (101 views)
2014-04-10 04:04:31

BurntPizza (161 views)
2014-04-08 23:06:04

tom_mai78101 (256 views)
2014-04-05 13:34:39

trollwarrior1 (209 views)
2014-04-04 12:06:45

CJLetsGame (216 views)
2014-04-01 02:16:10
List of Learning Resources
by SHC
2014-04-18 03:17:39

List of Learning Resources
by Longarmx
2014-04-08 03:14:44

Good Examples
by matheus23
2014-04-05 13:51:37

Good Examples
by Grunnt
2014-04-03 15:48:46

Good Examples
by Grunnt
2014-04-03 15:48:37

Good Examples
by matheus23
2014-04-01 18:40:51

Good Examples
by matheus23
2014-04-01 18:40:34

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-11 15:22:30
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!