Sign in to follow this  
temp_ie_cant_thinkof_name

[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.addKeyListener(myGame);
    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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by MindWipe
I 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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this