2
votes

N.B. Keep in mind the difference between key code and character code. For example, the number 1 (one) and the character ! (bang) both have the same key code but different character codes. Likewise, the number 7 from the row of numbers and the number 7 from the numpad have different key codes but the same character codes.

I'm programming a music rhythm game in Adobe Flex and would like to bind keyboard keys. This isn't a problem, but I certainly would have a problem, say, setting the default keys to A, S, D, and F and telling the user that this is the case.

If you take a look at the documentation for flash.ui.Keyboard, you'll see that there are constants for keyboard keys to key codes. However, these are only available in Adobe AIR and not the browser. This makes sense since not all operating systems and keyboards are alike (or present!), so key codes can vary.

So, how can I assign default keys that have meaning instead of picking key codes and praying?

My only sane thought is to store the character codes for the key bindings and then provide an character code to String mapping so I can tell the user what to press. However, my gut tells me that this will break in subtle or not-so-subtle ways. Like CAPSLOCK.

Thanks.

Update: I am currently using radekg's answer, but I still think that this will break easily. I would feel more comfortable with some persuasion that this is correct.

2

2 Answers

4
votes

according to Flash 8 documentation you can simply rely on ASCII codes. Take a look at these topics of the Flash 8 documentation:

As far as I'm aware of all modern operating systems use standard ASCII. These codes have not changed since Flash 5 era. To compare letters if you don't want to rely on ASCII codes:

private function compareChar(code:Number):void {
    if ( "a" == String.fromCharCode( code ).toLowerCase() ) {
        trace("A pressed");
    } else {
        trace("You pressed " + String.fromCharCode(code));
    }
}
...
compareChar(65); // 65 is A
compareChar(96); // 96 is numpad 0

However I think you can rely on ASCII codes. Hope this helps.

2
votes

Radekg is mostly correct.

Flash has a built in Class flash.ui.KeyLocation with four static properties: LEFT, RIGHT, NUM_PAD, STANDARD. This means that you can have a definitive idea which key has been pressed, even if the keyboard has been remapped. If you this in combination with String.fromCharCode, you should be able to solve this problem rather neatly.

Your final code might look like:

import flash.ui.KeyLocation;
import flash.events.KeyboardEvent;

function handleKeyboardEvent( event:KeyboardEvent )
{
    // This will work for a majority of the keys.
    var key:String = String.fromCharCode( event.charCode ).toLowerCase();

    // Use strict comparison
    if( event.keyLocation !== KeyLocation.STANDARD )
    {
        // The key is a number, then it needs to be re-identified.
        if( event.keyLocation == KeyLocation.RIGHT  )    key = "r" + key;
        if( event.keyLocation == KeyLocation.LEFT   )      key = "l" + key;
        if( event.keyLocation == KeyLocation.NUM_PAD)   key = "n" + key;
    }

    switch( key )
    {
        case "r1":
            // Do something with the one which is not on the keypad.
            break;
        case "n.":
            // Do something with the number pad's period.
            break;
        case "n":
            // Do something with the letter N.
            break;
    }
}

I will admit, I am not certain what will happen with String.fromCharCode and control keys (F1, Alt, Ctrl, etc), but the KeyboardEvent does support event.shiftKey, event.ctrlKey, event.altKey