Javascript - 使用增量时间的游戏循环

Posted

技术标签:

【中文标题】Javascript - 使用增量时间的游戏循环【英文标题】:Javascript - gameloop using delta time 【发布时间】:2015-08-13 20:55:27 【问题描述】:

我正在尝试实现一个使用增量时间的游戏循环。我从this article 获得了以下代码,但是我觉得它并不能很好地解释这种类型的游戏循环。我对 requestAnimationFrame 进行了研究,但这些解释似乎都没有用。有人可以简单地分解一下这个循环是如何工作的吗?

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】:

requestAnimationFrame 是一个特殊的计时器。与 setInterval 在给定的最小毫秒后重复执行回调不同,requestAnimationFrame 以可变方式执行以实现平滑的帧速率。

问题在于requestAnimationFrame 是如何做到这一点的。根据情况,它可能运行得更快或更慢。这意味着,如果您的更新逻辑直接与requestAnimationFrame 相关联,则在requestAnimationFrame 以60fps 运行时,以“每次更新一步”运行的角色将在一秒钟内移动60 步,但在以60fps 运行时只会移动40 步。它会降低到 40fps。

为了抵消计时器的这种突然加速/减速,我们使用“增量时间”。您无需依赖requestAnimationFrame 的每次迭代来调用更新,而是检查帧之间的时间以查看是否是调用更新的正确时间。

假设你的角色应该每 100 毫秒走一步。如果游戏以 60fps 运行,100ms 大约是每 6 帧。这意味着对于每次迭代,您的代码都会检查 100 毫秒是否已过。在第 6 帧左右,它会调用 update。现在如果计时器以 40fps 运行,100ms 大约是 4 帧。同样的逻辑,在每次迭代时,它都会检查是否经过了 100 毫秒。在第 4 帧它执行并调用更新。这样,您就可以确保无论波动如何,都会始终调用更新。

【讨论】:

upvote ...还提到requestAnimationFrame 的当前版本自动为动画函数提供时间戳。您可以使用该时间戳来计算自您上次进入动画循环以来已经过去了多少时间。重要的是:经过的时间可用于根据经过的时间而不是(可能不规则的)动画循环计数来移动您的角色 任何有效的方法来计算自上一帧以来的时间?

以上是关于Javascript - 使用增量时间的游戏循环的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++ 'for' 循环中放置两个增量语句?

希尔排序

使用 requestAnimationFrame 的 javascript 中一个简单的 30fps 游戏循环?

JavaScript3

直接插入排序与缩小增量插入排序(希尔排序ShellSort)

Javascript 游戏循环