设置碰撞检测,然后在 2D 游戏中处理碰撞

Posted

技术标签:

【中文标题】设置碰撞检测,然后在 2D 游戏中处理碰撞【英文标题】:Setting up for collision detection and then dealing with a collision in a 2D game 【发布时间】:2012-04-27 16:28:37 【问题描述】:

我搜索了碰撞检测主题,但它们都是关于检测本身的。我的问题更多是关于检测过程之前和之后的。我正在编写我的第一个大型游戏,我想让它尽可能高效。

游戏的前提是你驾驶一艘船绕着一个运动场飞行。在这个领域将是由环境、敌舰和在太空中飞行和漂浮的弹丸提供的不同性质的障碍物。如果需要或想要,这些对象将能够围绕它们的中心等旋转。

我设置测试的想法是让对象以某种方式将自己加载到队列和列表中。然后,游戏将获取队列前面的任何内容,并针对列表中的所有内容进行测试。它会首先检查以确保列表中的东西不是它自己(这会一直为所有东西产生冲突,哈哈)。接下来,游戏将检查队列中的对象与列表中的对象之间是否存在碰撞。如果发生碰撞,它将标记对象说它们已经碰撞并保存引用或对象碰撞的任何内容。

例如,如果 A 与 B 发生碰撞,游戏将告诉 A 运行碰撞函数,B 运行碰撞函数,并将 B 的引用存储到 A 中,B 将存储 A 的引用。

然后游戏将继续检查队列中对象的碰撞,直到它遍历列表,每次都执行上述操作以说明一个对象击中或被多个对象击中。

例如,如果有三个球 A、B 和 C,并且 A 在同一帧中同时被 B 和 C 击中,则 A 的速度将由 B 修改,然后由 C 和 B和 C 的速度会被 A 修改。

这是一种明智的做法吗?我现在并不担心碰撞的实际检测,有很多可用的文章或教程加上我自己的想法来解决这个问题。我没有遇到任何谈论之前和之后的事情。我不确定队列和列表中有多少东西会开始导致大量负载并减慢游戏速度。现在我的对象都只是 x,y 位置、x,y 速度、它们面对的方向以及其他一些东西。

现在我想我开始喋喋不休地谈论无关的事情了。任何见解或智慧将不胜感激。

【问题讨论】:

移动向量是否在您遍历队列时更新?似乎 B 和 C 的运动向量会在 A 改变其运动向量之后被 A 修改。 它会保存旧值和新值,运行检测过程,然后如果需要,所有对象都会自行更新。所以在这个例子中,A 将与 B 交互,A 将保存它的新速度。然后,它将与 C 交互,这将修改并保存更新的速度。然后,一旦游戏退出检测,它就会运行一个进程来更新对象,让它们使用新的速度或做任何事情。 是的,但是当您计算 C 的新速度时,C 不会使用 A 的新速度吗?假设我能想到的最简单的碰撞响应,A 具有起始速度 (0,1),C 具有 (0, -1),B 也具有 (0, -1),A 与 B 和 C 在同一帧,首先它被 B 修改,给 A 速度 (0,-1),然后它与 C 碰撞,但是由于它们具有相同的速度矢量,所以两者都没有变化(或者它们都在同一方向上增加速度)。或者你的意思是新的速度存储在一个新的列表中,并且在所有计算完成后交换列表? 是的,新速度将单独存储,然后在所有碰撞功能完成后交换。 【参考方案1】:

对于许多游戏开发主题,没有通用的答案,这取决于您的游戏类型,但在遍历对象时请记住一些事项:

尝试考虑在碰撞检测后您将如何做出实际反应(您将使用双重调度、访问者、向下转换/rtti、存储可在函数映射中使用的特征,...)。有多种技术,都有其优点和缺点。您选择的方法可以反映您如何进行实际遍历。 尝试将场景拆分为对象类型。例如,如果您有许多永远不会移动的静态对象,那么将它们全部相互测试是荒谬的,您应该将它们分开。但根据经验,不要尝试过多地专门化这个,拥有 staticdynamic 这样的东西可能会带来很大的好处,拥有 100 种类型会产生维护地狱,通常没有真正的收益。 这可能与您的遮挡机制有关。例如,如果它是基于门户的,则来自不同单元的对象不太可能发生碰撞。

我现在可能忘记了其他一些技巧,因为这是一个复杂的话题,但我希望它能让你继续前进。

【讨论】:

有任何链接到一个很好的教程,其中一些东西,最好是真正一步一步的东西?我最难通过阅读来学习东西,需要看到它发生并解释它。 @Azaral:我对碰撞检测的了解大部分来自经验或阅读独立文章。我真的不能推荐一本书或教程。

以上是关于设置碰撞检测,然后在 2D 游戏中处理碰撞的主要内容,如果未能解决你的问题,请参考以下文章

Unity 2d 中的碰撞检测

2D空间中使用Quadtree四叉树进行碰撞检测优化

[译]2D空间中使用四叉树Quadtree进行碰撞检测优化

降维检测物体碰撞

canvas游戏和动画中的碰撞检测

love2d(lua)中的碰撞检测