异步屏幕更新为游戏玩法逻辑,C ++
我正在使用Visual C ++ 2008 Express和Ogre3D sdk编写游戏。
我的核心游戏逻辑被设计为以每秒100次的速度运行。 为了简单起见,我会说这是一种名为'gamelogic()'的方法。 这不是基于时间的,这意味着如果我想将游戏时间提前1秒,我必须将“gamelogic()”调用100次。 'gamelogic()'与游戏的屏幕渲染相比是轻量级的。
Ogre有一个“监听器”逻辑,当它要绘制一个框架并完成绘制一个框架时通知你的代码。 如果我在帧渲染之前调用“gamelogic()”,那么游戏将受到屏幕渲染速度的很大影响,屏幕渲染速度可能从5fps到120fps不等。
想到的简单解决方案是:计算自上次呈现帧后流逝的时间,并在下一帧之前多次调用“gamelogic()”:100 * timeElapsedInSeconds
然而,我认为“正确”的方式是使用多线程; 有一个单独的线程运行'gamelogic()'100次/秒。
问题是,我该如何做到这一点,以及在两个独立的线程之间发生冲突时可以做些什么:在Ogre同时呈现屏幕时,gamelogic正在改变屏幕内容(3D对象坐标)。
提前谢谢了。
如果这是您的第一款游戏应用程序,那么使用多线程来实现您的结果可能比您在第一场游戏中真正应对更多的工作。 在不同线程中同步游戏循环和渲染循环并不是一个容易解决的问题。
正如您正确指出的那样,渲染时间会大大影响游戏的“速度”。 我建议你不要让你的游戏逻辑依赖于设定的时间片(即1/100秒)。 使其依赖于当前的帧时间(好吧,最后一帧时间,因为你不知道你的当前帧需要多长时间来渲染)。
通常我会写下面的东西(我写的东西大大简化了):
float Frametime = 1.0f / 30.0f;
while(1) {
game_loop(Frametime); // maniuplate objects, etc.
render_loop(); // render the frame
calculate_new_frametime();
}
其中Frametime是当前帧采用的calculcated frametime。 当你处理你的游戏循环时,你正在使用前一帧的帧时间(因此将初始值设置为合理的值,如1/30或1/15秒)。 在以前的frametime上运行它足以让您获得所需的结果。 使用该时间框架运行你的游戏循环,然后渲染你的东西。 您可能必须更改游戏循环中的逻辑,以避免假定固定的时间间隔,但通常这些修复很容易。
异步游戏/渲染循环可能是你最终需要的东西,但这是一个难以解决的难题。 它涉及到拍摄对象及其相关数据的快照,将这些快照放入缓冲区,然后将缓冲区传递给渲染引擎。 该内存缓冲区必须在关键部分正确分区,以避免在渲染循环正在读取时将游戏循环写入它。 在传递到渲染循环之前,您必须小心确保将所有相关数据复制到缓冲区中。 此外,您必须编写逻辑来停止游戏或渲染循环,同时等待其中一个或另一个完成。
这种复杂性就是为什么我建议先写一个更连续的方式(除非你有经验,你可能会这么做)。 原因在于,首先使用“简单”方法将迫使您了解代码的工作方式,渲染引擎的工作方式,渲染引擎需要的数据类型等。多线程知识在复杂游戏开发中非常明确这些天,但知道如何做得好,需要深入了解游戏系统如何相互作用。
核心游戏逻辑的运行速度并不比玩家能够做出的反应快得多。 关于唯一一次真正有用的是物理模拟,在快速,固定的时间步长运行可以使模拟的行为更加一致。
除此之外,每帧更新一次游戏循环,并传递可变时间增量,而不是依赖于固定时间增量。 您从多线程中获得的好处与成本相比是微不足道的,特别是如果这是您的第一场比赛。
双缓冲你的渲染物体是一种你可以探索的方法。 意思是,渲染组件正在使用1个缓冲区,当所有游戏动作已经更新了第二缓冲区中的相关对象时,该缓冲区将被更新。
但我个人不喜欢它,我会(并经常)采用Mark的方法。
链接地址: http://www.djcxy.com/p/95553.html上一篇: Asynchronous screen update to gameplay logic, C++
下一篇: How to revolve an object around another object (C++ and Ogre3D)?