KeyManager Class for Detecting Key Press Combos or Sequences
Posted by: Keith H in ActionScript 3, Adobe AIR, Flash 9, Flex, Games, tags: ASWD, control, dev mode, easter eggs, key press, Keyboard, KeyboardEvent, videogamesWhen I am writing a flash app or game which uses the keyboard to control a character's movement, there is a situation that becomes annoying while controlling the character. I do not know the proper term for it ("sticky keys"?) but I will describe it...
When an app or game is written we "expect" the user to precisely press the proper key or key combination at a time to execute programmatic actions. However, most of us have ten fingers and we use more than one finger to press more than one button on the keyboard. The expected program reaction from multiple fingered keyboard input might not occur because you have another function executing when you expect just one at a time.
Key Combinations
Imagine you are using the keyboard to play a game. The RIGHT arrow key is for moving your character right, the LEFT arrow key is for moving your character LEFT.
Ok, the action in this game is heating up, you are pressing LEFT to avoid the lasers shooting at you. You successfully dodged the lasers, now you press RIGHT to move in and attack...but in the heat of battle, your other finger is still on the LEFT button. What happens now is your character most likely gets stuck, because both movement keys are pressed telling the character to go in opposite directions!
In some cases allowing multiple key presses is how you want the app to react. For example you want the user to press both UP and RIGHT keys to move the characters in a diagonal direction. When to allow this and when not can be different among all of the control buttons. It becomes messy having to write "If" and "switch" statements to make the KeyboardEvent listeners work according to the different controls needed.
Key Sequences
If you love video games cheats or the easter eggs developers sometimes place in apps you'll remember to access them, you will usually enter in a sequence of key presses. If you entered the sequence successfully you would have access to cool game cheats or some special developer mode of an application.
KeyManager
For the above reasons I've written a KeyManager class to add key control that allows individual keys/keycombos the option to cancel out the any previous key/keycombo that are pressed down...and when key/keycombos are released, whatever key/keycombo that are still pressed will be active again. And for detecting key press sequences the KeyManager class will allow also.
This is a basic example using KeyManager. The "addKey" method is for adding key press combos and the "addKeySequence" is for obviously adding
key press sequences.
In the working flash example, you can click "singular combos" checkbox to false, to see the problem described previously about the character getting stuck when pressing RIGHT and LEFT key at the same time. When you set the checkbox back to true you will notice how each new key press overrides any others that are still down. This results in responsive execution if a user has a habit of holding down other keys while pressing new ones..
Also in the working sample above if you enter in the proper key sequence you will be rewarded with an "Easter Egg" to view the source and FLA.
Example usage:
import net.keithhair.KeyManager; var keyManager:KeyManager; keyManager=new KeyManager(stage); keyManager.addKey(["right"], goRight,stopRight,"control1"); keyManager.addKey(["left"], goLeft,stopLeft,"control2"); keyManager.addKey(["up"], goUp,stopUp,"control3"); keyManager.addKey(["down"], goDown,stopDown,"control4"); keyManager.addKey(["shift","w","t"], toggleWindow); keyManager.addKeySequence(["up","up","down","down","left","right","left","right"],openEasterEgg);
Entries (RSS)
Damn, this thing is cool!
Thanks for sharing.
You inspired me all the way.
Thanks very much. Implementation is cool. I tried this in my game works greatly
You’re the best !
Great class Keith! Nice one mate. Cheers.
can macromedia flash 8 execute this properly?
Jay, this class is for AS3, you are welcome to make an AS2 version of it.
that’s easy…………
So easy a caveman can do it?
Can this be used for mixed combos? like P+K,K,K,J
Individual key combinations within a key sequences Array (such as ["P+K","K","K","J"]) will not work in this class. Feel free to add support for it though.
Hey Keith,
Your key manager doesn’t handle the commandKey bug with Flash Keyboard Events on Mac. To see this, uncheck singular combos. Press & hold command key, move the box using any arrow key, and release the arrow key. The box will continue to move off in the direction last pressed, even if you then release the command key.
The problem is that any keys pressed while command key is down will not generate a KEY_UP event. I’ve logged this bug with Adobe https://bugs.adobe.com/jira/browse/FP-5089
The only semi decent workaround I’ve found is listening explicitly for command key KEY_UP event, and removing all registered KEY_DOWN references. Sucks, but I haven’t found any other means to workaround the bug.
Hello
Proceeding the Function Keys (F1 – F10) actually doesn’t work.
The Key code for e.x. the F10 key is 121,
inside the __onKeyDown methode it handles this keycode like a “y” (std. ascii code) and converts it to an uppercase “Y”
which then is another key (code 89) and the previously defined handler for the F10 key is obviously never called….
the workaround for me was to commend out the block
if (k >= 97 && k <= 122)
{
k=String.fromCharCode(k).toUpperCase().charCodeAt(0);
}
inside the __onKeyDown handler…
why is this check actually included?
Flex and AIR apps what i know proceed only the uppercase ascii codes, so if you hit "a" the keyCode will be 65 and not 97…
beside that i really appreciate your KeyManager class,
so thx a lot for your work and sharing it!
greetings