使程序基于计时器而不是帧速率依赖?

时间:2009-11-16 18:28:31

标签: c++ directx

我有一个游戏引擎可以作为课程的一部分。目前,它的渲染依赖于帧速率,一个要求是转向基于计时器的依赖。我不知道如何确定它依赖于帧速率的位置。我不知道该找什么。我意识到我需要以某种方式合并一个计时器(GetTickCount?)来实现这一目标,但我不确定更新频率的频率。

我不打算交代码,可能只是一些有用的指导方针?

4 个答案:

答案 0 :(得分:5)

想象一下,你有一个非常简单的游戏,它只是一个球在屏幕上移动。如果没有基于时间的更新,它会随着您的更新而移动。

你想要做的是找出已经过了多少时间(在一小部分。我通常以秒为单位测量,因此物理方程式匹配得更好。)更新时,而不是像这样:

ballPosition += ballVelocity

你有这个:

ballPosition += ballVelocity * timeElapsed

这意味着对于更高的帧速率,timeElapsed会更低,从而减少球的移动。较低的帧速率意味着timeElapsed将更大,并且球将逐帧移动。

最后,球将移动相同的距离,与帧速率无关。 60 FPS更新率使timeElapsed等于0.01666667f,而30 FPS更新率将使其成为0.03333333f。您可以看到在60 FPS时,经过的时间是30 FPS的一半,但因为它的速度是它的两倍,所以它的数量是相同的。

我通常将timeElapsed作为参数传递给任何与时间相关的函数。这样做的一个很好的结果是你可以通过将经过的时间乘以一个值来减慢或加速你的游戏。您也可以将其应用于单个组件。如果你切换到帧限制模型,它也会很好用,因为你实际上只是强迫timeElapsed成为常量。伪代码:

while (gameRunning)
{
    const float timeElapsed =
                    timer.elapsed(); // elapsed returns the number of seconds
                                     // passed since it was last called

    // GlobalTimeScale is 1 for normal time
    game.update(timeElapsed * GlobalTimeScale);
    game.draw();
}

要获得时间,GetTickCount应该有效。您可能还需要查看QueryPerformanceCounter以获得更高的精度,但它可能会出现多核问题。

答案 1 :(得分:1)

我使用fix your timestep取得了一些成功

然后问题就是跟踪任何滞后......如果计算机无法跟上,那就会减慢速度。

答案 2 :(得分:0)

可能的伪代码游戏循环:

constant TIMETHRESHOLD xxxx // nanoseconds to pass between executions of game loop

while true loop
    if getTime() - previousTime > TIMETHRESHOLD
        previousTime = getTime();
        // Execute game logic here
    end if
end loop

问题在于,您可以为游戏逻辑的不同部分使用不同的TIMETHRESHOLD。例如,您可能希望帧速率为60fps,但如果物理引擎以30fps“工作”就足够......这种事情。使用快速硬件,它将按预期工作,并且使用较慢的硬件(不能满足时间要求的硬件),它将尽可能快地工作。当然,这是一个简单的单过程示例。

答案 3 :(得分:0)

如果您不确定帧速率的使用位置,那么它几乎肯定会隐含在主循环中。如果在主循环中调用渲染函数,并且渲染需要很长时间,那么主循环的“循环速率”与帧速率相同,对吧?单线程执行意味着在循环中处理的所有内容都会影响您的帧速率。