1

我试图公然撕掉小行星,但我遇到了一个严重的内存管理问题。

我正在使用 window.requestAnimationFrame 为我的游戏提供帧,方法是使用“gameloop”函数调用 requestAnimationFrame 并将其自身作为参数。但是,我一定是做错了什么,因为我的游戏的内存使用量很大,导致频繁的垃圾收集和性能不佳(以及与之相关的典型锯齿状内存使用模式)。我很确定这个问题的原因是许多函数对象是由这个函数和回调循环创建的——可能是一些无害的语句导致一个函数被创建而不是被重用......可能是 gameloop 函数。 ..

我从这篇文章中得到了这个想法:https ://www.scirra.com/blog/76/how-to-write-low-garbage-real-time-javascript

这是一个带有我的代码的 jsfiddle:http: //jsfiddle.net/LEqUr/(点击空格,窗口处于焦点位置以使新的小行星出现)。我知道我的一些东西是驼峰式的,有些是用下划线完成的——对不起。

这是(我认为)代码中最相关的部分:

var gameLoop = function () {
    getSetStageSize(1, 1);
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    updateGameState();
    window.requestAnimFrame(gameLoop);
}

window.requestAnimFrame = (function () {
    return window.requestAnimationFrame || 
       window.webkitRequestAnimationFrame || 
       window.mozRequestAnimationFrame || 
       function (callback) {
               window.setTimeout(callback, 1000 / 60);
           };
})();

综上所述,我真的很想得到一些关于我的代码是如何组织的反馈(它肯定可以使用一些工作)、一些关于回调的信息、一些关于如何/何时在疯狂的嵌套回调中创建对象的信息以及任何其他有用的信息你可能有的建议。

谢谢!

4

1 回答 1

0

我不太了解动画特定的部分,但您可以稍微简化最后一部分。您不需要 IIFE,因为您没有声明任何局部变量。

window.requestAnimFrame = (
    window.requestAnimationFrame || 
    window.webkitRequestAnimationFrame || 
    window.mozRequestAnimationFrame || 
    function (callback) {
        window.setTimeout(callback, 1000 / 60);
    }
);

除此之外,您可能会考虑编写代码以在幕后使用 setInterval 而不是 setTimeout。当您使用 setTimeout 时,每帧的实际时间是超时后的 (100/60) 加上您的代码处理该帧所需的时间。另一方面,setInterval 更了解幕后的真实时钟,并会调整帧之间的超时时间以补偿处理时间。

于 2013-09-10T21:38:53.060 回答