You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

游戏循环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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 20:05:33