我正在尝试实现一个使用增量时间的游戏循环。我从this article获得了以下代码,但我觉得它并不能很好地解释这种类型的游戏循环。我研究过requestAnimationFrame,但没有一个explenations似乎有用。有人可以简单地分解这个循环是如何工作的吗?
function timestamp() {
return window.performance && window.performance.now ? window.performance.now() : new Date().getTime();
},
var now,
dt = 0,
last = timestamp(),
step = 1/60;
function frame() {
now = timestamp();
dt = dt + Math.min(1, (now - last) / 1000);
while(dt > step) {
dt = dt - step;
update(step);
}
render(dt);
last = now;
requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
答案 0 :(得分:3)
requestAnimationFrame
是一个特殊的计时器。与在给定的最小毫秒之后重复执行回调的setInterval
不同,requestAnimationFrame
可变地执行以实现平滑的帧速率。
问题是requestAnimationFrame
如何实现这一目标。根据具体情况,它可能会运行得更快或更慢。这意味着如果您的更新逻辑直接绑定到requestAnimationFrame
,那么当requestAnimationFrame
以60fps运行时,以“每次更新一步”运行的字符将在一秒钟内传输60步,但是当它节流到40fps时,只做40次。
为了抵消计时器的这种突然加速/减速,我们使用“delta time”。您可以检查帧之间的时间,以确定是否是调用更新的正确时间,而不是依赖于requestAnimationFrame
的每次迭代来调用更新。
所以,让我们说你的角色应该每100毫秒做一步。如果游戏以60fps运行,则大约每6帧100ms。这意味着对于每次迭代,您的代码会检查是否已经过了100ms。在它的第6帧左右,并调用更新。现在,如果计时器以40fps运行,则100ms约为4帧。所以相同的逻辑,在每次迭代时它检查是否经过了100ms。在它的第4帧,并调用更新。通过这种方式,您可以确保无论波动如何都会始终调用更新。