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

SDL2 C++中std::chrono计算deltaTime失效,玩家移动仍受帧率影响

问题根源分析

你的deltaTime计算逻辑存在核心问题:当前代码只统计了游戏逻辑+渲染的耗时,完全没把SDL_Delay的休眠时长算进去。因为你在循环开头就把prevTime更新为当前时间,后续的SDL_Delay会让帧的实际时长变长,但这部分延迟没被计入下一次的deltaTime,导致deltaTime的数值远小于真实的每帧时长,最终移动速度还是会随帧率波动。

修复方案

把prevTime的更新操作移到整个帧的末尾(包括SDL_Delay执行完成后),这样deltaTime就能完整覆盖一帧的所有耗时(逻辑处理+渲染+休眠)。同时建议统一时间计算方式,避免混用std::chrono和SDL原生API,减少逻辑混乱。

修改后的游戏循环代码(基于std::chrono实现)

SDL_Event event;
int frameCount = 0;
auto startTime = std::chrono::high_resolution_clock::now();
long frameStart, frameTime;

auto prevTime = std::chrono::high_resolution_clock::now();

while (!quit){
    frameStart = SDL_GetTicks();

    // 事件处理
    while (SDL_PollEvent(&event)){
        if (event.type == SDL_QUIT)
            quit = true;
        UpdateInput(event);
    }

    // 计算当前帧的deltaTime(单位:秒)
    auto currentTime = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> deltaTime2 = currentTime - prevTime;
    deltaTime = deltaTime2.count();

    // 执行游戏逻辑(包含玩家移动)
    UpdateGameObjects();

    // FPS限制
    if (capFPS){
        frameTime = SDL_GetTicks() - frameStart;
        const int frameTarget = 1000 / maxFPS;
        if (frameTarget > frameTime) {
            SDL_Delay(frameTarget - frameTime);
        }
    }

    // 关键:帧结束后更新prevTime,确保下一次deltaTime包含休眠时间
    prevTime = std::chrono::high_resolution_clock::now();

    // FPS统计
    frameCount++;
    auto elapsedSeconds = std::chrono::duration<double>(std::chrono::high_resolution_clock::now() - startTime).count();
    if (elapsedSeconds >= 1.0) {
        int currentFPS = frameCount;
        text->SetText(std::to_string(currentFPS).c_str());
        frameCount = 0;
        startTime = std::chrono::high_resolution_clock::now();
    }
}

额外优化建议

  1. 统一时间API:如果觉得std::chrono过于繁琐,也可以全程用SDL_GetTicks()实现,逻辑更简洁:
    // 替换deltaTime计算部分
    long currentTime = SDL_GetTicks();
    double deltaTime = (currentTime - prevTime) / 1000.0;
    // 帧末尾更新prevTime
    prevTime = SDL_GetTicks();
    
  2. 修复整数除法误差:1000 / maxFPS是整数除法,比如maxFPS=60时会得到16,但实际目标帧时长是16.666ms。可以改成static_cast<int>(1000.0 / maxFPS)来获得更精确的目标值。
  3. 调整速度数值:你当前的移动速度555 * deltaTime代表每秒移动555像素,这个数值可能过大,测试时可以先改成100左右,再根据实际体验调整。

内容的提问来源于stack exchange,提问作者Nagisa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 01:09:50