Java冲突检测无法按预期运行

时间:2012-12-22 00:06:36

标签: java collision-detection collision lwjgl

使用以下代码检测到碰撞,但未正确注册边。

public int checkBoxes(int aX, int aY, int aWidth, int aHeight, int bX, int bY, int bWidth, int bHeight){

    /*
     * Returns int
     * 0 - No collisions
     * 1 - Top
     * 2 - Left
     * 3 - Bottom
     * 4 - Right
     */

    Vector2f aMin = new Vector2f(aX, aY);
    Vector2f aMax = new Vector2f(aX + aWidth, aY + aHeight);

    Vector2f bMin = new Vector2f(bX, bY);
    Vector2f bMax = new Vector2f(bX + bWidth, bY + bHeight);

    float left = bMin.x - aMax.x;
    float right = bMax.x - aMin.x;
    float top = bMin.y - aMax.y;
    float bottom = bMax.y - aMin.y;

    if(left > 0) return 0;
    if(right < 0) return 0;
    if(top > 0) return 0;
    if(bottom < 0) return 0;

    int returnCode = 0;

    if (Math.abs(left) < right)
    {
        returnCode = 2;
    } else {
        returnCode = 4;
    }

    if (Math.abs(top) < bottom)
    {
        returnCode = 1;
    } else {
        returnCode = 3;
    }

    return returnCode;
}

当A与形状B的顶部,左侧或右侧碰撞时,返回数字3,当与底部碰撞时,返回数字1。我真的不知道造成这种情况的原因。我的代码出了什么问题?

2 个答案:

答案 0 :(得分:2)

使用这些if块,您将始终获得13,因为第二个if块将始终独立于您在第一个块中设置的块执行。

if (Math.abs(left) < right)
{
    returnCode = 2;
} else {
    returnCode = 4;
}

if (Math.abs(top) < bottom)
{
    returnCode = 1;
} else {
    returnCode = 3;
}

答案 1 :(得分:1)

问题是你正在检查一侧,但当你通过示例检查左边并且底部也发生碰撞时你忽略了那一面。我在这里测试了代码:http://wonderfl.net/c/i90L

我所做的是首先获得两侧X和Y的距离。然后检查哪个距离最大,乘以矩形本身的大小,因为那边将始终是正方形的好边缘。

    Vector2f returnCode = new Vector2f(0, 0);

    returnCode.x = (Math.abs(left) - right) * aWidth;
    returnCode.y = (Math.abs(top) - bottom) * aHeight;

    int temp = 0;

    if(returnCode.x > 0){
        //Hits left
        temp = 2;
    }else{
        //Hits right
        temp = 4;
    }

    if(returnCode.y > 0){
        //Hits top
        if(returnCode.y > Math.abs(returnCode.x)){
            temp = 1;
        }
    }else{
        //Hits bottom
        if(returnCode.y < -Math.abs(returnCode.x)){
            temp = 3;
        }
    }

    return temp;