gcsaba2
Junior Devvie  
Hello world
|
 |
«
Posted
2006-09-10 14:19:15 » |
|
I've got a method like this: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public void keyPressed(KeyEvent key) { int code = key.getKeyCode(); if (code == KeyEvent.VK_ESCAPE) gameRunning = false; if (code == KeyEvent.VK_F1) switchFullscreen(); if (code == KeyEvent.VK_LEFT) Globals.offsetX--; else if (code == KeyEvent.VK_RIGHT) Globals.offsetX++; if (code == KeyEvent.VK_UP) Globals.offsetY++; else if (code == KeyEvent.VK_DOWN) Globals.offsetY--; } |
This works fine, except that when I press the UP key and the LEFT key at the same time, I want the game to react to both keypresses. Right now only one of them happens. I tried like if ((code & KeyEvent.VK_UP) == 1), but this did not work, so obviously code does not hold a flag of pressed keys. How should I solve this?
|
|
|
|
Kova
|
 |
«
Reply #1 - Posted
2006-09-10 15:17:36 » |
|
this happens only for up+left? ... This looks fine, problem is probably way you handle it in game. For simple test, add System.out.println(....) to both conditions and see if you get text printed out for both keys when you press them at the same time, you should get 2 lines in one pass through keyPressed().
Edit: this is wrong, read the rest of thread
|
|
|
|
gcsaba2
Junior Devvie  
Hello world
|
 |
«
Reply #2 - Posted
2006-09-10 15:46:06 » |
|
For example in LWJGL I can write 1 2 3 4
| if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) Globals.offsetX--; if (Keyboard.isKeyDown(Keyboard.KEY_UP)) Globals.offsetY--; |
And if I press both left and up buttons, I will go in a diagonal direction. With a KeyListener, when I press both buttons I get something like this: up left left left left .... So when one key starts to prevail it will not allow the other one to take control. The KeyEventListener has special support for the shift, alt and ctrl keys, but I don't see how it will support something like I want. My guess is I need somehow to discard the last keypress, so that Java would evaluate it again. But in any case I'm not sure what's going on. I tried decompiling LWJGL's Keyboard class, but didn't find anything interesting there. I'm not sure where they implement their key listening.
|
|
|
|
Games published by our own members! Check 'em out!
|
|
gcsaba2
Junior Devvie  
Hello world
|
 |
«
Reply #3 - Posted
2006-09-10 15:50:39 » |
|
Oh yeah, and let's say I press UP and LEFT, and it goes like this:
up left left left ...
And after some time I release the LEFT button, while continue to press down the UP button... but it does not react anymore. So to move up, I have to release the up button and press it again.
|
|
|
|
gcsaba2
Junior Devvie  
Hello world
|
 |
«
Reply #4 - Posted
2006-09-10 15:52:17 » |
|
Is there some other way to listen to key events, other than using a KeyEventListener?
|
|
|
|
BloodRain
|
 |
«
Reply #5 - Posted
2006-09-10 16:02:47 » |
|
Use something 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 31 32 33 34 35 36 37 38 39 40 41
| public void keyPressed(KeyEvent e) { int k=e.getKeyCode(); if(k==KeyEvent.VK_UP) { up=true; } else if(k==KeyEvent.VK_DOWN) { down=true; } else if(k==KeyEvent.VK_LEFT) { left=true; } else if(k==KeyEvent.VK_RIGHT) { right=true; } } public void keyReleased(KeyEvent e) { int k=e.getKeyCode(); if(k==KeyEvent.VK_UP) { up=false; } else if(k==KeyEvent.VK_DOWN) { down=false; } else if(k==KeyEvent.VK_LEFT) { left=false; } else if(k==KeyEvent.VK_RIGHT) { right=false; } } public void keyTyped(KeyEvent e){} |
|
|
|
|
gcsaba2
Junior Devvie  
Hello world
|
 |
«
Reply #6 - Posted
2006-09-10 16:35:09 » |
|
For some reason that works and I don't know why. If I copy-paste your code then it works, but if I do a similar implementation which should do the same thing, then it doesn't. Anyway, glad that that's solved, thanks for the help 
|
|
|
|
BloodRain
|
 |
«
Reply #7 - Posted
2006-09-10 19:00:35 » |
|
LooL !!!  You can post your code and I'll tell you what is wrong. The main thing is that the variable code (int code = key.getKeyCode()  can remeber only one value. So when you press a new button code it will change into the code of the last button pressed and it won't remember that you are still holding down the previous keys. When you use the boolean variables you don't change the up value into false because you just pressed left. I hope you understood ! I'm not sure I would understand what I wrote:)
|
|
|
|
fletchergames
|
 |
«
Reply #8 - Posted
2006-09-11 14:55:43 » |
|
This is an unrelated issue, but shouldn't "up" decrease the y offset and "down" increase it? That's the way the coordinates are on the screen.
|
|
|
|
Markus_Persson
|
 |
«
Reply #9 - Posted
2006-09-11 15:07:49 » |
|
This is an unrelated issue, but shouldn't "up" decrease the y offset and "down" increase it? That's the way the coordinates are on the screen.
Not in opengl. 
|
|
|
|
Games published by our own members! Check 'em out!
|
|
gcsaba2
Junior Devvie  
Hello world
|
 |
