2

我正在从一本关于游戏编程的书中学习 DirectX,它使用以下方法进行游戏循环:

long int start = GetTickCount();
while(true)
    GameRun();

void GameRun()
{
     if(GetTickCount() - start >= 30)
         //do stuff
}

无论时间是什么,这都是start相等的(我猜 get tick count 给出了自程序启动以来的“ticks”数量),然后,30 个滴答后,所有的 AI、渲染等都完成了。

我的问题是,先做所有的 AI 等不是更有效率,然后,如果还有时间,等到框架需要改变?

那么,保持稳定帧速率的更好方法是什么?(最好只使用我已经用于声音、图像和输入的 DirectX 标头(例如 d3d9.h))

并且,在相关说明中,GetTickCount() 究竟做了什么,“tick”有多长

4

2 回答 2

6

对于您的游戏循环,请阅读这篇文章。它总结了您的选择并使您的选择更加清晰。

现在对于 GetTickCount(),这是在 Windows 中获取时间的最简单方法(我不知道用于 unix 操作系统的方法)。QueryPerformanceFrequency 和 QueryPerformanceCounter 提供了更高的精度,但可能很难理解如何正确使用它们。

您可能有兴趣阅读Ogre::Timer 类的工作方式(Ogre 是一个著名的开源实时 3D 渲染库)。他们添加了一些代码来处理这些功能的一些潜在问题,并且有多个平台的代码。

您可以获取代码并在您的应用程序中使用它,. 即将到来的 Ogre 版本的许可证是 MIT

这样你就可以专注于你的游戏循环和游戏代码。


更新时间精度:现在,如果您可以使用最后一个 boost 版本,则boost.chrono提供了一个高精度时钟,steady_clock,它是跨平台的,并在 windows 上使用 QueryPerformanceFrequency 和 QueryPerformanceCounter。事实上,chrono 是对 C++ 标准库的补充。

于 2009-10-17T23:33:20.863 回答
2

您提供的示例代码是实现游戏循环的最糟糕的方法。正如您所注意到的,等到刷新时间是一种巨大的浪费。

只需选择一个任意时间步(例如,一秒)并相对于该时间步表达您的所有度量。

这看起来像:

while ( !done )
{
    float alphaTime = timeConstant / (currentTime - lastLoopTime);
    dispatchEvents();
    gameLogic( alphaTime );
}

void gameLogic( float alphaTime )
{
    movePlayer( playerSpeed * alphaTime );
}

这样你就不会浪费时间等待帧率,你可以让你的 AI 脚本运行,......一切都将以相同的速度移动,因为移动乘以时间因子。

于 2009-10-17T23:07:26.297 回答