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
> 
>  


Reply via email to