views:

66

answers:

2

What is the correct way to detect held keys in a flash game? For example, I want to know that the right arrow is held to move the player.

Naive code:

function handleKeyDown(event:KeyboardEvent) {
    held[event.keyCode] = true;
}

function handleKeyUp(event:KeyboardEvent) {
    held[event.keyCode] = false;
}

stage.addEventListener(KeyboardEvent.KEY_DOWN, handleKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, handleKeyUp);

The naive code has problems on some computers. The KEY_DOWN event is alternating with KEY_UP many times for a held key there. That makes the key appear to be released in some frames.

An example of the seen events:

[Just holding a single key.]
KEY_DOWN,KEY_UP,KEY_DOWN,KEY_UP,KEY_DOWN,KEY_UP,...
A: 

here's a quick fix , with the limitation that it can only work one key at a time

var currentKey:uint;

function handleKeyDown(event:KeyboardEvent) {
    held[event.keyCode] = true;

    //make sure the currentKey value only changes when the current key 
    //has been released. The value is set to 0 , 
    //but it should be any value outside the keyboard range
    if( currentKey == 0 )
    {
        currentKey = event.keyCode;

       //limitation: this can only work for one key at a time
       addEventListener(Event.ENTER_FRAME , action );
    }
}

function handleKeyUp(event:KeyboardEvent) {
    held[event.keyCode] = false;

    if( currentKey != 0 )
    {
        //reset
        removeEventListener(Event.ENTER_FRAME , action );
        currentKey = 0;
    }
}

function action(event:Event):void
{
   //your code here
}

stage.addEventListener(KeyboardEvent.KEY_DOWN, handleKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, handleKeyUp);
PatrickS
Sorry for a misunderstanding. The problem with alternating KEY_UP events remains unsolved. If the alternating KEY_UP is seen as the last event, currentKey will be 0. That would result in a pause in the motion.
Ivo Danihelka
well yes, but the motion will start as soon as the key is pressed again. i assumed that you would need a way for the motion to stop when the key is released. the idea was to cover all the unintentional key up events. the alternative is to stop the motion by pressing another key.
PatrickS
A: 

My workaround is to remember the keys that were seen down at least once in this frame.

function handleKeyDown(event:KeyboardEvent) {
    held[event.keyCode] = true;
    justPressed[event.keyCode] = true;
}

function handleKeyUp(event:KeyboardEvent) {
    held[event.keyCode] = false;
}

// You should clear the array of just pressed keys at the end
// of your ENTER_FRAME listener.
function clearJustPressed() {
    justPressed.length = 0;
}

And I use a function to check if a key was down in this frame:

function pressed(keyCode:int) {
    return held[keyCode] || justPressed[keyCode];
}
Ivo Danihelka
justPressed.length = 0; instead of justPressed = []. Why create new array every frame when you can reuse old one?
alxx
@alxx Thanks. I updated the code.
Ivo Danihelka