Thanks for your response Alex. I added the key listeners to the stage, after having an issue with a null stage reference when trying to get the stage off the Canvas during creationComplete. I changed it to applicationComplete and it worked. I still have to click on the App to get focus there.
Unfortunately, I still can't reproduce the original problem, which involves using a timer to manage the many events generated when holding down a key. It works for awhile, meaning you hold down a key and the image continues to move across the screen. But then after awhile it stops working, the image stops moving while still holding the key down. Once the continued movement stops while holding down the key, it moves once when you press and hold the key down, and once again on KeyUp. I tried adding debug statements and here's where it gets even weirder. I've placed a text area below the Canvas where I write my debug statements so I can see them in real-time instead of having to go look at the trace output afterward. I added this to this smaller app below as well. I added a 'logFlag' because I don't want to log all these messages until it stops working. So I'll move around a bit until it stops working, then go into the debugger and set the logFlag to true, and continue to try to move around. At this point the error stops, when I have the logFlag turned on. That's what's even more baffling. I'm purely speculating, but it's almost like it's losing track of some of the timerComplete events and not calling the timerCompleteHandler method, unless there's another 'hook' in that timerCompleteHandler method, the 'hook' being the method call to the log TextArea. I know it doesn't make much sense, but that's the behavior I've been seeing. Should I repost this under another subject about timing events and/or a keyboard buffer, since we're beyond KeyboardEvents now? The mxml from the 'smaller' app is below again. It's bigger because I've included various bits from a few classes in my real app, in an attempt to include all the pieces that may have an impact on the problem. But again, this smaller app still doesn't reproduce the original problem. At one time I wondered if it had to do with memory management, since I'm adding lots of small 'tile images' as I move around, so I added a bit like that here as well. But I still can't reproduce the problem <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="800" height="600" applicationComplete="initApp()"> <!--creationComplete="initApp()" --> <mx:Script> <![CDATA[ import mx.controls.Image; import mx.managers.SystemManager; import flash.events.KeyboardEvent; import flash.utils.Timer; [Embed(source="../images/tiles13x13/man.gif")] public static var MAN:Class; [Embed(source="../images/tiles13x13/floor.gif")] public static var FLOOR:Class; const KEY_DOWN:String = "2"; const KEY_UP:String = "8"; const KEY_RIGHT:String = "6"; const KEY_LEFT:String = "4"; const DIR_LEFT:int = 0; const DIR_RIGHT:int = 1; const DIR_UP:int = 2; const DIR_DOWN:int = 3; var tileSize:int = 13; var curX:int; var curY:int; var keyEventReady:Boolean = true; var moveEventLogging:Boolean = false; var timer:Timer; var numLines:int; var moveEventNum:int=0; function initApp():void { log("into initApp"); //map.setFocus(); map.stage.addEventListener(KeyboardEvent.KEY_UP, keyUpEventHandler); map.stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownEventHandler); image.source = MAN; curX = 10; curY = 15; image.x = curX * tileSize; image.y = curY * tileSize; timer = new Timer(40, 1); timer.addEventListener(TimerEvent.TIMER_COMPLETE, timerCompleteHandler); } public function keyDownEventHandler(e:KeyboardEvent):void { if(keyEventReady) { moveEventNum++; keyEventReady = false; var char:String = numToChar(e.charCode); var direction:int; if(char == KEY_DOWN) { direction = DIR_DOWN; } else if(char == KEY_UP) { direction = DIR_UP; } else if(char == KEY_LEFT) { direction = DIR_LEFT; } else if(char == KEY_RIGHT) { direction = DIR_RIGHT; } if(moveEventLogging) log("firing moveEvent " + moveEventNum); // in the real app, I dispatch an event here because there are multiple handlers handleMoveEvent(direction); if(moveEventLogging) log("moveEvent handling done " + moveEventNum); timer.reset(); timer.start(); } } function handleMoveEvent(direction:int):void { // first, put a floor tile down where we were var floor:Image = new Image(); floor.x = curX * tileSize; floor.y = curY * tileSize; floor.source = FLOOR; map.addChild(floor); switch(direction) { case(DIR_RIGHT): curX++; break; case(DIR_LEFT): curX--; break; case(DIR_UP): curY--; break; case(DIR_DOWN): curY++; break; } image.x = curX * tileSize; image.y = curY * tileSize; } public function keyUpEventHandler(e:KeyboardEvent):void { if(moveEventLogging) { log("keyUp"); } timer.stop(); keyEventReady = true; } public function timerCompleteHandler(e:TimerEvent):void { if(moveEventLogging) { log("timer Complete " + moveEventNum); } keyEventReady = true; } function log(msg:String):void { if(numLines > 50) { messageLog.text = ""; numLines = 0; } messageLog.text = messageLog.text.concat(msg + "\n"); messageLog.validateNow(); messageLog.verticalScrollPosition = messageLog.maxVerticalScrollPosition; trace(msg); numLines++; } function numToChar(num:int):String { if (num > 47 && num < 58) { var strNums:String = "0123456789"; return strNums.charAt(num - 48); } else if (num > 64 && num < 91) { var strCaps:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; return strCaps.charAt(num - 65); } else if (num > 96 && num < 123) { var strLow:String = "abcdefghijklmnopqrstuvwxyz"; return strLow.charAt(num - 97); } else { return num.toString(); } } ]]> </mx:Script> <mx:Canvas id="map" left="6" top="32" right="148" bottom="132" backgroundColor="#010101" > <mx:Image id="image" /> </mx:Canvas> <mx:HDividedBox height="120" bottom="6" right="148" left="6"> <mx:TextArea id="messageLog" cornerRadius="6" editable="false" width="50%" height="100%"/> <mx:Canvas id="otherStuff" cornerRadius="8" width="50%" height="100%" backgroundColor="#ffffff"/> </mx:HDividedBox> </mx:Application> --- In [email protected], "Alex Harui" <[EMAIL PROTECTED]> wrote: > > Kinda surprised it worked at all. Canvas or one if its children would > need to have focus for this to work and normally they do not receive > focus because they are not IFocusManagerComponent. Listening to the > stage will get keystrokes no matter who has focus. You'll probably have > to do that or subclass Canvas to be an IFocusManagerComponent > >

