简体   繁体   中英

Javascript loop not working properly (FRAME UPDATE LOOP)

When I try to run the following code, on my console log, I get "Done!!", instead of getting

currentFrame=0

sourceX=0

It's suppose to have a counter, and with and interval of every 300 millisecond, it's suppose to update the "currentFrame" and "sourceX" variable. The condition is true nevertheless It doesn't output anything but "Done!!".

  • Note : yes, all elements on the page are loaded properly

The following is my code:.

            var canvas = document.querySelector("canvas");
            var drawingSurface = canvas.getContext("2d");
            var tileSheet = new Image();
            tileSheet.src="frames.png";

            var msperFrame = 300;

            var interval;
            SIZE=128;

            tileSheet.addEventListener("load",loadHandler,false);

            var monster={
                frames:6,
                SIZE:128,
                currentFrame:0,
                sourceX:0,
                sourceY:0,
                updateAnimation: function(){
                    var self=this;
                    if(self.currentFrame <= self.frames){
                        self.sourceX = self.currentFrame*this.SIZE;
                        console.log("Current Frame: "+self.currentFrame+"\nSourceX: "+self.sourceX);
                        self.currentFrame++;
                        render();
                    }else{
                        console.log("Done!!");
                        window.clearInterval(interval);
                    }
                }
            };

            function loadHandler(){
                interval = window.setInterval(monster.updateAnimation,msperFrame);
            }

            function render(){
                drawingSurface.drawImage(tileSheet,
                monster.sourceX,monster.sourceY,monster.SIZE,monster.SIZE,
                0,0,monster.SIZE,monster.SIZE);
            }

Now that's a funny bug :-)

Your problem is this : When run by setTimeout or setInterval , it defaults to window , not monster . Try this:

interval = window.setInterval(function(){monster.updateAnimation();},msperFrame);

By wrapping it inside an anonymous function, you should be fine. You're getting "Done!!" because both properties in if (window.currentFrame <= window.frames) are undefined.

Side notes:

You're using this.SIZE instead of self.SIZE .

300 ms per render loop might produce a chunky animation.

window.setInterval(monster.updateAnimation,msperFrame);

will in effect get translated into

window.setInterval(function(){
                var self=this; //here 'this' is window
                if(self.currentFrame <= self.frames){
                    self.sourceX = self.currentFrame*this.SIZE;
                    console.log("Current Frame: "+self.currentFrame+"\nSourceX: "+self.sourceX);
                    self.currentFrame++;
                    render();
                }else{
                    console.log("Done!!");
                    window.clearInterval(interval);
                }
            },msperFrame);

This function will be run from global scope, or from window scope. So this will be window object.

When you do

window.setInterval(function(){monster.updateAnimation();},msperFrame);

as @erik suggested http://jsfiddle.net/Vn3s7/

function(){monster.updateAnimation();}

will be run from window scope. As monster is available as global in window scope, 'moster.updateAnimation' is available and will be called with this pointer as monster itself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM