【问题标题】:Setting fixed FPS doesn't work设置固定 FPS 不起作用
【发布时间】:2013-09-18 00:30:51
【问题描述】:

我正在为一个学校项目制作 2D 游戏。我老师给的模板效果很好,但是我想替换代码中一个非常非常愚蠢的东西。在代码中,他调用了 20 次重方法来减慢游戏速度。而不是这样做,我想检查是否应该处理下一帧。

游戏是模板命名空间内的一个对象。这个命名空间有一个无限循环,它调用游戏滴答方法并交换帧缓冲区。

在这个模板中,我用一个简单的 if 语句替换了 Game->Tick()

if (game->Ready(lastftime)) {
    game->Tick();
}

lastframe 是上次调用与现在之间的时间差(以秒为单位)。 我知道我可以利用这段时间来计算游戏中的动作,但这不是我现在想做的!

这是Ready 方法:

bool Game::Ready(float timedif) {
    // Add time to framecounter
    framecounter += timedif;

    // Check if the counter over lapses the fps
    if (framecounter > fps) {
        // If so, substract the fps from the counter
        while (framecounter > fps) {
            framecounter -= fps;
        }
        m_Screen->Clear(0);
        Draw();

        return true;
    }

    // Frame is still inside the fps margin
    return false;
}

fps 计算如下:fps = 1000.0f/60

我不知道为什么它不能以每秒 60 帧的速度运行,而且我 100% 肯定它的调用次数超过了这个速度(printf 进行了测试)。任何帮助将不胜感激。

【问题讨论】:

  • 你传递给Readylastftime是什么?名称暗示了一个时间点,但在 Ready 中,您将其视为差异
  • 如果difference 是以秒为单位的时间,您将很难计算出高于 1fps 的帧...
  • 还有fps变量表示帧之间的毫秒数,而不是每秒帧数
  • @nyarlathotep 非常正确。这已经在模板中,但我可以更改名称。
  • @Paddyd 没错,我首先尝试了另一种方式,它只是一个整数,现在使用相同的变量。

标签: c++ frame-rate


【解决方案1】:

什么是timedif?
你应该有一些关于“实时”时间的信息 - 例如 ms 是最后一帧
在我看来,您假设您的 while 循环的每次迭代都需要一毫秒。

bool Game::Ready(float msSinceLastFrame)
{
    if(msSinceLastFrame > fps)
    {
        m_Screen->Clear();
        Draw();
        return true;
    }       
    return false
}

//call this using some kind of while where you update msSinceLastFrame  
if(game->Ready(msSinceLastFrame)
{
    msSinceLastFrame = 0;
    game->Tick();
}

但是,如果您要使用这种方法,则需要使用 while(); 调用 game::ready 循环

我会建议其他方法。

void Game::gameLoop()
{
    auto lastFrameTimeStamp = GetTickCount(); // if you are on windows
    auto frameLength = 1000/fps;
    while(true) //true or some kind of condition
    {
        auto currentTimeStamp = GetTickCount();
        if( currentTimeStamp - lastFrameTimeStamp >= frameLength)
        {
            //do your job;
            lastFrameTimeStamp = currentTimeStamp;
        }
        Sleep(1); // you can use sleep here if you dont want to heat ur pcu =)
    }
}

【讨论】:

  • 感谢您的回答。通过使用您的最后一个示例,它的运行速度与我已经拥有的完全相同。如果 fps 设置得更高,它也会运行得更快,这是不应该的。或者我的大脑现在无法正常思考。
  • 对于 FPS,如果您想要更精确,可以转到 timeGetTime 和 timeBeginPeriod(1) randomascii.wordpress.com/2013/05/09/…
【解决方案2】:

为什么要从framecounter 中减去fps?超过fps时需要重置framecounter

尝试以下方法:

bool Game::Ready(float timedif) {
    // Add time to framecounter
    framecounter += timedif;

    // Check if the counter over lapses the fps
    if (framecounter > fps) {
        framecounter = 0;
        m_Screen->Clear(0);
        Draw();

        return true;
    }

    // Frame is still inside the fps margin
    return false;
}

【讨论】:

  • 我减去它是因为如果一帧几乎花费了两帧的时间,那么 if 将在下次再次调用它时执行,而不是等到它再次达到 fps。
猜你喜欢
  • 2016-06-04
  • 2016-06-07
  • 2018-11-26
  • 2015-11-16
  • 2014-11-02
  • 2018-03-04
  • 2013-12-31
相关资源
最近更新 更多