【问题标题】:Ball vs Ball collision Optimization球与球碰撞优化
【发布时间】:2013-10-04 06:22:13
【问题描述】:

我正在做一个有球碰撞的项目,我检测这种碰撞的方法很简单。它从数组中获取一个对象,然后将自己与数组中的所有对象进行比较。如何检测碰撞是通过检查中心点距离是否低于两个半径。

这很好用,但是当您同时拥有 100 多个对象时,就会出现很多冗余。这意味着为什么单个对象会检查屏幕另一侧的对象的位置,它碰撞的可能性很低。

我发现了一个理论,一个对象应该只检查比它自己更大的区域中的其他对象。然后,如果该区域内有另一个物体,就会开始检测碰撞。但这只会创建额外的检查,因为对象必须检查所有对象是否在该区域内,然后检查对象是否正在碰撞。

有没有一种方法可以有效地检测碰撞?

public function newHandler():void
{
    for ( var i:int = 0; i < _objectArrayLayer1.length; i++ )
    {
        mcBall1 = _objectArrayLayer1[i];

            for ( var j:int = i + 1; j < _objectArrayLayer1.length; j++)
            {
                mcBall2 = _objectArrayLayer1[j];

                p1 = new Point(mcBall1.nX, mcBall1.nY);
                p2 = new Point(mcBall2.nX, mcBall2.nY);
                distance = Point.distance(p1,p2);

                radius1 = mcBall1._radius ;
                radius2 = mcBall2._radius ;

                if (distance <= radius1 + radius2)
                {
                    solveBalls( mcBall1, mcBall2 );
                }
            }
        }

【问题讨论】:

    标签: actionscript-3 collision-detection


    【解决方案1】:

    您可以采取一些措施来加快循环速度 - 这不是一个确定的列表,但它有助于获得一些额外的性能。

    1. 您正在为您的检查创建许多临时的Point 对象。只需在函数开头创建 2 个Point 对象并不断更新它们的xy 坐标。这样您就可以避免构建大量对象的成本。内存分配很昂贵,然后垃圾收集器也必须处理它们。
    2. 您应该将mcBall1._radius 缓存在局部变量中(如radius1 - 它比在嵌套循环的每次迭代中读取属性更快。
    3. 不要使用distance,而是使用距离的平方 - 这样可以避免计算平方根。在这种情况下,您可以缓存radius1*radius1

    除此之外,您还可以将您的世界划分为多个部分,并为每个部分分配一个分区索引。为每个球添加一个分区变量 - 当它们在世界各地移动时,您将更新此分区变量。这不是一项昂贵的操作,因为它只是一个简单的检查,看看球是否在哪个分区矩形内 - 根据球的速度,它们只能从给定分区移动到这么多其他分区。

    如果您使用 5x5 分区,您可以得到 25 个分区,并且在任何时候您都可以知道单个分区中有多少个球。在碰撞检测方面,您可以避免检查不在当前分区或任何周围分区中的任何对象。这将使您的碰撞检测代码显着提升。

    以这个问题为例:Optimizing collison detection code in AS3

    编辑:在我打字的时候,@Paddyd 发布了他对四叉树的回答——这实际上是一个“四叉树”的简单实现,但没有嵌套分区和 5x5 而不是 2x2 分区。

    【讨论】:

    • Point.distance 再补充一点,将 X 偏移量和 Y 偏移量平方并与半径和的平方进行比较,OP 确实会更好。否则,很好。
    • @Vesper Point.distance 不会创建 Point 对象 - 它返回 Number。在本地(而不是在函数调用中)计算距离的平方可能会更快。
    • 噢。抱歉,看来我要睡觉了。
    • 对于第 1 点,你是对的,但第二点我必须检查每个循环的半径,因为对象的大小不同。第三点,我之前尝试过,它减慢了fps。我又试了一次,现在它提高了性能,真的很奇怪。
    • 非常感谢!我想我会试试你的四叉树实现。
    【解决方案2】:

    阅读Quadtrees

    Here 是一个实现示例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-11
      • 1970-01-01
      • 2010-12-29
      • 2014-05-19
      • 2014-06-06
      相关资源
      最近更新 更多