我有一个游戏引擎可以作为课程的一部分。目前,它的渲染依赖于帧速率,一个要求是转向基于计时器的依赖。我不知道如何确定它依赖于帧速率的位置。我不知道该找什么。我意识到我需要以某种方式合并一个计时器(GetTickCount?)来实现这一目标,但我不确定更新频率的频率。
我不打算交代码,可能只是一些有用的指导方针?
答案 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)
如果您不确定帧速率的使用位置,那么它几乎肯定会隐含在主循环中。如果在主循环中调用渲染函数,并且渲染需要很长时间,那么主循环的“循环速率”与帧速率相同,对吧?单线程执行意味着在循环中处理的所有内容都会影响您的帧速率。