我使用SDL 1.2和VS2008来制作类似游戏的小应用程序。我最近(从其他帖子中得到一些我现在找不到的帖子的想法,如果你认为我应该将你的问题链接起来以供参考),重新编写我的游戏循环以不使用Sleep或SDL_Delay进行计时。相反,我用已知频率调用我的游戏逻辑,并根据实际时间步长计算距离和位置。
当我这样做时,我期待FPS被SDL_Flip限制到屏幕的帧速率(vsynch?),但我最终在我的机器上运行大约300 FPS,运行Windows 7.这可能是导致这种情况的原因。 ?你可以在监视器vsynchs之间多次运行整个游戏循环(包括SDL_Flip)吗?在不同的机器上行为可能是不同的,或者SDL_Flip永远不应该同步到vsynch?我没有看到任何闪烁或其他不期待的屏幕更新效果。
这是我的游戏循环供参考:
void GraphicsFramework::run()
{
Uint32 last_input_check = 0;
Uint32 last_logics_check = 0;
while(true)
{
Uint32 now = SDL_GetTicks();
if(now - last_input_check > 10) // Every 10 millisecond
{
if(!processEvents())
{
return;
}
last_input_check = now;
}
if(now - last_logics_check > 20) // Every 20 milliseconds
{
handleGameLogics();
last_logics_check = now;
}
draw(); // No FPS limitation
m_Window.flipSurface(); // Calls SDL_Flip(surface)
m_ActualFrameTime = SDL_GetTicks() - now;
}
}
修改 固定等待繁忙的FPS看起来像这样。取代
m_ActualFrameTime = SDL_GetTicks() - now;
与
do
{
m_ActualFrameTime = SDL_GetTicks() - now;
} while ((Uint32)(1000/m_ActualFrameTime) > getDesiredFPS());
这比使用SDL_Delay或Sleep提供了更稳定的结果,至少在我的机器上,你可以得到一些可变的FPS。当然,两者都会破坏示例中processEvents()的时间。
还为完整性添加了SDL_Delay变体:
Sint32 timeToSleep = (Uint32)(1000/getDesiredFPS()) - m_ActualFrameTime;
if(timeToSleep > 0)
{
SDL_Delay((Uint32)timeToSleep);
}
答案 0 :(得分:1)
SDL_Flip只是将表面上的内容推送到屏幕上。它与fps无关。并且你不应该在同一个循环中多次使用SDL_Flip,你应该在更新曲面后准备好在屏幕上显示它。
管理fps SDL_Delay(简称为睡眠)是我认为最好的选择。