Oneshot Gems
立即玩

游戏开发者指南

跨显示器保持可预测的游戏循环

浏览器游戏循环负责协调模拟、绘制和输入,但不能假设每个显示器每秒都会产生相同数量的帧。回调可能按不同的刷新率运行,在标签页隐藏时暂停,或在主线程繁忙时延迟执行。让模拟基于经过的时间,并由浏览器安排画面呈现。这样更容易理解运动,也能明确控制长时间卡顿后的行为。

本页内容

将状态变化与绘图分开

使用 requestAnimationFrame 请求下一次画面更新,并把它提供的时间戳传给一个简洁的循环协调器。根据经过的时间更新位置、计时器和规则,然后绘制当前状态。渲染器不应负责判断是否发生碰撞,碰撞检测也不应取决于精灵是否恰好被绘制出来。

做一个简单的平台移动测试:让标记以选定的世界单位/秒水平移动,分别在 60 Hz 显示器和高刷新率显示器上运行同一路径。如果在相同的实际时间内,标记在某个显示器上移动得更远,说明仍有部分移动量是按每次回调计算的,而非按时间计算。

选择延迟帧的恢复策略

长时间暂停会产生很大的时间间隔。对于轻量的实时游戏,应限制这段时间,避免玩家回来时看到角色瞬间穿过多个障碍。对于确定性模拟,应使用带累加器的固定更新步长,限制追赶更新的次数;如果插值有帮助,可以在模拟状态之间绘制画面。

在可重复的障碍路线中记录最长的回调间隔,然后切换到其他页面再返回,检查游戏状态。明确决定游戏应暂停、少量追赶时间,还是从上一个状态继续;不要让一次延迟的回调替你做决定。

关于⁨浏览器游戏循环⁩的常见问题

我应该使用 setInterval 进行绘图吗?

使用 requestAnimationFrame 进行视觉工作,因为它安排在重绘附近,并且通常会因隐藏文档而暂停。计时器仍然可以安排非视觉任务,但不应将其视为显示时钟。

帧时间戳从何而来?

requestAnimationFrame 回调提供高分辨率时间戳。 MDN 记录了其时间安排和一次性行为;使用该时间戳来计算进度而不是计算回调。

延伸阅读

发现信息过时了? 报告需要更正的内容

继续玩下去。

免费浏览器游戏,随时等你开玩。发现喜欢的游戏,让它成为你的下一个最爱。

跟随好奇心探索