在setTimeout之后找不到对象方法

时间:2013-03-14 01:41:57

标签: html5 canvas timeout game-loop

LoCEngine.prototype.runGame = function() {
    // Initiate our game loop
    ctx.clearRect(0, 0, 800, 600);
    this.drawScene(this.curScene);
    if(this.gameRunning) {
            window.setTimeout(Engine.runGame, 1000 / this.framerate);
    }
}

LoCEngine是一个实验性引擎,我一直在努力学习HTML5 Canvas游戏的细节。这是一个非常好的时光,直到我遇到游戏循环。随着时间的推移调用runGame,它会清除Canvas并调用drawScene函数。

LoCEngine实例存储在变量Engine中(不确定是否在setTimeout中使用它是最佳实践...请指教)

它会正确调用this.drawScene作为第一帧,但是在Timeout(30 FPS)时它会抛出一个异常说:

TypeError: this.drawScene is not a function

不太确定为什么......我确定这只是关于JS的一些我没有遇到的事情。提前谢谢。

1 个答案:

答案 0 :(得分:1)

你需要这样做才能正确调用方法:

LoCEngine.prototype.runGame = function() {
    // Initiate our game loop
    ctx.clearRect(0, 0, 800, 600);
    this.drawScene(this.curScene);
    if(this.gameRunning) {
            window.setTimeout(function() {
                Engine.runGame()
            }, 1000 / this.framerate);
    }
}

当您将Engine.runGame传递给setTimeout()时,它只会传递方法引用本身,并且对象部分会丢失。因此,当它由setTimeout()的内部调用时,它在this中不再具有正确的对象引用,并且当代码尝试基于{{1}调用另一个方法时,它会生成您看到的错误}。解决方法是用我所展示的匿名函数自己调用它。

也可以使用this,它在内部基本上对你做同样的事情。但是,旧版浏览器不支持.bind(),因此我倾向于使用匿名函数。