使用并行处理在C ++中制作游戏

时间:2020-03-05 18:56:11  来源:igfitidea点击:

我想用C ++"模仿"一个流行的Flash游戏Chrontron,并且需要一些入门帮助。 (注意:不是为了释放自己,而是为自己练习)

Basics:
Player has a time machine. On each iteration of using the time machine, a parallel state
is created, co-existing with a previous state. One of the states must complete all the
objectives of the level before ending the stage. In addition, all the stages must be able
to end the stage normally, without causing a state paradox (wherein they should have
been able to finish the stage normally but, due to the interactions of another state,
were not).

因此,这种解释说明了游戏的运作方式。你应该稍微玩一下
了解我的问题是什么。

我认为解决此问题的好方法是使用链接列表存储每个状态,
它可能是基于时间的哈希图,也可能是迭代的链表
根据时间。我还不确定。

实际问题:

现在我有了一些粗略的规范,我需要一些帮助来决定为此使用哪种数据结构以及原因。另外,我想知道应该使用什么图形API /层来执行此操作:SDL,OpenGL或者DirectX(我目前的选择是SDL)。我将如何实现并行状态?有平行螺纹吗?

编辑(澄清更多):
操作系统-Windows(由于这是一个业余项目,请稍后在Linux中进行)
图形-2D
语言-C ++(必须为C ++,这是下一学期的课程实践)

Q-未回答:SDL:OpenGL:Direct X
Q解答:避免并行处理
Q-解答:使用STL实施时间步操作。

So far from what people have said, I should:
1. Use STL to store actions.
2. Iterate through actions based on time-step.
3. Forget parallel processing -- period. (But I'd still like some pointers as to how it
could be used and in what cases it should be used, since this is for practice).

补充这个问题,我之前主要使用C#,PHP和Java,所以我不会形容自己是一个炙手可热的程序员。哪些C ++特定知识将有助于使我更轻松地完成这个项目? (即向量?)

解决方案

回答

我以前玩过这个游戏。我不一定认为并行处理是要走的路。我们在游戏中有共享的对象(杠杆,盒子,电梯等),可能需要在每个进程之间共享进程之间的共享对象,从而降低了并行性的有效性。

我个人只是保留动作列表,然后对于每个后续迭代开始将它们交织在一起。例如,如果列表的格式为<[iteration.action]>,则第3次到第3次将执行动作1.1、2.1、3.1、1.2、2.2、3.3等。

回答

在简要介绍了描述之后,我认为我们有一个正确的主意,我将拥有一个保存状态数据的状态对象,并将其放入链接列表中...我认为我们不需要并行线程...

就图形API而言,我只使用过opengl,并且可以说它非常强大并且具有良好的C / C ++ API,因为我们可以在* Nix计算机上使用messa库,因此opengl也会更跨平台。

回答

一个非常有趣的游戏想法。我认为并行计算对这种设计是有益的,但是没有其他任何高资源程序可以了,这是正确的。

这个问题有点模棱两可。我看到我们打算用C ++编写此代码,但是我们要为其编写什么操作系统呢?我们打算将其作为跨平台使用吗?我们想要哪种图形,即3D,2D,高端,基于Web的图形。

所以基本上我们需要更多信息。

回答

并行处理不是解决方案。我们应该简单地"记录"玩家的动作,然后针对"先前的动作"进行播放

因此,我们将创建一个包含动作的向量(单个链接列表)。只需存储执行动作的帧号(或者增量),然后在代表该特定实例的玩家的"虚拟机器人"上完成该动作即可。我们只需遍历状态并一个接一个地触发它们。

当状态悖论发生时,我们会轻易地"打破"游戏的副作用,这仅仅是因为下一个动作失败了。

回答

除非我们迫切希望使用C ++进行自己的学习,否则,绝对应该为游戏和图形框架使用XNA(它使用C#)。它是完全免费的,可以为我们做很多事情,很快我们就可以在Xbox Live上出售游戏。

要回答主要问题,我们在Flash中已经无法执行的任何操作都不需要使用多个线程。只需将位置列表存储在数组中,然后为每个机器人使用不同的偏移量循环即可。

回答

这听起来与辫子非常相似。我们确实不希望这种并行编程很难进行并行处理,对于这样的事情,性能应该不是问题。

由于游戏状态向量将非常快地增长(可能每秒几千字节左右,具体取决于帧速率和存储的数据量),因此我们不希望使用链表,因为链表的开销很大空间(如果布局不当,可能会由于高速缓存未命中而导致较大的性能损失)。对于每个并行时间轴,我们都需要一个矢量数据结构。我们可以将每个并行时间轴存储在链接列表中。每个时间轴都知道它的开始时间。

要运行游戏,我们要遍历所有活动的时间轴,并按步调从每个时间轴执行一帧的动作。无需并行处理。

回答

首先,我们应该阅读并理解"固定时间步长"游戏循环(以下是一个很好的解释:http://www.gaffer.org/game-physics/fix-your-timestep)。

然后,我们要做的是保留帧计数器和动作对列表的列表。 STL示例:

std::list<std::list<std::pair<unsigned long, Action> > > state;

或者也许是成对列表的向量。为了创建状态,对于每个动作(玩家交互),我们都存储帧号和执行的动作,如果仅是"按下<X>键"或者" <X>键",则很可能会获得最佳结果":

state.back().push_back(std::make_pair(currentFrame, VK_LEFT | KEY_PRESSED));

要播放以前的状态,我们必须在每次播放器激活时间机器时重置帧计数器,然后遍历每个先前状态的状态列表,并查看是否与当前帧匹配。如果存在,请对该状态执行操作。
为了进行优化,我们可以保留一个迭代器列表,以使其位于每个先前状态列表中的位置。这是一些伪代码:

typedef std::list<std::pair<unsigned long, Action> > StateList;
std::list<StateList::iterator> stateIteratorList;
//
foreach(it in stateIteratorList)
{
  if(it->first == currentFrame)
  {
    performAction(it->second);
    ++it;
  }
}

我希望你能明白...

单独的线程只会使事情复杂化,这样我们每次都会得到相同的结果,我们无法通过使用单独的线程(无法真正看到将如何实现)或者不固定的时间步游戏循环来保证。

对于图形API,我会选择SDL,因为它可能是最简单的入门方法。如果我们想进行3D操作,则以后总是可以使用SDL中的OpenGL。