AABB 检测边缘碰撞 [libGDX]

AABB detecting edge collision [libGDX]

我在整个网络上搜索了回复,但一无所获。 无论如何,我想做的是实现正方形碰撞,但我想知道正方形在哪些边上与另一个正方形发生碰撞。例如,我想检查玩家是否与正方形的上边缘或正方形的左边缘发生碰撞。

这有点痛苦,因为它是 java 但这是解决方案。如果两个矩形相交,我们只关心生成的矩形的大小。每次我们比较它的宽度和高度以获得碰撞的最佳边缘。

public static class AABB {
    float minX, minY, maxX, maxY;

    public AABB(int a, int b, int c, int d) {
        minX = a;
        minY = b;
        maxX = c;
        maxY = d;
    }

    float cx, cy;

    public void updateCenter() {
        cx = minX + (maxX - minX)/2;
        cy = minY + (maxY - minY)/2;
    }

    public Side detect(AABB o) {
        if(maxX < o.minX || minX > o.maxX || maxY < o.minY || minY > o.maxY) return Side.None;

        o.updateCenter();
        updateCenter();

        boolean
        top = minY < o.cy,
        bottom = maxY > o.cy,
        left = maxX > o.cx,
        right = minX < o.cx;

        // depends on how you define y axis, in this case it increases upwards
        if(top && left) {
            return o.minY - maxY > minX - o.maxX ? Side.Top : Side.Left;
        }

        if(top && right) {
            return o.minY - maxY > o.minX - maxX ? Side.Top : Side.Right;
        }

        if(bottom && right) {
            return minY - o.maxY > o.minX - maxX ? Side.Bottom : Side.Right;
        }

        if(bottom && left) {
            return minY - o.maxY > minX - o.maxX ? Side.Bottom : Side.Right;
        }

        throw new RuntimeException("should not reach");
    }

    enum Side {
        Left, Right, Top, Bottom, None
    }
}

public static void main(String[] args){
    AABB base = new AABB(0, 0, 10, 10);
    System.out.println(base.detect(new AABB(12, 0, 20, 10)) == Side.None);
    System.out.println(base.detect(new AABB(10, 0, 20, 10)) == Side.Right);
    System.out.println(base.detect(new AABB(-10, 0, 0, 10)) == Side.Left);
    System.out.println(base.detect(new AABB(0, 10, 10, 20)) == Side.Top);
    System.out.println(base.detect(new AABB(0, -10, 10, 0)) == Side.Bottom);
    System.out.println(base.detect(new AABB(10, 7, 20, 17)) == Side.Right);
    System.out.println(base.detect(new AABB(-10, 7, 0, 17)) == Side.Left);
    System.out.println(base.detect(new AABB(7, 10, 17, 20)) == Side.Top);
    System.out.println(base.detect(new AABB(7, -10, 17, 0)) == Side.Bottom);
}