为什么这个经过时间(帧时间)计算会锁定我的游戏

Why does this elapsed time (frametime) calculation lockup my game

目前我正在尝试实现一个固定步骤的游戏循环,但我的代码似乎以某种方式锁定了我的游戏。


Uint32 SDL_GetTicks(void) : Returns 一个无符号的 32 位值,表示自 SDL 库初始化以来的毫秒数。

这个有效:

1.cc)

Uint32 FPS = 60;
Uint32 MS_PER_SEC = 1000 / FPS;
Uint32 current_time, last_time, elapsed_time;
current_time = last_time = elapsed_time = 0;

while(Platform.Poll())
{
    current_time = SDL_GetTicks(); // Get time of frame begin

    // Clear Window
    Renderer.Clear();

    // Update Input
    //...

    // Draw
    Renderer.Draw();

    // Update Window
    Renderer.Update();

    last_time = SDL_GetTicks(); // Get time of frame end
    elapsed_time = last_time - current_time; // calculate frametime

    SDL_Delay(MS_PER_SEC - elapsed_time);
}

然而这不是:

2.cc)

Uint32 FPS = 60;
Uint32 MS_PER_SEC = 1000 / FPS;
Uint32 current_time, last_time, elapsed_time;
current_time = elapsed_time = 0;

last_time = SDL_GetTicks();

// Poll for Input
while(Platform.Poll())
{
    current_time = SDL_GetTicks();
    elapsed_time = current_time - last_time;

    // Clear Window
    Renderer.Clear();

    // Update Input
    //...

    // Draw
    Renderer.Draw();

    // Update Window
    Renderer.Update();

    last_time = current_time;
    SDL_Delay(MS_PER_SEC - elapsed_time);
}

我希望 1.cc 和 2.cc 的结果相同,这意味着 SDL_Delay(MS_PER_SEC - elapsed_time) 确实延迟了固定时间减去帧时间(此处为 16 - 帧时间)。 但是 2.cc 确实锁定了我的游戏。

从 2.cc 计算的 elapsed_time(帧时间)不是等同于 1.cc 吗?

该函数基于 RTC,精度非常低,并且使用时间长,具体取决于平台。 10-30 毫秒的准确度是一个乐观的猜测。

这可能是相关的:SDL_GetTicks() accuracy below the millisecond level

让我们稍微展开循环...

// First iteration

last_time = SDL_GetTicks();
current_time = SDL_GetTicks();
elapsed_time = current_time - last_time; // Probably zero

...

SDL_Delay(MS_PER_SEC - elapsed_time);    // Probably a whole second

// Second iteration

current_time = SDL_GetTicks();
elapsed_time = current_time - last_time; // Probably slightly more than a whole second

...

SDL_Delay(MS_PER_SEC - elapsed_time);    // Probably negative (4 billion milliseconds)