2

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

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

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

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% 确定它的调用次数不止于此(用 a 测试过printf)。任何帮助,将不胜感激。

4

2 回答 2

4

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

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 =)
    }
}
于 2013-09-13T10:55:55.650 回答
2

你为什么要减去fpsfrom framecounterframecounter超过时需要重新设置fps

尝试以下操作:

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;
}
于 2013-09-13T11:01:57.830 回答