Javascript循环无法正常工作(FRAME UPDATE LOOP)

时间:2014-03-16 07:14:16

标签: javascript

当我尝试运行以下代码时,在我的控制台日志中,我得到了#34;完成!!"而不是

  

currentFrame = 0

     

sourceX = 0

假设有一个计数器,并且每300毫秒间隔一次,它就是 假设更新" currentFrame"和" sourceX"变量。条件是真的但是它不输出任何东西,但是"完成!!"。

  • 注 :是的,页面上的所有元素都已正确加载

以下是我的代码:。

            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);
            }

2 个答案:

答案 0 :(得分:1)

现在这是一个有趣的错误: - )

您的问题是this:由setTimeoutsetInterval运行时,默认为window,而不是monster。试试这个:

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

通过将其包装在匿名函数中,你应该没问题。你得到了&#34;完成!!&#34;因为if (window.currentFrame <= window.frames)中的两个属性都未定义。

附注:

您正在使用this.SIZE而不是self.SIZE

每个渲染循环300毫秒可能会产生一个粗糙的动画。

答案 1 :(得分:0)

window.setInterval(monster.updateAnimation,msperFrame);

实际上会被翻译成

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

此功能将从global范围或window范围运行。因此this将是window对象。

当你这样做时

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

正如@erik建议http://jsfiddle.net/Vn3s7/

function(){monster.updateAnimation();}

将从window范围运行。由于monsterglobal范围内window可用,因此'moster.updateAnimation'可用,并且this指针将调用monster本身。