2009-11-16 82 views
1

我有一个游戏引擎可以作为课程的一部分工作。目前,其渲染速度取决于帧速率,并且一个要求是转向基于计时器的依赖项。我不知道如何确定它依赖于帧速率。我不知道该找什么。我意识到我将需要以某种方式合并一个计时器(GetTickCount?)来完成此任务,但我不确定更新频率有多频繁。使程序基于定时器而不是帧速率相关?

我不想交代码,只是一些有用的指导方针吗?

+0

那么,你受限于你的帧率,不是吗?例如,如果帧速率滞后,则不能连续更新输入。 – 2009-11-16 18:35:30

+0

这是一个合乎逻辑的假设。然而,就目前而言,它非常停顿,随着计算机的速度波动。我假设我被要求保持这种稳定的基于计时器的状态,而不是只是随机更新和渲染?我真的不完全理解,因此这个问题:) – Mark 2009-11-16 18:37:47

回答

1

我以前fix your timestep一些成功

然后问题就变成了保留任何滞后的轨道......和拖慢的事情,如果计算机无法跟上。

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“工作”就足够了......这种类型的东西。如果硬件速度很快,它可以按照预期工作,而硬件速度较慢(不能满足时间要求的硬件),它的速度将会尽可能快。当然,这是一个简单的单进程示例。

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以获得更高的精度,但它可能在多个内核方面存在问题。

+0

该方案的问题是,您正在设置基于前一帧的速度下一帧的时间。通常这会引起一个令人讨厌的口吃效果,因为驱动程序缓冲了多个数据帧。如果你打算这样做,最好是平均数帧。这将消除很多这些口吃问题。 – Goz 2009-11-17 09:06:01

+0

@Goz:你说的是某种浮动平均0.50 *上涨+0.30 *之前+ 0.20前beforeBeforeLast?即给予近期更多的权重以更快适应变化。 – 2009-11-17 13:04:56

+0

你可以加权。就我个人而言,我发现即使在帧速率非常低(15fps)的情况下,平均最后3帧速率也会给您带来足够好的效果,从而不会显眼:) – Goz 2009-11-17 14:55:16

0

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