# [java] multiple key input in Java

## Recommended Posts

I'm posting here b/c the Java forum hasn't been replied to in 10 yrs. Take a simple Java app like this:
// MyGame.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class MyGame extends JComponent implements KeyListener {
privates static JFrame frame;

public static void main(String[] args) {
MyGame myGame = new MyGame();

frame = new JFrame("My Game etc.");
frame.setSize(640, 480);
frame.setContentPane(myGame);
frame.setVisible(true);
}

public MyGame() {
// init JComponent
}

/* move method that's called on key presses */
public void move(int dx, int dy) {
System.out.println("dx = " + dx);
System.out.println("dy = " + dy);
}

public void paintComponent(Graphics g) {
// do the painting on g context
}

/* THE IMPORTANT PART: */
public void keyPressed(KeyEvent event) {
switch(event.getKeyCode()) {
case KeyEvent.VK_UP:
move(0, -1);
break;
case KeyEvent.VK_DOWN:
move(0, 1);
break;
case KeyEvent.VK_RIGHT:
move(1, 0);
break;
case KeyEvent.VK_LEFT:
move(-1, 0);
break;
default:
break;
}
}

public void keyTyped(KeyEvent event) {}
public void keyReleased(KeyEvent event) {}
}


If you run the above example (if you can, b/c i just typed it here for simplicity), or if you have experience with Java, you'd know that when you hold down one key, and subsequently hold down another, the new key that you hold down "overrides" the old key. Therefore, using this simple method, one CANNOT have multiple arrow key input AFAIK, to control something in a game, which I am trying to do. Now that you hopefully understand the problem, you may be able to point me to a resource that I am unaware of that will help me fix this. I don't think c++ programmers have this problem when using win32, b/c I've seen a few examples and they ran as wanted without even addressing this problem. I know how to use JNI, and if it came to that I'd have to make a win32 dll that would take user input for me, but then there would be no point in using Java if I had to write win32 code still. So, I've researched this, yes, I've Googled, and found only KeyListener and KeyEvent in Java. And I don't want people to say "OMG your game sSucxks b/c Java can't handle multiple keys LOL." Kthx, for you time :)

##### Share on other sites
keyPressed( KeyEvent )
if someKeyPressed
booleanKeyPressed = true

keyReleased( KeyEvent )
if !someKeyPressed
booleanKeyPressed = false

##### Share on other sites
I see how that would work, but I have to try it first. I'm not sure if Java would see a KeyReleased event if another key is pressed when you release the key. I'll check real quick... Thanks for your help, GKW!

##### Share on other sites
I posted a question in the Java forum not long ago, got a reply within a couple of hours.

/MineWipe

##### Share on other sites
OMGTHX!!1 It worked:
	public void keyPressed(KeyEvent event) {		switch(event.getKeyCode()) {			case KeyEvent.VK_UP:				// moveBlock(0, -1);				upPressed = true;				break;			case KeyEvent.VK_DOWN:				// moveBlock(0, 1);				downPressed = true;				break;			case KeyEvent.VK_RIGHT:				/// moveBlock(1, 0);				rightPressed = true;				break;			case KeyEvent.VK_LEFT:				// moveBlock(-1, 0);				leftPressed = true;				break;			case KeyEvent.VK_SPACE:			default:				break;		}		if(upPressed) {			moveBlock(0, -1);		}		if(downPressed) {			moveBlock(0, 1);		}		if(rightPressed) {			moveBlock(1, 0);		}		if(leftPressed) {			moveBlock(-1, 0);		}	}	public void keyTyped(KeyEvent event) {}	public void keyReleased(KeyEvent event) {		switch(event.getKeyCode()) {			case KeyEvent.VK_UP:				upPressed = false;				break;			case KeyEvent.VK_DOWN:				downPressed = false;				break;			case KeyEvent.VK_RIGHT:				rightPressed = false;				break;			case KeyEvent.VK_LEFT:				leftPressed = false;				break;			default:				break;		}	}

rating++; for you GKW :)

##### Share on other sites
Quote:
 Original post by MindWipeI posted a question in the Java forum not long ago, got a reply within a couple of hours./MineWipe

That's because they don't want anyone to know! *pulls out hair*

edit: Oh great, move my rants about Java forum into the Java forum. Everything I said was really just to test the loyalty of the GDNet Lounge people, nothing more!1

add: Oh, u don't believe me taht the Java thread never has any activity? Watch this thread stay at the top for the rest of the day. (w/o anyone replying to it ie).

[Edited by - temp_ie_cant_thinkof_name on October 18, 2004 1:23:08 PM]

##### Share on other sites
Be careful how you use your booleans since keyevents are processed on the event thread and might not be current on another thread. Learn how to use the synchronize keyword.

##### Share on other sites
Thanks for your humble help, GKW. rating++;

##### Share on other sites
Also, the way you wrote it will have odd behaviour. When you press up, your block will move up, when you keep up pressed, and then press left, your block will move up again, and left.
It's good practice to execute code based on the keypressed vars in your main loop.
Of course I may be wrong cause this is the behaviour you want.

##### Share on other sites
I just now read your post tjoink. I see that as a problem and also something else I discovered: when you press up, for instance, and then left, keeping up pressed, then release left, up will no longer be pressed. I tried putting the conditional if(upPressed)... in keyReleased, but that obviously only worked for one release. So I have another question about multiple keys in Java: How can I invoke a keyEvent myself? If I can't do this, then I think I have to do what tjoink said, testing for keyPresses in a main loop somewhere, continuously. So, how is the latter done? I was thinking I could keep the code as it is, but in my gameLoop I could test for up/down/right/left booleans. But this obviously can't be done straight like that or there would be an up/down/right/left action every 1/1000 of a second or less. So isn't there a static function Thread.wait(20), that I'm supposed to use, that will simulate the delay of a keyPressed call? What do coders commonly use? I found a few tutorials on multi-threading if I must do that. In which case I'd do the same as described above (with Thread.wait(20)), but this would all be happening in a different thread, hopefully pausing execution in *that* thread, and leaving other, continuously running threads to their business. Am I correct in my assumptions? Thanks for the great help. This isn't too important atm, but will be in a few days, so try to reply before 2005, thanks. ;P

edit: is it all right to just use java.util.Timer class to check for input every t milliseconds when I create the timer?

[Edited by - temp_ie_cant_thinkof_name on October 20, 2004 10:09:59 AM]

##### Share on other sites
First of all, that is not true. The way you wrote it, the key release event will only set the Leftpressed var, in your example.
Secondly, rethink your design. Do you need different threads? Keeping things simple, you could just lock your main game loop to the desired rate. If you don't want that, have a timer execute code based on the keypressed vars. Like:

if time>=execute_time{
//do code based on pressed keys
execute_time=time+###ms
}
//rest of code, executed as fast as possible

Well, I guess you get it. Hope that helps!

##### Share on other sites
The thing is I don't have main game loop yet. So if I do this in java, how would I delay the current thread so that I don't end up having something similar to:
while(true);
Or is it okay to do this?

edit: what i mean when I mentioned the second problem was that yest keyReleased sets leftPressed to false, but there is no longer a keyPressed event invoked, so the if(pressed) etc conditionals are never seen after you release left (b/c keyPressed is no longer called.

##### Share on other sites
Yes, that is ok. Loop while (true) and put a thread.sleep in the loop. Move the "if LeftPressed{}" etc to there, and it's fine.

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628293
• Total Posts
2981870

• 11
• 10
• 10
• 11
• 17