0

我将 SDL 1.2 和 VS2008 用于较小的类似游戏的应用程序。我最近(在从 SO 上的其他帖子中获得了一些我现在找不到的想法之后,如果您觉得我应该将您的问题链接起来以供参考,非常抱歉)重新编写了我的游戏循环以不使用 Sleep 或 SDL_Delay 进行计时。相反,我以已知频率调用我的游戏逻辑,并根据实际时间步长计算距离和位置。

执行此操作时,我预计 FPS 会被 SDL_Flip 限制为屏幕的帧速率(vsynch?),但我最终在运行 Windows 7 的机器上获得了大约 300 FPS。这可能是什么原因?您可以在监视器 vsynch 之间多次运行整个游戏循环(包括 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);
        }
4

1 回答 1

1

SDL_Flip 只是将表面上的内容推送到屏幕上。跟fps没关系。不,你不应该在同一个循环中多次使用 SDL_Flip,你应该在更新你的表面并准备好在屏幕上显示它之后再做。

我认为管理 fps SDL_Delay(简单地称为睡眠)是你最好的选择。

于 2014-05-03T11:17:51.840 回答