碰撞检测逻辑应该放在哪里?


19

我正在开发一个小型2D游戏引擎。角色具有绘画方法,当前可以执行以下操作:

  1. 根据角色的速度等计算角色的新位置。
  2. 更新碰撞网格单元**
  3. 在新位置绘制角色

**我创建了一个碰撞网格以减少相交检查的次数

现在我想到的用于检测碰撞的基本算法是:

For Each Character
    Check intersection with characters in surrounding 8 cells

我可以简单地将此代码放在paint方法中。但是,这是我预期的问题。

假设两个字符A和B位于碰撞网格中的相邻单元格中。现在,按照上述算法,在字符A的迭代中,它将检测到它与B碰撞。在字符B的迭代中,它将检测到它与A碰撞。

但是我有一个想法,当A检测到它与B发生碰撞时,应该通知B它与A发生碰撞。当有两个以上的actor发生碰撞时,这样可以节省很多比较。但我不确定如何处理。我认为应该检查游戏循环内的碰撞,而不是每个角色都检查碰撞。

这种方法正确吗?您如何处理此类问题?我自己想到了碰撞网格。碰撞网格逻辑还有其他选择吗?


nitpick很抱歉,但是在一个专门的2D物理库中。游戏物理学通常是非常近似的,因此任何不会使游戏无法进行游戏的解决方案都可以,但是如果您想正确解决它,则可以使用Box2D ... :-D
user712092 2011年

Answers:


14

冲突检测的通常方法是不让A或B自己检测冲突。

取而代之的是,您首先移动所有对象,然后让一个单独的碰撞系统查找所有对象对之间的碰撞,向每个对象告知发生碰撞的事物,然后最终渲染所有对象。

因此,从本质上讲,您无需在Paint()函数中进行“移动,检查碰撞,绘制”,而是将“移动”和“绘制”拆分为单独的函数,分别调用(每个对象首先“移动”,然后为每个对象“绘制”)。在这些之间,检查是否有碰撞。

高级说明:如果您的任何对象对检测到的碰撞做出反应而移动,那么您可能需要重复“查找所有对对象之间的碰撞”步骤,以防对象的碰撞响应引起另一次碰撞。


这是正确的处事方式。让物体处理自己的责任,碰撞系统应确定遇到障碍物时会发生什么。您还可以在角色周围放置一个碰撞矩形/圆柱体(2d / 3d),作为一种早期触发方式。
James P.

大!关于高级提示,难道不应该仅针对因碰撞而移动的对象以及在新位置发生碰撞的对象重新检查碰撞吗?将有一系列检查,但它将避免检查所有对象的碰撞。
Cracker


1

我会像您说的那样为游戏循环中的所有角色运行一个循环。

我这样做的方式是在每个角色上都有一个状态,因此如果A和B在A正在检查碰撞时发生碰撞,则A和B被设置为命中。在B的循环开始时,它检查是否已经被击中,如果是,则id不在循环中运行。

我将情感代码放入循环中,因此对B采取的所有操作均已在A的循环中发生,因此B应该没有理由进行检查,因为这会弄乱碰撞的结果,尽管这可能与您有所不同。


但是在这种情况下,当A检测到与B的交集时,B.hit将设置为true,因此B不会检查任何交集。但是,如果另一个字符C与B相交,B不会检测到它吗?
饼干

对不起,知道了。由于A不与C相交,因此C.hit仍为假。B不会检查碰撞。但是C会检查并将B和C之间发生冲突的信息传递给B。太酷了!
饼干

但是我想如果所有的A,B和C都相交,就会有问题。A将B.hit和C.hit设置为true。B和C会知道他们已经与A发生碰撞。但是,由于hit属性为true,因此不会检查碰撞。B和C之间的冲突将不会引起注意。
饼干

您可以通过将每个可行的碰撞对象放入某种类型的集合中,然后仅检查与该集合中该对象之后的事物之间的碰撞,来采用类似的方法。IE:A检查vs B,C,D;B检查对C,D;C检查与D的比较。后面的每个回合都不需要检查,因为已经在后面的回合中对其进行了检查。不像完全跳过元素的碰撞那样快,但是仍然很有用。
鲁宁
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.