Phaser3中不设置forceSetTimeOut=True如何限制帧率?
在Phaser3中实现基于requestAnimationFrame的帧率限制
你完全可以在Phaser3中实现类似自定义requestAnimationFrame+时间差的帧率控制方案,核心思路是禁用Phaser的自动游戏循环,手动调用game.step()来驱动游戏更新,具体实现如下:
1. 初始化游戏时禁用自动循环
创建Phaser游戏实例时,在配置中设置autoStep: false,关闭Phaser内置的自动循环机制:
const config = { type: Phaser.AUTO, width: 800, height: 600, autoStep: false, // 关键配置:禁用自动循环 scene: { preload: preload, create: create, update: update } }; const game = new Phaser.Game(config);
2. 实现自定义帧率控制循环
参考你提供的代码逻辑,用requestAnimationFrame构建循环,计算时间差后手动触发Phaser的游戏更新:
const targetFps = 30; const fpsInterval = 1000 / targetFps; let lastTimestamp = performance.now(); let gameRunning = true; // 用于控制游戏运行状态 function customGameLoop(timestamp) { // 持续请求浏览器下一帧 requestAnimationFrame(customGameLoop); // 游戏暂停时跳过更新逻辑 if (!gameRunning) return; const elapsed = timestamp - lastTimestamp; // 达到目标帧率间隔时执行游戏更新 if (elapsed >= fpsInterval) { // 修正时间戳,避免累积误差 lastTimestamp = timestamp - (elapsed % fpsInterval); // 调用Phaser核心更新方法,传入秒级时间差 game.step(elapsed / 1000); } } function create() { // 你的场景初始化逻辑(比如创建精灵、设置交互等) // 启动自定义帧率控制循环 requestAnimationFrame(customGameLoop); }
关键细节说明
game.step(delta)是Phaser的核心驱动方法,负责处理所有游戏逻辑更新(包括场景update回调、物理模拟、渲染等),参数delta需要传入秒级的时间差,因此要把毫秒数转成秒。- 这种方案完全基于
requestAnimationFrame,和你自己写的逻辑一致,比forceSetTimeout: true更高效稳定——requestAnimationFrame会同步浏览器的刷新节奏,避免setTimeout的精度波动问题。 - 若需要暂停/恢复游戏,只需修改
gameRunning变量即可,和你原代码的控制逻辑对齐。
内容的提问来源于stack exchange,提问作者月牙天冲
相关产品推荐
相关产品推荐

