This discussion is archived
4 Replies Latest reply: Aug 19, 2010 1:49 PM by 843807 RSS

KeyListener anomoly: delay in firing KeyEvent

843807 Newbie
Currently Being Moderated
Hello,

I've implemented a KeyListener that's exhibiting some anomolies. I'm using it in a video game. I'm using it to control the main character's movement. It determines his movement based on strokes of the arrow keys. I've programmed it so that only one key has an effect at a time. That is, so long as (say) the up arrow was pressed first and held down, the character moves up, and no other key has an effect. Other keys only have an effect if the up arrow is released.

The anomoly comes about when two keys are held down (only one of them determining the movement of the character - which ever was first), and then the first is released. When the first is released (but the second is still held down), the character freezes for about a second, and only after that second does he move in the direction of the second key which is still held down.

It's this second-long delay which is the anomoly. I'm guessing it results from the fact that the KeyEvent is not being fired constantly or immediately after the release of the first key. Even though the second key is held down, it takes a second to fire the KeyEvent after the first key is released (though it seems to fire immediately upon depressing the key).

I'm wondering if there's a way to get rid of the delay or at least shorten it so it's not noticeable.

Here's my KeyListener code:
import java.awt.event.*;

public class InputProcessor implements KeyListener {

    // key codes
    public static final int      LEFT  = 37;
    public static final int      UP    = 38;
    public static final int      RIGHT = 39;
    public static final int      DOWN  = 40;

    private boolean      left_arrow_down  = false;
    private boolean      right_arrow_down = false;
    private boolean      up_arrow_down    = false;
    private boolean      down_arrow_down  = false;

    // flag to mark when a key (any key) is pressed
    private boolean     key_pressed      = false;

    public InputProcessor() {}

    public void keyPressed (KeyEvent KE) {

     if (key_pressed) return; // all other keys disabled if one key is down

     switch (KE.getKeyCode()) {

         case LEFT:
          left_arrow_down true;
          key_pressed = true; 
          break;

         case RIGHT:
          right_arrow_down = true;
          key_pressed = true;
          break;

         case UP:
          up_arrow_down = true;
          key_pressed = true;
          break;

         case DOWN:
          down_arrow_down = true;
          key_pressed = true; 
          break;
     }
    }

    public void keyReleased (KeyEvent KE) {

     switch (KE.getKeyCode()) {

         case LEFT:
          left_arrow_down = false;
          break;

         case RIGHT:
          right_arrow_down = false;
          break;

         case UP:
          up_arrow_down = false;
          break;

         case DOWN:
          down_arrow_down = false;
          break;
     }

     // only set key_pressed to false if all keys have been released
     if (!left_arrow_down &&
       !right_arrow_down &&
       !up_arrow_down &&
       !down_arrow_down)
         key_pressed = false;
    }

    public void keyTyped (KeyEvent KE) {}

    public boolean isLeftArrowDown()  {return left_arrow_down;}

    public boolean isUpArrowDown()    {return up_arrow_down;}

    public boolean isRightArrowDown() {return right_arrow_down;}

    public boolean isDownArrowDown()  {return down_arrow_down;}

    public static void main (String[] args) {

     InputProcessor IP = new InputProcessor();
    }
}
I'm wondering if there might be a command I can execute at the end of the keyReleased() method, something like this:
    public void keyReleased (KeyEvent KE) {

     switch (KE.getKeyCode()) {

         case LEFT:
          left_arrow_down = false;
          break;

         case RIGHT:
          right_arrow_down = false;
          break;

         case UP:
          up_arrow_down = false;
          break;

         case DOWN:
          down_arrow_down = false;
          break;
     }

     // only set key_pressed to false if all keys have been released
     if (!left_arrow_down &&
       !right_arrow_down &&
       !up_arrow_down &&
       !down_arrow_down)
         key_pressed = false;

     checkForKeyPressed();
    }
Let me know if you'd like a SSCCE.

Thanks