【问题标题】:Collision Detection in Java 2D Not Working ProperlyJava 2D 中的碰撞检测无法正常工作
【发布时间】:2017-02-08 07:16:25
【问题描述】:

所以基本上在过去的半年里,我一直试图让这个盒子家伙(玩家)当他与另一个盒子相撞时,他会停止向与盒子相撞的方向移动。这有点像成功,但在看似随机的时刻,如果我向上移动并击中玩家左侧的盒子,它可能会飞入与之碰撞的盒子并飞下来。各个方向都一样。

public int checkCollision(ID id){
    for(int i = 0; i < handler.obj.size(); i++){ //Cycles through all the objects
        GameObject go = handler.obj.get(i); //Stores a temp GameObject
        if(go.getID() == id){ //Checks if the id matches and if so do the collision stuff.
            if(getBoundsT().intersects(go.getBounds())){
                System.out.println("collided top");
                y = go.getY() + go.getHeight();
                velY = 0;
                return 0; //Top side
            }
            if(getBoundsB().intersects(go.getBounds())){
                System.out.println("collided bottom");
                y = go.getY() - height;
                velY = 0;
                return 1; //Bottom side
            }
            if(getBoundsL().intersects(go.getBounds())){
                x = go.getX() + width;
                velX = 0;
                System.out.println("collided left");
                return 2; //Left Side
            }
            if(getBoundsR().intersects(go.getBounds())){
                System.out.println("collided right");
                x = go.getX() - width;
                velX = 0;
                return 3; //Right Side
            }
            if(getBounds().intersects(go.getBounds())){
                System.out.println("collided on all sides");
                return 4; //All the sides
            }
        }
    }
    return 5; //No Collision
}

checkCollision 方法每秒被调用 60 次。 getBounds(l/r/u/d) 函数只返回对应于字母的左、右、顶(上)或底(下)侧的矩形。 Id 就是玩家正在碰撞的东西。在这种情况下,它是墙,所以无论它说 id,它只是墙。 (我已确保矩形不会超出应有的区域。)

我已经尝试了我能想到的所有方法,因此我们将不胜感激! (这是我的第一个问题,如果写得很糟糕,请见谅)

编辑:相交代码 (getBounds) 这是在所有对象继承的 GameObject 类中。

public Rectangle getBoundsB() {
        return new Rectangle((int)(x + (width/2) - (width/4)), (int)(y + height/2), (int)(width / 2), (int)(height / 2));
    }
    public Rectangle getBoundsT() {
        return new Rectangle((int)(x + (width/2) - (int)(width/4)), (int) y, (int)width / 2, (int)(height / 2));
    }
    public Rectangle getBoundsR() {
        return new Rectangle((int)(x + width - 5), (int)(y + 5), 5, (int)(height - 10));
    }
    public Rectangle getBoundsL() {
        return new Rectangle((int)x, (int)(y + 5), 5, (int)(height - 10));
    }

    public Rectangle getBounds() {
        return new Rectangle((int)x, (int)y, (int)width, (int)height);
    }

在tick方法中(每60秒调用一次):

checkCollision(ID.Wall);

【问题讨论】:

  • 您如何检查是否发生了交叉路口。它可以指定它在多个点相交,并且返回匹配的第一个 if 语句。因此,如果它对左侧和底部感兴趣,它可能会先返回底部。
  • 您是否只检查左边缘是否与右边缘相交?或者如果左边缘与任何边缘相交,你会这样做吗?
  • 所以我过去做过类似的事情。发生的事情是它按顺序检查。因此,当我进行相交检查时,它显示左边缘与左侧和底部相交。如果它发生在你的身上,它总是会按上、下、左、右的顺序返回。所以即使你从左边相交,它也可能返回底部。
  • 有可能。你能提供你的交叉代码吗?
  • 所以看起来这正是正在发生的事情。想象一下,将两个大小相等的矩形并排排列。即使只有 1 个像素,它也会在 3 个可能的边上相交。

标签: java 2d collision


【解决方案1】:

下图显示了矩形的 3 个边靠墙。如果我将矩形按在墙上,蓝色和绿色线的左角接触墙壁,红线接触墙壁。所以发生的事情是因为您首先检查顶部,它会看到在那个单点有一个交叉点,并且对于顶部交叉点而不是左侧返回 true。

我认为您可以通过修改获得上/下界的方式来解决此问题。也许通过从宽度中减去 1 来返回边界。

【讨论】:

  • 这不是问题:(我的碰撞框不是这样绘制的。我截取了它的外观。要注意的框是红色的。那些是碰撞框:imgur.com/51tMGkq。(两个蓝色框基本相同)。
  • 在您的 getBoundsB/T/L/R 方法中,您是在扩展框的边界还是与它碰撞的对象的边界?
  • 是的,我正在检查左侧是否与任何一侧发生碰撞 - 你认为如果我检查左侧是否与右侧发生碰撞会更好吗?编辑:不,它没有:(
  • @Cornchip 我注意到您已经打印出指定触发冲突代码的哪一侧。当你从左侧击球时,打印出来的内容是什么?
  • 如果我击中左侧直到我撞到它,它会说左侧,然后它会说它在稍微穿过它后在顶部和底部发生碰撞。我会快速告诉你:youtu.be/GzEQMD2SyWY
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多