«
Reply #10 - Posted
2006-09-11 15:10:41 » |
|
I dunno, if you think about it you're right, but it works this way... It's true the code remained from back when it was drawn in OpenGL, but now I'm drawing in Java and it still works the same... I probably placed a + somewhere where a - should have been placed 
|
|
|
|
Anon666
Junior Devvie  
aka Abuse/AbU5e/TehJumpingJawa
|
 |
«
Reply #11 - Posted
2006-09-11 21:47:32 » |
|
LooL !!!  You can post your code and I'll tell you what is wrong. The main thing is that the variable code (int code = key.getKeyCode()  can remeber only one value. So when you press a new button code it will change into the code of the last button pressed and it won't remember that you are still holding down the previous keys. When you use the boolean variables you don't change the up value into false because you just pressed left. I hope you understood ! I'm not sure I would understand what I wrote:) That is not the reason at all. The line "int code = key.getKeyCode();" in the first code example is storing the key code in a local variable. Even if pressing a second key caused a 2nd thread to simultaneously deliver another KeyEvent (which for the record - NO common VM does), it would still function fine. To the original question. Are you using Linux or Windows? KeyEvent delivery is bugged in Linux - and have been for the best part of 10 years. In Windows, you recieve the following sequence of events :- <key is pressed down> keyPressed... keyPressed... keyPressed... keyReleased. <key is released> In Linux, you recieve :- <key is pressed down> keyPressed... keyReleased. keyPressed... keyReleased. keyPressed... keyReleased. <key is released> If that isn't the cause of your problem, then I can only guess it is something else wrong in your code. p.s. may I suggest you use a switch statement instead of dozens of if/else's. It will improve the readability of your code.
|
|
|
|
BloodRain
|
 |
«
Reply #12 - Posted
2006-09-12 06:29:33 » |
|
I used the true/false stuff in a game and it works on both windows and linux  PS : I didn't think of k as a local variable because I thought it will be changed from the game loop .
|
|
|
|
gcsaba2
Junior Devvie  
Hello world
|
 |
«
Reply #13 - Posted
2006-09-12 07:57:07 » |
|
Btw. I don't know if anyone's interested, but I looked into how LWJGL handles this problem. They actually relly on platform-specific implementation, so for example on Windows it uses a WindowsKeyboard class, which calls a DirectInput's pollKeyboard() method. I'm guessing they also implemented the mouse and other inputs the same way 
|
|
|
|
cylab
|
 |
«
Reply #14 - Posted
2006-09-12 08:34:48 » |
|
That's because the KeyEvent Listening method can lead to lags under some circumstances, other than that using the KeyEvents with flags is just fine on both platforms. You could use JInput to directly poll the input without using LWJGL.
|
Mathias - I Know What [you] Did Last Summer!
|
|
|
JAW
|
 |
«
Reply #15 - Posted
2006-09-13 16:51:57 » |
|
You should never handle movement or position changes directly in the KeyListener methods. Never do something like
if keycode = key_left x_position -= 10;
Especially while a key is pressed, the result can differ depending on the computer, because the frequence of keypress events differs with different hardware. I made this error too in a Pong Clone. I inserted code moving the paddle directly in the listener and the paddle was too slow in my notebook because the keypressed event was not sent often enough.
So what you do is use flags that go true / false. For ordinary "while pressed" actions like moving, you just set a boolean true when the key gets pressed and set it false when the key is released. In the game logic loop, you check this flags and do movement (position change) if true. For other actions you can need a "has been pressed" funcionality. Functions like Pause, Menu, Quicksave, etc should work when the key has been pressed once, even if it has already been released. You dont want the game to go pause while p is pressed but if the user presses and releases p you gou pause.
You can use easy logic, this would be, set the flag true when the key is released and set it false when the game logic reads it. A more difficult logic sets the pause true already on keypress not on release, but if the logic reads it and sets it to false, it must remain false even if the key is still pressed. It may only be set true again if the key has been released. You need two booleans for this.
Some games only react on key release with this buttons, other games react on keypress but do not go like autofire when you keep it pressed. Otherwise you would go pause on/off all the time while you keep it pressed. You want pause or menu to switch on for the first press, and only disappear after a second distinct press, not just on a repeated pressed event beacause the key is still pressed.
Using this, you can also handly multiple key presses. Just read the flags for left right up down and react. Usually, left/right and up/down should be different forces in your game that are independent. For topdown, left and right would change x-velocity and up and down would change y-velocity, without each caring about the other. For a simulation of a plane or car its the same. The game logic doesnt notice if up AND left is pressed. They modify different forces.
-JAW
|
|
|
|
ENC
|
 |
«
Reply #16 - Posted
2006-09-28 08:01:25 » |
|
What you can do is set all to ifs... dont put else ifs
Cheers!
|
|
|
|
Kova
|
 |
«
Reply #17 - Posted
2006-09-30 00:24:22 » |
|
makes no difference becouse there's only one keycode value per pass through method
|
|
|
|
ENC
|
 |
«
Reply #18 - Posted
2006-10-08 01:30:32 » |
|
Is true that only one keycode value per pass.. however you must consider that when the game is in process.. the method may be invoked many times before the method is has finish its process...
This is from my experience though
|
|
|
|
|