我正在使用<canvas>
与JS / Coffeescript进行一场小游戏。
截至目前,我的绘制循环是使用requestAnimationFrame完成的:
draw: () =>
# Various drawing code.
requestAnimFrame(@draw, @canvas)
虽然我的更新循环是一个简单的setInterval
:
setInterval(() => @update Date.now(), 1000/FPS)
我将它们分开,以便绘图不会被不相关的更新代码堵塞,认为这可能是正确的方法。
但是吗?是否有意义?如何以最低的系统成本确保流畅的动画?
答案 0 :(得分:1)
同时使用requestAnimationFrame
(rAF)和setInterval
只会产生额外的开销。
这是因为JavaScript是单线程的,必须逐个执行范围。如果JS引擎位于rAF的作用域内,那么setInterval作用域的执行将作为在 rAF退出当前作用域后执行的事件排队 - 或者反之亦然。并且代码仍然可能被阻塞/堆叠(由于setInterval
)。
所以没有任何好处,恰恰相反,因为有更多的代码要执行(更多有时更少,但在这种情况下不是)包括。内部堆栈推送和弹出,事件的创建和排队,额外的代码解析等 - 可能在微观层面,但它的代码是昂贵的,然后它可能很重要。话虽这么说,考虑使用30 fps而不是60 fps,这在大多数情况下是充足的,它会使你的预算增加一倍。
对于rAF,您的“时间预算”通常约为16.7毫秒。无论你做什么,你都必须得到你需要的代码来创建一个在该时间范围内执行的帧。如果不是,则跳过一帧(或更多)。
关键是优化代码以及如何将场景组合在一起,无论是字面还是抽象。尽可能缓存所有内容(内存是你的朋友),只更新所需内容等等。对此没有通用的答案,因为它取决于具体情况,最佳的做事方式是什么。