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

时间:2008-09-16 14:45:20

标签: c++ opengl graphics directx sdl

我想用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).

所以,这种解释了游戏的运作方式。你应该真的玩一下 明白我的问题是什么。

我认为解决这个问题的一个好方法是使用链表来存储每个州, 它可能是基于时间的哈希映射,也可能是迭代的链表 基于时间。我还是不确定。

实际问题:

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

编辑(澄清更多):
操作系统 - Windows(因为这是一个爱好项目,可能会在以后的Linux中执行此操作)
图形 - 2D 语言 - C ++(必须是C ++ - 这是下学期课程的练习)

Q-Unanswered:SDL:OpenGL:Direct X
Q-Answered:避免并行处理
Q-Answered:使用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 ++特定知识有助于使我的项目更容易? (即向量?)

7 个答案:

答案 0 :(得分:6)

你应该做的是首先阅读并理解“固定时间步”游戏循环(这是一个很好的解释:http://www.gaffer.org/game-physics/fix-your-timestep)。

然后你要做的是保留一组帧计数器和动作对列表。 STL示例:

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

或者可能是对列表的向量。要创建状态,对于每个操作(玩家互动),您存储帧编号和执行的操作,如果操作只是“按键&lt; X&gt;按下”或“键&lt; X&gt;,则很可能获得最佳结果;发布了“:

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。

答案 1 :(得分:5)

这听起来与Braid非常相似。你真的不希望并行处理 - 并行编程很难,对于这样的事情,性能应该不是问题。

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

要运行游戏,您将遍历所有活动时间轴,并以锁步方式执行每个帧中的每个帧的操作。无需并行处理。

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

在简要介绍一下描述之后,我认为你有正确的想法,我会有一个状态对象来保存状态数据,并把它放到一个链表中......我认为你不需要并行线程。 ..

就图形API而言,我只使用了opengl,并且可以说它非常强大且具有良好的C / C ++ API,opengl也可以更加跨平台,因为你可以使用* Nix上的messa库电脑。

答案 4 :(得分:0)

一个非常有趣的游戏理念。我认为你认为parrellel计算对这个设计是有益的是正确的,但不会超过任何其他高资源计划。

问题有点模糊。我看到你要用C ++编写这个,但你编写的操作系统是什么?您是否打算跨平台以及您想要什么样的图形,即3D,2D,高端,基于Web。

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

答案 5 :(得分:0)

并行处理不是答案。你应该简单地“记录”玩家的动作,然后回放“之前的动作”

因此,您创建了一个包含动作的向量的矢量(单链表)。只需存储操作所采用的帧编号(或增量),并在该特定实例中代表玩家的“虚拟机器人”上完成该操作。你只需循环遍历状态并一个接一个地触发它们。

当状态悖论发生时,你只会因为下一个动作失败而轻易“打破”游戏的副作用。

答案 6 :(得分:0)

除非你迫切希望将C ++用于自己的教育,否则你一定要看XNA你的游戏&amp;图形框架(它使用C#)。它是完全免费的,它为你做了很多事情,很快你就可以在Xbox Live上出售你的游戏了。

要回答您的主要问题,您在Flash中已经做过的任何事情都不需要使用多个线程。只需在阵列中存储一个位置列表,并为每个机器人循环使用不同的偏移量。