为什么这个经过时间(帧时间)计算会锁定我的游戏
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)
目前我正在尝试实现一个固定步骤的游戏循环,但我的代码似乎以某种方式锁定了我的游戏。
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)