为什么毫秒计数器在 requestAnimationFrame() 中一直运行?

我正在用 JavaScript 制作游戏,使用了很棒的requestAnimationFrame(callback)功能。


今天我了解到,requestAnimationFrame()自从我们打开该页面以来,传递给的回调得到了一个高分辨率时间。让我们称之为ms:


function paint(ms) {

    // draw my game

    requestAnimationFrame(paint);

}


requestAnimationFrame(paint);

一切都很好,但有一件事我不太明白。


requestAnimationFrame()当我们转到另一个选项卡时,函数不执行任何操作,因此暂停渲染。另一方面,当我们离开时,传递给回调的时间仍在继续。因此,我不确定如何使用该值。如果它与渲染引擎成比例地工作,我可以ms用来计算我的游戏的逻辑时间,因为依靠requestAnimationFrame()稳定的 60 FPS 听起来并不是最好的主意。


我错过了什么吗?ms如果我们离开选项卡时它继续计数,该参数的目的是什么?


开满天机
浏览 426回答 2
2回答

SMILET

添加到凯多的答案。限制时间增量在应用程序中也很常见。例如,应用程序中帧率独立计算的一种常见方法是计算帧之间的时间let previousTime = 0;function loop(currentTime) {  const deltaTime = currenTime - previousTime;  previousTime = currentTime;  // use deltaTime in various calculations  posX = posX + velX * deltaTime;  requestAnimationFrame(loop);}requestAnimationFrame(loop);但是,有时如果deltaTime太大,碰撞或其他数学运算可能会中断,因此游戏通常会添加限制器  // don't let deltaTime be more than a 1/10 of a second  const deltaTime = Math.min(currenTime - previousTime, 1000 / 10);这主要消除了检查onvisiblitiychange. 特别是如果您保留自己的动画/游戏时钟。let previousTime = 0;let clock = 0;let clockRate = 1;function loop(currentTime) {  const deltaTime = Math.min(currenTime - previousTime, 1000 / 10) * clockRate;  previousTime = currentTime;  clock += deltaTime;  // update our own clock  requestAnimationFrame(loop);}requestAnimationFrame(loop);现在,如果玩家隐藏选项卡,不仅不会或时钟不会跳转,而且clockRate如果我们想要暂停,我们可以设置为 0。为什么要使用自己的时钟?它使您可以轻松地减慢或加快依赖于该时钟的所有计算的时间(见clockRate上文)。许多应用程序(游戏)也有多个时钟。他们会为每个时钟计算不同的 deltaTime。例如,所有需要暂停的对象都需要一个时钟,即使应用程序/游戏暂停,时钟也需要继续运行。另一个可能是玩家的时钟与敌人的时钟,这样当玩家使用他们的“慢时间超能力”时,敌人的动作会变慢,但玩家的动作会保持相同的速度。

鸿蒙传说

这只是一个时间戳,它并没有真正计算任何东西。它确实通常与performance.now()它给出的时间量相同,因为页面处于活动状态。至于为什么,这就是DOMHighResTimeStamp 的来源是如何定义的。我们通常使用它来了解自某些先前事件发生以来已经过去了多长时间,即我们存储一个 start_time,然后检查当前时间戳,我们可以获得动画的增量时间,而不管实际帧速率如何.顺便说一句,不,依赖requestAnimationFrame于任何固定帧率确实不是一个好主意,requestAnimationFrame不依赖于任何规格的帧率,实际上建议将其与屏幕刷新率对齐(尽管只有 Blink 这样做)。因此,您实际上需要依赖这样的时间戳才能在不同的设置中保持一致的速度。pos++在每一帧都做一个简单的操作会让你的动画在 120Hz 显示器上比在 60Hz 显示器上运行快两倍(至少在 Chrome 中)。这只会让你的想法更复杂,难以理解它是如何实现的:当窗口移动到 120Hz 显示器时,你的绘图计时器会快两倍吗?这个时间戳也可能有助于赶上长帧,这并不是因为系统出现了问题,您就一定希望动画持续更长时间。同样,并非所有情况都希望在窗口模糊时停止动画逻辑。假设我有一个带有 rAF 支持的背景动画的标题,我真的不希望它在离开屏幕时暂停,即使它没有被绘制。如果您希望您的游戏逻辑在窗口模糊时暂停,请侦听onvisibilitychange并保存当前时间戳(performance.now()因为我们在 rAF 之外,所以使用此时间戳)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript