Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (107)
games submitted by our members
Games in WIP (535)
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  
  How to detect up-left keypress?  (Read 3229 times)
0 Members and 1 Guest are viewing this topic.
Offline gcsaba2

Junior Member




Hello world


« Posted 2006-09-10 16: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?
Offline Kova

Senior Member





« Reply #1 - Posted 2006-09-10 17: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
Offline gcsaba2

Junior Member




Hello world


« Reply #2 - Posted 2006-09-10 17: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!
Legends of Yore - The Casual Retro Roguelike
Offline gcsaba2

Junior Member




Hello world


« Reply #3 - Posted 2006-09-10 17: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.
Offline gcsaba2

Junior Member




Hello world


« Reply #4 - Posted 2006-09-10 17:52:17 »

Is there some other way to listen to key events, other than using a KeyEventListener?
Offline BloodRain

Junior Member





« Reply #5 - Posted 2006-09-10 18: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){}
   
Offline gcsaba2

Junior Member




Hello world


« Reply #6 - Posted 2006-09-10 18: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 Grin
Offline BloodRain

Junior Member





« Reply #7 - Posted 2006-09-10 21:00:35 »

LooL  !!!  Smiley
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()Wink 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:)
Offline fletchergames

Senior Member





« Reply #8 - Posted 2006-09-11 16: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.
Offline Markus_Persson

JGO Wizard


Medals: 14
Projects: 19


Mojang Specifications


« Reply #9 - Posted 2006-09-11 17: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. Wink

Play Minecraft!
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline gcsaba2

Junior Member




Hello world


« Reply #10 - Posted 2006-09-11 17: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  Wink
Offline Anon666

Junior Member




aka Abuse/AbU5e/TehJumpingJawa


« Reply #11 - Posted 2006-09-11 23:47:32 »

LooL  !!!  Smiley
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()Wink 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.
Offline BloodRain

Junior Member





« Reply #12 - Posted 2006-09-12 08:29:33 »

I used the true/false stuff in a game and it works on both windows and linux Smiley
PS : I didn't think of k as a local variable because I thought it will be changed from the game loop .
Offline gcsaba2

Junior Member




Hello world


« Reply #13 - Posted 2006-09-12 09: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 Cool
Offline cylab

JGO Ninja


Medals: 38



« Reply #14 - Posted 2006-09-12 10: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!
Offline JAW

Senior Member


Medals: 2



« Reply #15 - Posted 2006-09-13 18: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
Offline ENC

Junior Member





« Reply #16 - Posted 2006-09-28 10:01:25 »

What you can do is set all to ifs... dont put else ifs

Cheers!
Offline Kova

Senior Member





« Reply #17 - Posted 2006-09-30 02:24:22 »

makes no difference becouse there's only one keycode value per pass through method
Offline ENC

Junior Member





« Reply #18 - Posted 2006-10-08 03: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
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.

E.R. Fleming (8 views)
2014-07-29 03:07:13

E.R. Fleming (4 views)
2014-07-29 03:06:25

pw (38 views)
2014-07-24 01:59:36

Riven (39 views)
2014-07-23 21:16:32

Riven (26 views)
2014-07-23 21:07:15

Riven (28 views)
2014-07-23 20:56:16

ctomni231 (59 views)
2014-07-18 06:55:21

Zero Volt (50 views)
2014-07-17 23:47:54

danieldean (42 views)
2014-07-17 23:41:23

MustardPeter (44 views)
2014-07-16 23:30:00
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
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!