【问题标题】:Java - Checking Colisions Between Multiple Rectangles in an ArrayListJava - 检查 ArrayList 中多个矩形之间的冲突
【发布时间】:2016-05-21 08:14:24
【问题描述】:

在搜索了包括这个在内的大量网站后,我遇到的每个解决方案似乎都不起作用,或者只适用于列表中的第一个对象。

问题

Slick2Ds Rectangle 类提供了许多不同的碰撞方法,其中一种是intersects(Rectangle box); 方法,在将此类与 ArrayList 类中内置的 java 结合使用时,在一定程度上可以正确检测碰撞。我遇到的问题是只有列表中的第一个对象被检测到并正确碰撞。

以下代码处理冲突:

public void move(float x, float y) {
    if (blocks.size() > 0) {
        for (int i = 0; i < blocks.size(); i++) {
            Rectangle r = blocks.get(i);
            Rectangle p = new Rectangle(xx + x, yy + y, 32, 32);
            if (!r.intersects(p)) {
                xp = xx;
                yp = yy;
                xx += x;
                yy += y;
                break;
            } else {
                xx = xp;
                yy = yp;
                xx += 0;
                yy += 0;
                System.out.println("Collide" + new Date());
                break;
            }
        }
    }else{
        xp = xx;
        yp = yy;
        xx += x;
        yy += y;
    }
}

密钥:xx = 玩家 x; yy = 玩家 y; xp = 玩家最后 x 位置; yp = 玩家最后 y 位置; r = 迭代列表中的当前矩形; p = 预先计算的玩家的下一个位置

这个基本的代码工作是通过模拟一个矩形来添加运动,该矩形将在玩家的下一个位置。如果它没有碰撞,那么玩家不会碰撞并且我们可以移动,但是如果它确实碰撞了,那么我们不会移动玩家,因为下一个位置没有打开。

但是代码有一个缺陷,因为在迭代过程中的某个时刻,只有 first 框起作用,其他的确实检测到碰撞但不会停止该框。

Correct Collision; logged in the console to confirm

Incorrect Collision; not logged in the console, even though its another instance of the same object

【问题讨论】:

  • 我将打印两个相交矩形的值,而不是打印 "Collide" + new Date() - 这样您就可以看到它们是否应该实际相交或不是。
  • 我添加了一个新的记录器供大家查看,看看您是否可以帮助我找到我的错误
  • 为什么r.intersects(p) if 语句的两个分支都会中断?
  • 为了不允许代码在迭代中添加运动,基本上它会做的是每次迭代后速度会成倍增加。但我发现取消休息并不会改变这种情况。只会让移动速度变慢。
  • 请注意,ArrayList 对问题或解决方案并不重要,任何类型的List 都会起到相同的作用;事实上,任何Iterable 也可以使用enhanced for loop,如for (final Rectangle r : blocks) { ... (在卡尔的回答中)

标签: java arraylist collision-detection slick2d


【解决方案1】:

如果你使用会发生什么:

public void move(float x, float y) {

    boolean intersectedBlock = false;

    for (int i = 0; i < blocks.size(); i++) {
        Rectangle r = blocks.get(i);
        Rectangle p = new Rectangle(xx + x, yy + y, 32, 32);

        if (r.intersects(p)) {
            intersectedBlock = true;
            break;
        }
    }

    if (intersectedBlock) {
        xx = xp;
        yy = yp;
        xx += 0;
        yy += 0;
        System.out.println("Collide" + new Date());
    } else {
        xp = xx;
        yp = yy;
        xx += x;
        yy += y;
    }
}

【讨论】:

  • 它有效,我没想过要单独进行迭代和移动
【解决方案2】:

尝试删除所有中断。 因为如果它找到相交与否,它就会跳出循环。

【讨论】:

  • 完成,虽然检测到碰撞,但不会发生停止,它只会减慢玩家的移动速度。那是未知的问题。检测到碰撞,但未按应有的方式处理。另一个错误是相对于数组列表的大小出现指数播放器速度。
  • 加速可能是因为您为当前未与玩家相交的每个块添加了玩家位置的动量。您的 for 循环遍历每个块。如果玩家与它相交,它不会移动。如果玩家不这样做,玩家就会被移动。
猜你喜欢
  • 2014-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-29
  • 2017-02-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多