游戏循环deltaTime与指定targetFrameRate不匹配问题求助
问题解决:targetFrameRate生效但deltaTime未匹配目标帧率
问题描述
将targetFrameRate设置为30(对应0.03333秒),但deltaTime始终显示为0.01667秒(60fps),尽管targetFrameRate确实生效(已添加延迟)。这导致当指定帧率不等于60时,基于velocity * deltaTime的移动代码无法正常工作,核心问题是deltaTime始终保持60fps的数值,不受targetFrameRate影响。
问题原因
当前代码中,Time.deltaTime是基于requestAnimationFrame的真实帧间隔计算的(通常是60fps对应的0.01667秒),而Update函数虽然按目标帧率(30fps)的间隔执行,但并未将deltaTime替换为目标帧率对应的固定时间步长,导致Update里输出的deltaTime还是真实的帧间隔值。
修复方案
在执行Update函数时,将Time.deltaTime设置为目标帧率对应的固定时间步长(1 / targetFrameRate),这样移动逻辑就能基于设定的帧率时间步长计算,不受真实渲染帧率的影响。
修改后的完整代码:
// Initializes the game loop window.onload = () => { PlayerLoop.init(); }; // Gets called every frame function Update () { console.log(Time.deltaTime); } // The specified fps const targetFrameRate = 30; // 预计算目标时间步长 const fixedTimeStep = 1 / targetFrameRate; // Class that holds time class Time { static unscaledTime = 0; static unscaledDeltaTime = 0; static timeScale = 1; static frameCount = 0; static time = 0; static deltaTime = 0; static maximumDeltaTime = 0.3333333; } // Game loop class class PlayerLoop { static #accumulator = 0; static #requestUpdate () { requestAnimationFrame(this.#update.bind(this)); } static #update () { Time.unscaledDeltaTime = (performance.now() / 1000) - Time.unscaledTime; Time.unscaledTime += Time.unscaledDeltaTime; var deltaT = Time.unscaledDeltaTime; if (deltaT > Time.maximumDeltaTime) deltaT = Time.maximumDeltaTime; // 基于真实时间更新累加器 this.#accumulator += deltaT * Time.timeScale; while (this.#accumulator >= fixedTimeStep) { Time.frameCount++; // 设置为目标帧率对应的固定时间步长 Time.deltaTime = fixedTimeStep * Time.timeScale; Time.time += Time.deltaTime; Update(); this.#accumulator -= fixedTimeStep; } // Render this.#requestUpdate(); } static init () { this.#requestUpdate(); } }
关键修改点
- 预计算
fixedTimeStep = 1 / targetFrameRate,避免重复计算开销 - 将
Time.deltaTime的赋值移到while循环内部,每次执行Update时固定为目标时间步长 - 调整累加器逻辑:基于真实时间累加,按固定步长消耗,保证逻辑更新的稳定性
修改后,Update函数中输出的deltaTime会是目标帧率对应的0.03333秒,移动逻辑能正常适配设定帧率,同时游戏循环也能应对真实渲染帧率的波动。
内容的提问来源于stack exchange,提问作者CalmBubbles
相关产品推荐
相关产品推荐

