【问题标题】:Slow collision detection using bounding box使用边界框进行慢速碰撞检测
【发布时间】:2012-04-08 01:02:28
【问题描述】:

我有一个小型库,我想用它来创建游戏。首先,我尝试实现像素完美碰撞检测,但并不顺利,所以我决定使用简单的边界框碰撞检测。它工作正常,但在对象数量超过 20 个左右后,它开始变慢。这是我的代码: (循环运行,每秒 25 次)

for (int i=0;i<sc.collGr.size();i++){
    CollisionGroup gr=sc.collGr.get(i);
    Collidable[] cc=gr.getCollidables();
    for (int l=0;l<cc.length;l++){
        for (int w=l+1;w<cc.length;w++){
            if (BorderBox.areColliding(cc[l].getBorderBox(), cc[w].getBorderBox()){
                addEventToHandler(sc.collGr.get(i),cc[l],cc[w]);
            }
        }
   }
}

BorderBox 类的一部分:

public class BorderBox {
int top;
int down;
int left;
int right;

/**
 * Creates new BorderBox object
 * Arguments: (top, down, left, right);
 * */
public BorderBox(int topy,int downy, int leftx,int rightx){
    top=topy;
    down=downy;
    left=leftx;
    right=rightx;
}

/**
 * Checks if two provided BorderBoxes are colliding.
 * */
public static boolean areColliding(BorderBox a,BorderBox b){
    if (b.left<=a.right && b.right>=a.left && b.down>=a.top && b.top<=a.down){
        return true;
    }
    return false;
}

【问题讨论】:

  • 不要检查每一对,而是尝试设置一个“智能”系统,粗略地(没有误报)估计两个物体何时会发生碰撞,以防止检查两个彼此相距不远的物体。您可以使用边界圆来完全防弹。

标签: java android


【解决方案1】:

以这种方式检查是O(n^2) 操作。也就是说,当您添加一个新对象时,您所做的工作量会呈二次方增长。

我之前缓解此问题的方法以及其他建议是在两个不同的数组中拥有两种类型的可碰撞对象。一个阵列有少量对象,主要是角色,另一个阵列有敌人。这个想法是你不关心敌人相互碰撞。因此,您只需检查较小数组中的元素是否与较大数组中的元素发生冲突,就可以大大减少您必须做的工作量。

这当然是特定于游戏的,如果一切都必须与其他一切发生冲突,这将无法正常工作。不过,我发现简单的游戏通常不是这种情况。

【讨论】:

    【解决方案2】:

    划分您的空间以避免检查相距较远的物体的碰撞。根据您的游戏,可以使用简单的网格,或者使用更高级的东西,例如 kd-Trees。我曾经做过一个有实际房间的游戏,我只是检查了同一个房间中的对象之间的碰撞(假设房间比对象少,或者更新哪个对象在哪个房间很容易)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-01
      • 2014-02-04
      • 1970-01-01
      • 1970-01-01
      • 2015-02-02
      • 1970-01-01
      • 1970-01-01
      • 2011-04-21
      相关资源
      最近更新 更多