views:

373

answers:

5

I am teaching myself, from online tutorials, how to write games in Java. I am using Java Applets to create a Pong game. each paddle is controlled from different keys for 1v1 competition. this works fine if both users are hitting the keys at different times. but when one key is being held down and then another key is held down(ex: holding down on the arrow key, then user 2 holds the 'S' key), the second key overrides the first and the first paddle will stop moving. i'm guessing that i need to use threads but i don't know much about them and i am having trouble understanding how to use/implement them. how would i go about handling the case when two (or more) keys are being held down?

Bonus: like i said i don't know much about threads - i'm assuming i also need one for the ball/puck to be moving around while all else is going on. is the right and if so how do i put a thread on something that takes no input?

Thanks for you help, DJ

+2  A: 

Usually instead of threads, games use something called the game loop (google it).

http://en.wikipedia.org/wiki/Game_programming

The basic idea is

 Loop
    Get all inputs
    Get game clock
    Update state based on clock and inputs
    Update Display
    Limit frame rate if you need to

Anyway -- instead of getting keyboard events -- you check the keyboard's state at certain points. This code seems to do it for Java

http://www.gamedev.net/reference/articles/article2439.asp

It uses events to set variables you look at in your loop.

Lou Franco
Thanks for your input. I had never heard of the "game loop" before. That 2nd link there is great stuff. Thanks again!
DJ
A: 

If I'm not mistaken, you have the keyUp() and keyDown() methods at your disposal with Applet. Have you tried setting a flag on keyDown, then unsetting it on keyUp? For example:

   public boolean keyDown( Event e, int key )
   {
      if (key == 'a') {
        player1.go("left")
      }
   }

   public boolean keyUp( Event e, int key )
   {
      if (key == 'a') {
        player1.stop("left")
      }
   }

Just an idea. I'm sure there's a standard way to deal with this.

rledley
+2  A: 

What you usually do is to remember the state of every keypress.

You keep an array of your actions(or an array of all the keys if you want too). A keyDown event results in e.g.

boolean actions[12];...
...

public boolean keyDown( Event e, int key ) {
 if (key == 'a') {
    actions[ACTION_LEFT] = true; 
  }
..
}

And you'll need to catch the keyup event and set the actions to false when the keys are released.

In the movement logic you can just check the states of the keypresses

if(actions[ACTION_LEFT] == true)
   moveLeft();
if(actions[ACTION_RIGTH] == true)
   moveRight();
nos
Combine this with Lou Franco's answer about having a game loop. Checking the states of the keypresses would be inside that loop.
Ricket
Thanks! This solution worked for me.
DJ
A: 

You could use Swing Timer to periodically fire movement events between a keydown/keyup event.

kd304
Thanks for your input.
DJ
+1  A: 

Just in case anyone wanted to see how I ended up answering this question. My keyDown() and keyUp() method are as follows:

public boolean keyDown(Event e, int key)
{
     message = key + "pressed";

     //right paddle
     if(key == 1005)
     {
      rpaddle_up = true;
     }
     if(key == 1004)
     {
      rpaddle_down = true;
     }

     //left paddle
     if(key == 115)
     {
      lpaddle_up= true;
     }
     if(key == 119)
     {
      lpaddle_down=true;
     }

     //x key = exit
     if(key == 'x')
      System.exit(0);
     return true;  
    }

public boolean keyUp(Event e, int key)
    {
     //right paddle
     if(key == 1005)
     {
      rpaddle_up = false;
     }
     if(key == 1004)
     {
      rpaddle_down = false;
     }

     //left paddle
     if(key == 115)
     {
      lpaddle_up= false;
     }
     if(key == 119)
     {
      lpaddle_down=false;
     }
     return true;
    }

Hopefully if someone has the same issue this will help them. And thanks everyone for your input and help.

DJ