Javascript - 使用delta时间的gameloop

时间:2015-08-13 20:55:28

标签: javascript requestanimationframe game-loop

我正在尝试实现一个使用增量时间的游戏循环。我从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);

1 个答案:

答案 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帧,并调用更新。通过这种方式,您可以确保无论波动如何都会始终调用更新。