【问题标题】:Collision Detection - Any Language碰撞检测 - 任何语言
【发布时间】:2012-03-23 11:28:11
【问题描述】:

我现在正在编写一个简单的游戏,我需要能够检测许多对象之间的碰撞(检查 10 个对象是否与任何 20 个其他对象发生碰撞,但不会在两组之间发生碰撞)。我编写了一些现在可以工作的简单代码,但在我检测到碰撞后会导致游戏速度非常慢(顺便说一下在 Java 中):

        //Check for collisions between tanks and bullets
        ArrayList<Object> objectsToRemove = new ArrayList<Object>();
        for (int i = 0; i < tanksOnScreen.size(); i += 1) {
            //Get tank
            Tank tank = tanksOnScreen.get(i);

            for (int e = 0; e < bulletsOnScreen.size(); e += 1) {
                //Get bullet
                Bullet bullet = bulletsOnScreen.get(e);

                //Check for collision
                if (tank.collides(bullet.x, bullet.y, 10, 10)) {
                    System.out.println("Collide");
                    objectsToRemove.add(bullet);
                    objectsToRemove.add(tank);
                    break;
                }
            }
        }

        for (Object obj:objectsToRemove) {
            if (obj.getClass().equals(Bullet.class)) {
                bulletsOnScreen.remove(bulletsOnScreen.indexOf(obj));
            } else if (obj.getClass().equals(Tank.class)) {
                tanksOnScreen.remove(tanksOnScreen.indexOf(obj));
            }
        }

还有坦克的collides()方法:

public boolean collides(float px, float py, float pwidth, float pheight) {
    // If the distance between the two centers of the lines on x and y axis
    // Is less than the distance of half the w and h added together, the objects
    // Are colliding
    float x1 = (px > x) ? x : px, x2 = (px > x) ? px : x, y1 = (py > y) ? y : py, y2 = (py > y) ? py : y;
    float w1 = (x1 < x2) ? width : pwidth, w2 = (x1 < x2) ? pwidth : width, h1 = (y1 < y2) ? height : pheight, h2 = (y1 < y2) ? pheight : height;
    if ((x2 + w2/2) - (x1 + w1/2) < (w1/2 + w2/2)&&(y2 + h2/2) - (y1 + h1/2) < (h1/2 + h2/2)) {
        return true;
    } else {
        return false;
    }
}

我认为滞后是由于双 for 循环来迭代对象。我不确定如何消除这些 for 循环或如何在屏幕的某个区域获取项目符号,并且只检查这些项目符号而不使用另一个 for 循环(我认为是隔离)。谁能指出我与许多物体的碰撞检测的正确方向?我不介意答案是什么语言,即使是伪代码。

谢谢,

编辑 1

我现在正在使用适用于 java 的 Slick 图形 API,它为您提供了一个更新和渲染方法来添加渲染和游戏逻辑。我将此碰撞检测放在更新方法中(每帧调用一次 - 大约每秒 60 次)。碰撞发生后速度变慢,物体从屏幕上移除——我觉得这很奇怪。也许删除for循环中的对象后的break命令会根除它?

编辑 2

感谢所有回答的家伙,这些参考对未来有很大帮助。我仅通过将子弹和坦克换成循环来解决问题,因此在子弹被摧毁后它不会继续循环。我不应该问这个问题,因为最后很容易解决。 Dave 和 Banthar 说得对,问题不在于代码,它应该是即时的。

【问题讨论】:

  • 这里看看@trashgod 的这个链接,Collision Detection。这可能会对您的工作有所帮助,尽管它处理弹性碰撞:-)
  • 您当前的方法适用于少量对象。它可能是别的东西,可能是微不足道的。当您打开碰撞检测或检测到某些碰撞时,程序会变慢?有多少坦克和子弹?多少 fps 有/没有碰撞?

标签: java performance for-loop collision-detection collision


【解决方案1】:

一个好主意是使用octree。由于子弹会移动,我假设您将需要它的动力学版本 - 互联网上有很多关于动力学数据结构的文章。

另外,如果你想检测更复杂的凸多边形之间的碰撞,我建议你使用gjk 算法,这种计算速度非常快。请注意,这只会加快一对对象的碰撞检测时间,对的数量仍将保持不变。

【讨论】:

    【解决方案2】:

    除非我遗漏了某些内容,或者您​​没有显示其他代码,否则您将在 O(n^2) 中运行,其中 n 为 20。对于用户来说,它应该是即时的。

    尝试在调试器中单步执行它,看看它在哪里变慢了。

    编辑详细说明:您的昂贵操作不在您发布的代码中。它在其他地方,被您发布的代码调用。

    【讨论】:

      【解决方案3】:

      感谢所有回答的家伙,这些参考对未来有很大帮助。我仅通过将子弹和坦克换成循环来解决问题,因此在子弹被摧毁后它不会继续循环。我不应该问这个问题,因为最后很容易解决。 Dave 和 Banthar 说得对,问题不在于代码,它应该是即时的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-05
        • 2019-04-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多