2 回答
TA贡献1796条经验 获得超4个赞
添加到凯多的答案。限制时间增量在应用程序中也很常见。例如,应用程序中帧率独立计算的一种常见方法是计算帧之间的时间
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。例如,所有需要暂停的对象都需要一个时钟,即使应用程序/游戏暂停,时钟也需要继续运行。另一个可能是玩家的时钟与敌人的时钟,这样当玩家使用他们的“慢时间超能力”时,敌人的动作会变慢,但玩家的动作会保持相同的速度。
TA贡献1865条经验 获得超7个赞
这只是一个时间戳,它并没有真正计算任何东西。它确实通常与performance.now()
它给出的时间量相同,因为页面处于活动状态。至于为什么,这就是DOMHighResTimeStamp 的来源是如何定义的。
我们通常使用它来了解自某些先前事件发生以来已经过去了多长时间,即我们存储一个 start_time,然后检查当前时间戳,我们可以获得动画的增量时间,而不管实际帧速率如何.
顺便说一句,不,依赖requestAnimationFrame
于任何固定帧率确实不是一个好主意,requestAnimationFrame
不依赖于任何规格的帧率,实际上建议将其与屏幕刷新率对齐(尽管只有 Blink 这样做)。
因此,您实际上需要依赖这样的时间戳才能在不同的设置中保持一致的速度。pos++
在每一帧都做一个简单的操作会让你的动画在 120Hz 显示器上比在 60Hz 显示器上运行快两倍(至少在 Chrome 中)。
这只会让你的想法更复杂,难以理解它是如何实现的:当窗口移动到 120Hz 显示器时,你的绘图计时器会快两倍吗?
这个时间戳也可能有助于赶上长帧,这并不是因为系统出现了问题,您就一定希望动画持续更长时间。
同样,并非所有情况都希望在窗口模糊时停止动画逻辑。假设我有一个带有 rAF 支持的背景动画的标题,我真的不希望它在离开屏幕时暂停,即使它没有被绘制。
如果您希望您的游戏逻辑在窗口模糊时暂停,请侦听onvisibilitychange
并保存当前时间戳(performance.now()
因为我们在 rAF 之外,所以使用此时间戳)。
添加回答
举报