If you are creating a Flash game that used keyboard controls, you may want to be aware of a bug in the Firefox browser (Mac and PC) that causes Flash to ignore keyboard events. When you embed a movie in a page using a transparent or opaque wmode, the movie seems to be unable to acquire keyboard focus. The specific problem is that Key.isDown always returns false. The workaround for this problem is to use Key.getCode instead. However, this is a problem for Flash games, because Key.getCode only returns the value of the last pressed or released key, so you can’t easily use it for multiple simultaneous key-presses.
So, I put together an ActionScript 2 class that can track multiple keypresses and act as a replacement for Key.isDown in cases where it does not work. The nice thing about this class is that it will default to the standard Key.isDown if Flash is working normally. So, if future versions of Firefox fix this problem, then you won’t need to change your code. Usage is simple. Instead of checking Key.isDown, simply use MochiKey.isDown instead.
Installation is simple. In the first frame of your movie, call MochiKey.initialize. After that, the MochiKey class will listen for keyboard events. The way it tracks multiple key presses is that it keeps an array of current keys pressed. When you press a key down, the onKeyDown event callback will add the key to the array. Likewise, the onKeyUp event will remove the key from the array. MochiKey.isDown will return true if the key you are checking is in the array, and false if not.
There is only one drawback to the class. If a user happens to focus on something outside your Flash movie while pressing keys (by using the mouse,) then the keys they were holding down will remain down because the onKeyUp events could not be captured. Once they focus back on the Flash and press those keys again, normal functionality will return. This is a minor issue though for most situations.
Download MochiKey.as. Here is the source:
/**
* Class: MochiKey
* This class offers a replacement for the Key.isDown method, which is faulty in Firefox when
* Flash movies are used with wmode transparent or opaque. This class reverts to the standard
* Key.isDown method if that method works normally.
*
* ------------------------------------------------------------------------------------------
* INSTALLATION:
* Copy MochiKey.as to the same location as your FLA. Add this to the first frame of your
* movie (this MUST be done before anything else!)
* MochiKey.initialize();
*
* ------------------------------------------------------------------------------------------
* USAGE:
* Simply use in a conditional just like Key.
* if (MochiKey.isDown(65)) return true; // checks if the 'A' key is down.
*
* ------------------------------------------------------------------------------------------
* LIMITATIONS: This isDown function keeps a list of keys that are down in order to support
* multiple key presses. If the Flash movie loses focus and keys are released, the onKeyUp
* event will not dispatch. The keys will remain stuck down until they are pressed and released
* again.
*
* @author Geoff Gaudreault
* @version 0.1
*/
class MochiKey extends Key {
// _revert is a flag that is set if standard Key.isDown works.
private static var _revert:Boolean;
// _keyListener is a listener object that receives Key events
private static var _keyListener:Object;
// _downKeys is an array that contains the state of keys pressed
private static var _downKeys:Array;
//
// INITIALIZE created the Key event listener and creates the key down array
public static function initialize ():Void {
_downKeys = new Array();
_keyListener = new Object();
_keyListener.onKeyDown = function ():Void { MochiKey.onKeyDown(); }
_keyListener.onKeyUp = function ():Void { MochiKey.onKeyUp(); }
Key.addListener(_keyListener);
}
/**
* Method: onKeyDown
* Event listener that adds the last pressed key to the list of down keys
*/
public static function onKeyDown ():Void {
//trace("Key pressed: " + chr(Key.getCode()));
_downKeys[Key.getCode()] = true;
}
/**
* Method: onKeyUp
* Event listener that removes the last released key from the list of down keys
*/
public static function onKeyUp ():Void {
//trace("Key released: " + chr(Key.getCode()));
_downKeys[Key.getCode()] = false;
}
/**
* Method: isDown
* Get the down state of a key
* @param keyCode the ASCII key code of the key you want to check
* @return true if the key is down, false if not
*/
public static function isDown (keyCode:Number):Boolean {
if (Key.isDown(keyCode)) {
_revert = true; // if Key.isDown ever returns true, revert to standard Key.isDown method.
return true;
} else if (_revert) {
return false;
}
if (!isNaN(keyCode)) {
if (_downKeys[keyCode] != null) {
return _downKeys[keyCode];
}
}
return false;
}
/**
* Method: letterIsDown
* Get the down state of a key
* @param keyChar the letter of the key you want to check
* @return true if the key is down, false if not
*/
public static function letterIsDown (keyChar:String):Boolean {
if (Key.isDown(Key.getAscii(keyChar))) {
_revert = true; // if Key.isDown ever returns true, revert to standard Key.isDown method.
return true;
} else if (_revert) {
return false;
}
if (keyChar.length == 1) {
var keyCode:Number = Key.getAscii(keyChar);
return isDown(keyCode);
} else {
return false;
}
}
}

Awesome, that is the most annoying bug ever. Thanks for the work-around!
That’s really useful. Very cool.
Do you know of a way to receive keyboard events when Flash doesn’t have focus? I know AS3 can now receive mouse events using MouseEvent.MOUSE_LEAVE.
Cheers.
Philip
Philip,
I’m pretty sure Flash can’t receive any keyboard events if it loses the browser’s focus. If you hear otherwise, let me know!
-g
Looks like Senocular has an AS3 implementation over at Kirupa:
http://www.kirupa.com/forum/showpost.php?p=2098269&postcount=319
The other problem with wmode transparent is is turns all keyboards into american configurations.
Seriously !
how come I keep commenting in the past ?!?!?
omg you went back in time :P
you wrong! actually you’re in the future!
hence the – (minus) :P
how is it there?? did Hillary win election?
no, Arnie is in charge. Unfortunately skynet has now become self aware so he has to go back in time to kill off his grand mother.
or something.
wow it seems we are All in the same future, where are you guys? i’m taking the moonbus now, meet me there :P
Erm.. flash can catch events without focus if you use Zinc and interface with some external dlls.
The problem is that only works for specially compiled projectors, and the resultant coding system would probably be about twelve times are long as the class you just wrote.
…
And how did my post just appear “-1 years, 12 months ago”
Congratulations, Geoff, you’ve got bugs.
nooo it is not a bug, it is a portal to the future :o
I think there is no way that an Flash-Movie gets automatically gets keyboard focus when the site is loaded? With “.focus()” it works in IE but not in Firefox.