用 C++ 制作游戏 使用并行处理
我想用 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
问题解答:避免并行处理
问题解答:使用 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++ 特定知识可以帮助我更轻松地完成这个项目? (即向量?)
I wanted to "emulate" a popular flash game, Chrontron, in C++ and needed some help getting started. (NOTE: Not for release, just practicing for myself)
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).
So, that sort of explains how the game works. You should play it a bit to really
understand what my problem is.
I'm thinking a good way to solve this would be to use linked lists to store each state,
which will probably either be a hash map, based on time, or a linked list that iterates
based on time. I'm still unsure.
ACTUAL QUESTION:
Now that I have some rough specs, I need some help deciding on which data structures to use for this, and why. Also, I want to know what Graphics API/Layer I should use to do this: SDL, OpenGL, or DirectX (my current choice is SDL). And how would I go about implementing parallel states? With parallel threads?
EDIT (To clarify more):
OS -- Windows (since this is a hobby project, may do this in Linux later)
Graphics -- 2D
Language -- C++ (must be C++ -- this is practice for a course next semester)
Q-Unanswered: SDL : OpenGL : Direct X
Q-Answered: Avoid Parallel Processing
Q-Answered: Use STL to implement time-step actions.
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).
Appending to the question, I've mostly used C#, PHP, and Java before so I wouldn't describe myself as a hotshot programmer. What C++ specific knowledge would help make this project easier for me? (ie. Vectors?)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
除非您迫切希望使用 C++ 进行自己的教育,否则您绝对应该为您的游戏和应用程序查看 XNA。 图形框架(它使用 C#)。 它完全免费,可以为您做很多事情,很快您就可以在 Xbox Live 上销售您的游戏。
为了回答您的主要问题,您在 Flash 中已经可以做的任何事情都不需要使用多个线程。 只需将位置列表存储在数组中,并为每个机器人使用不同的偏移量进行循环。
Unless you're desperate to use C++ for your own education, you should definitely look at XNA for your game & graphics framework (it uses C#). It's completely free, it does a lot of things for you, and soon you'll be able to sell your game on Xbox Live.
To answer your main question, nothing that you can already do in Flash would ever need to use more than one thread. Just store a list of positions in an array and loop through with a different offset for each robot.
我以前玩过这个游戏。 我并不一定认为并行处理是正确的选择。 您在游戏中拥有共享对象(杠杆、盒子、电梯等),这些对象需要在进程之间(可能是每个增量)共享,从而降低并行性的有效性。
我个人只会保留一个操作列表,然后对于每个后续迭代开始将它们交错在一起。 例如,如果列表的格式为<[iteration.action]>,则列表的格式为: 那么第三次将执行动作 1.1、2.1、3.1、1.2、2.2、3.3 等。
I have played this game before. I don't necessarily think parallel processing is the way to go. You have shared objects in the game (levers, boxes, elevators, etc) that will need to be shared between processes, possibly with every delta, thereby reducing the effectiveness of the parallelism.
I would personally just keep a list of actions, then for each subsequent iteration start interleaving them together. For example, if the list is in the format of <[iteration.action]> then the 3rd time thru would execute actions 1.1, 2.1, 3.1, 1.2, 2.2, 3.3, etc.
在简要概述了描述之后,我认为您的想法是正确的,我将有一个保存状态数据的状态对象,并将其放入链接列表中...我认为您不需要并行线程...
作为就图形API而言,我只使用过opengl,可以说它非常强大并且具有良好的C / C++ API,opengl也将更加跨平台,因为您可以在*Nix计算机上使用messa库。
After briefly glossing over the description, I think you have the right idea, I would have a state object that holds the state data, and place this into a linked list...I don't think you need parallel threads...
as far as the graphics API, I have only used opengl, and can say that it is pretty powerful and has a good C / C++ API, opengl would also be more cross platform as you can use the messa library on *Nix computers.
一个非常有趣的游戏想法。 我认为你是对的,并行计算将有利于这种设计,但不会比任何其他高资源程序更有利。
这个问题有点模棱两可。 我看到您将用 C++ 编写此代码,但是您要为什么操作系统编写它? 您打算让它跨平台吗?您想要什么类型的图形,即 3D、2D、高端、基于网络。
所以基本上我们需要更多的信息。
A very interesting game idea. I think you are right that parrellel computing would be benefical to this design, but no more then any other high resource program.
The question is a bit ambigous. I see that you are going to write this in C++ but what OS are you coding it for? Do you intend on it being cross platform and what kind of graphics would you like, ie 3D, 2D, high end, web based.
So basically we need a lot more information.
并行处理不是答案。 您应该简单地“记录”玩家的动作,然后回放“之前的动作”,
因此您创建了一个包含动作的向量(单链表)。 只需存储所采取操作的帧编号(或增量),并在该特定实例期间代表玩家的“虚拟机器人”上完成该操作即可。 您只需循环遍历这些状态并依次触发它们即可。
当仅仅因为下一个动作失败而发生状态悖论时,您就会得到轻松“破坏”游戏的副作用。
Parallel processing isn't the answer. You should simply "record" the players actions then play them back for the "previous actions"
So you create a vector (singly linked list) of vectors that holds the actions. Simply store the frame number that the action was taken (or the delta) and complete that action on the "dummy bot" that represents the player during that particular instance. You simply loop through the states and trigger them one after another.
You get a side effect of easily "breaking" the game when a state paradox happens simply because the next action fails.
这听起来与 Braid 非常相似。 您确实不希望为此进行并行处理 - 并行编程很难,对于这样的事情,性能不应该成为问题。
由于游戏状态向量会增长得非常快(可能约为每秒几千字节,具体取决于帧速率和存储的数据量),因此您不需要链表,它在方面有很大的开销空间(如果布局不当,可能会因缓存未命中而导致巨大的性能损失)。 对于每个并行时间线,您需要一个矢量数据结构。 您可以将每个并行时间线存储在链接列表中。 每个时间线都知道它从什么时间开始。
要运行游戏,您需要遍历所有活动时间线,并同步执行每个时间线的一帧动作。 无需并行处理。
This sounds very similar to Braid. You really don't want parallel processing for this - parallel programming is hard, and for something like this, performance should not be an issue.
Since the game state vector will grow very quickly (probably on the order of several kilobytes per second, depending on the frame rate and how much data you store), you don't want a linked list, which has a lot of overhead in terms of space (and can introduce big performance penalties due to cache misses if it is laid out poorly). For each parallel timeline, you want a vector data structure. You can store each parallel timeline in a linked list. Each timeline knows at what time it began.
To run the game, you iterate through all active timelines and perform one frame's worth of actions from each of them in lockstep. No need for parallel processing.
您应该做的是首先阅读并理解“固定时间步长”游戏循环(这里有一个很好的解释:http://www.gaffer.org/game-physicals/fix-your-timestep)。
然后你要做的就是保存帧计数器和动作对的列表。 STL 示例:
或者可能是成对列表的向量。 要创建状态,对于每个操作(玩家交互),您存储帧编号以及执行的操作,如果操作只是“按下键”或“键”,您很可能会获得最佳结果;released”:
要回放以前的状态,您必须在每次玩家激活时间机器时重置帧计数器,然后遍历每个先前状态的状态列表并查看是否有与当前帧匹配的状态。 如果有,则执行该状态的操作。
为了优化,您可以保留一个迭代器列表,指向您在每个先前状态列表中的位置。 这里有一些伪代码:
我希望你明白...
单独的线程只会使问题变得非常复杂,这样你每次都会得到相同的结果,而你不能通过使用单独的线程来保证这一点线程(无法真正看到如何实现)或非固定时间步长游戏循环。
当谈到图形 API 时,我会选择 SDL,因为它可能是最容易入门的。 如果您想使用 3D,以后可以随时使用 SDL 的 OpenGL。
What you should do is first to read and understand the "fixed time-step" game loop (Here's a good explanation: http://www.gaffer.org/game-physics/fix-your-timestep).
Then what you do is to keep a list of list of pairs of frame counter and action. STL example:
Or maybe a vector of lists of pairs. To create the state, for every action (player interaction) you store the frame number and what action is performed, most likely you'd get the best results if action simply was "key <X> pressed" or "key <X> released":
To play back the previous states, you'd have to reset the frame counter every time the player activates the time machine and then iterate through the state list for each previous state and see if any matches the current frame. If there is, perform the action for that state.
To optimize you could keep a list of iterators to where you are in each previous state-list. Here's some pseudo-code for that:
I hope you get the idea...
Separate threads would simply complicate the matter greatly, this way you get the same result every time, which you cannot guarantee by using separate threads (can't really see how that would be implemented) or a non-fixed time-step game loop.
When it comes to graphics API, I'd go with SDL as it's probably the easiest thing to get you started. You can always use OpenGL from SDL later on if you want to go 3D.