是否有更快的碰撞检测算法?

时间:2012-11-21 03:49:13

标签: android performance collision-detection

我正在Android上编写这个游戏,我有一堆人物四处移动,互相碰撞。一切正常,但当我同时在屏幕上传递一定数量的字符时,应用程序的性能会受到严重影响。我做了我的测试并且绘图没有导致低帧率,它是用于碰撞检测的算法,因为每次他们移动时他们必须检查他们对所有其他角色的位置。所以目前我只是为每个角色循环遍历它们。有没有办法改善这个?在我不知道的大量物体上是否存在碰撞检测的性能技巧?

4 个答案:

答案 0 :(得分:2)

是的,有一种基于第一次宽相和第二次窄相检测的技术。

我将引用一些段落来自:开始Android游戏,由Mario Zechner撰写。

  

广泛阶段:在这个阶段,我们试图找出哪些对象可以   潜在的碰撞。想象一下,每个都有100个物体   相互碰撞。我们需要执行100 * 100/2重叠   测试我们是否选择天真地测试每个对象   宾语。这种天真的重叠测试方法是O(n ^ 2)渐近   复杂性,意味着它需要n ^ 2步才能完成(实际上   完成了那么多步骤的一半,但是渐近的复杂性   遗漏任何常数)。在一个良好的,非暴力的广泛阶段,我们   试着找出哪些物体实际上有危险   碰撞。其他对(例如,两个相距太远的物体)   不会检查发生碰撞的情况。我们可以减少   以这种方式计算负载,因为窄相位测试通常很漂亮   昂贵。

     

狭窄阶段:一旦我们知道哪些对象可能存在   碰撞,我们测试他们是否真的碰撞了   它们的边界形状的重叠测试。

广泛的阶段涉及将世界划分为大型细胞,形成某种网格。 每个细胞具有完全相同的大小,整个世界都被细胞覆盖。如果两个对象不在同一个单元格中,则不需要这两个对象的窄相位。

再次引用:

  

我们需要做的就是:

     
      
  • 根据物理和控制器步骤更新世界上的所有对象。

  •   
  • 根据对象的位置更新每个对象的每个边界形状的位置。我们当然也可以在这里包括方向和规模。

  •   
  • 根据边界形状确定每个对象包含哪个或哪些单元格,并将其添加到这些单元格中包含的对象列表中。

  •   
  • 检查碰撞,但仅检查可能发生碰撞的对象对(例如,Goombas不与其他Goombas发生碰撞)并且位于同一单元格中。

  •   
     

这称为空间散列网格广泛阶段,并且很容易实现。我们要定义的第一件事是每个单元格的大小。这在很大程度上取决于我们用于游戏世界的规模和单位。

它还取决于您正在使用的边界形状。围绕角色的简单矩形或圆圈以及它的欧氏距离是一个简单的计算方法,但是更精细的形状(包括“头部”,“腿部”以及几乎没有其他边界形状的细节)将会计算成本要高得多。

答案 1 :(得分:0)

如果所有对象都可以自由移动到屏幕的任何部分,那么您可以做的最好的就是O(n^2)算法。通过实现当检查对象A是否与对象B发生碰撞时,可以通过常数因子对其进行改进,然后您不必稍后检查对象B是否与对象A发生碰撞。

答案 2 :(得分:0)

将每个字符包含在固定大小的正方形中。在检查字符冲突之前,请检查它们所包围的方块是否发生碰撞。当且仅当正方形碰撞时,角色才有可能发生碰撞。现在检查方块碰撞很容易,因为你只需要比较x和amp; y坐标。

答案 3 :(得分:0)

按照Federico的建议分为宽泛阶段和狭窄阶段,只有在您的碰撞检测算法很昂贵(即它不是一个简单的边界框)的情况下才有用。

幸运的是,还有其他选择。

您可以尝试使用碰撞遮罩技术。由于您似乎不受渲染速度的限制,因此将每个对象的边界框渲染为隐藏的位图。在渲染下一个对象之前,请检查其边界框的四个角处的像素,看是否已被写入。您甚至可以为每个对象使用不同的颜色,以便该颜色告诉您发生碰撞的对象。

另一个流行的技巧是根本不对每个帧进行每个碰撞检查。例如,《超级马里奥兄弟》这类游戏实际上仅每隔一帧就检查玩家与敌人之间的碰撞。您可以做一个更高级的版本,以循环方式检查所有对象,每帧可以完成所有检查。当事情变得忙碌时,每个对象可能只会被检查一次,甚至每三帧一次,但是玩家不太可能注意到。如果您的物体移动得不太快,以至于它们只能互相碰撞一帧,那么这种方法效果最好。