桌面端requestAnimationFrame返回70fps致NES模拟器运行过快,求解决方案
NES模拟器帧率异常问题分析与解决
桌面端FPS过高的原因
- 显示器刷新率差异:多数桌面显示器支持75Hz或更高刷新率(比如电竞屏常见144Hz),
requestAnimationFrame的回调触发频率会与显示器刷新率同步。你的桌面设备刚好是70-71Hz左右的刷新率,因此回调按这个频率执行;而Samsung S20的屏幕是标准60Hz,所以回调稳定在60fps。 - NES的固定运行逻辑:NES主机的CPU运行频率为1.79MHz,游戏逻辑、音频输出完全基于这个固定时钟周期推进。如果模拟器直接绑定
requestAnimationFrame的帧率来执行模拟循环,当帧率高于60时,整个模拟进程的速度就会超出原始主机的标准速率,导致游戏和音频加速。
解决方案不止是FPS限制函数
有几种更专业的处理方式,比单纯限制帧率更可靠:
- 时钟周期同步法:这是模拟器开发的标准方案。计算NES CPU每帧需要执行的时钟周期数(比如1.79MHz÷60≈29833周期/帧),在
requestAnimationFrame回调中,根据当前帧与上一帧的时间差,计算需要执行的CPU周期总数,确保模拟进度严格匹配原始主机的速率,不受当前帧率影响。 - 固定时间步长分离逻辑与渲染:将游戏逻辑更新和画面渲染解耦。设置固定的时间步长(比如1/60秒),在
requestAnimationFrame中计算累计时间差,循环执行逻辑更新直到消耗完时间差,最后再进行渲染。这种方式能保证逻辑运行速度稳定,无论帧率如何波动都不会影响游戏节奏。 - 帧率限制(备选方案):如果暂时不想调整核心逻辑,可以用
performance.now()配合requestAnimationFrame控制回调间隔,确保每秒仅执行60次模拟循环。但这种方式精度不如前两种,因为浏览器定时器存在一定误差。
内容的提问来源于stack exchange,提问作者Caleb Prenger
相关产品推荐
相关产品推荐

