代码之家  ›  专栏  ›  技术社区  ›  apandit

用并行处理制作C++游戏

  •  2
  • apandit  · 技术社区  · 16 年前

    我想“模仿”一个流行的Flash游戏,CalthCon,在C++中,需要一些帮助开始。(注:不释放,只为自己练习)

    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)。我该如何实现并行状态呢?有平行螺纹吗?

    编辑(澄清更多内容):
    OS—Windows(因为这是一个业余项目,以后在Linux中可能会这样做)
    图形-2D 语言——C++(必须是C++——这是下学期课程的练习)

    Q-未应答: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 回复  |  直到 9 年前
        1
  •  6
  •   Mr Lister hawi    9 年前

    您应该首先阅读并理解“固定时间步”游戏循环(以下是一个很好的解释: 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。

        2
  •  5
  •   Adam Rosenfield    16 年前

    这听起来很像 Braid . 你真的不想为这个并行处理-并行编程是 坚硬的 对于这样的事情,性能不应该是一个问题。

    由于游戏状态向量的增长速度非常快(可能以每秒几千字节的速度增长,这取决于帧速率和存储的数据量),因此您不需要链表,因为链表在空间方面开销很大(如果布局不好,可能会因缓存未命中而带来很大的性能损失)。对于每个平行时间线,您需要一个向量数据结构。可以将每个平行时间线存储在链接列表中。每个时间线都知道它何时开始。

    要运行游戏,您需要迭代所有活动的时间线,并在lockstep中从每个时间线执行一帧的操作。不需要并行处理。

        3
  •  1
  •   Jason Z    16 年前

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

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

        4
  •  0
  •   mmattax    16 年前

    在对描述进行简单的说明之后,我认为您的想法是正确的,我将有一个保存状态数据的状态对象,并将其放入一个链接列表中…我认为您不需要并行线程…

    至于图形API,我只使用OpenGL,并且可以说它是相当强大的,并且有很好的C/C++ API,OpenGL也会更跨平台,因为你可以在*NIX计算机上使用MISA库。

        5
  •  0
  •   Cunnyngham    16 年前

    一个非常有趣的游戏想法。我认为你是对的,Parrellel计算将有利于这一设计,但不比任何其他高资源程序。

    这个问题有点含糊不清。我看到你要用C++写这个,但是你为它编写了什么操作系统呢?您是否打算将其作为跨平台,以及您希望使用哪种图形,即3D、2D、高端、基于Web。

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

        6
  •  0
  •   enigmatic    16 年前

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

    因此,创建一个向量(单独链接的列表)来保存动作。只需存储执行操作的帧编号(或delta),并在表示该特定实例期间的播放机的“虚拟bot”上完成该操作。您只需循环遍历状态并逐个触发它们。

    当一个状态悖论仅仅因为下一个操作失败而发生时,你会得到一个容易“打破”游戏的副作用。

        7
  •  0
  •   Iain    16 年前

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

    要回答您的主要问题,您在flash中已经做的任何事情都不需要使用多个线程。只需在一个数组中存储一个位置列表,然后用不同的偏移量循环遍历每个机器人。