我正在使用很棒的 requestAnimationFrame(callback)
函数用 JavaScript 制作游戏。
今天我了解到传递给 requestAnimationFrame()
的回调获得了 self 们打开该页面以来测量的高分辨率时间。我们称它为 ms
:
function paint(ms) {
// draw my game
requestAnimationFrame(paint);
}
requestAnimationFrame(paint);
一切都很好,但有一件事我不太明白。
当我们转到另一个选项卡时,函数 requestAnimationFrame()
不会执行任何操作,因此渲染会暂停。另一方面,传递给回调的时间在我们离开时仍然继续。因此,我不确定如何使用该值。如果它与渲染引擎成比例地工作,我可以使用 ms
来计算我的游戏的逻辑时间,因为依赖 requestAnimationFrame()
作为稳定的 60 FPS 听起来并不喜欢最伟大的想法。
我错过了什么吗?如果 ms
参数在我们离开标签页时继续计数,它的目的是什么?
最佳答案
那只是一个时间戳,并没有什么实际意义。它实际上通常与 performance.now()
相同,后者给出自页面处于事件状态以来的时间量。至于为什么,这就是DOMHighResTimeStamp's origin已定义。
我们通常用它来了解自某个先前事件发生以来经过了多长时间,即我们存储一个开始时间,然后检查当前时间戳,我们可以获得动画的增量时间,而不管实际时间帧速率。
顺便说一下,不,依赖于 requestAnimationFrame
处于任何固定帧率确实不是一个好主意,requestAnimationFrame
不依赖于任何帧率根据规范,实际上建议将其与屏幕刷新率对齐(尽管只有 Blink 这样做)。
所以您实际上需要依赖这样的时间戳,以便在不同的设置中保持一致的速度。在每一帧执行一个简单的 pos++
将使您的动画在 120Hz 显示器上的运行速度比在 60Hz 显示器上快两倍(至少在 Chrome 中是这样)。
这只会让您的想法变得更加复杂,难以理解它是如何实现的:当窗口移动到 120Hz 显示器时,您的绘画计时器会快两倍吗?
这个时间戳也可能有助于 catch 长帧,这并不是因为系统有问题你一定希望你的动画持续更长时间。
同样,并非所有情况都希望动画逻辑在窗口模糊时停止。假设我有一个带有由 rAF 驱动的背景动画的标题,我真的不希望它在离开屏幕时暂停,即使它没有被绘制。
如果您希望游戏逻辑在窗口模糊时暂停,请监听 onvisibilitychange
,并保存当前时间戳(使用 performance.now()
因为我们在 rAF 之外)。
关于javascript - 为什么毫秒计数器在 requestAnimationFrame() 中一直走?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58984325/