Search code examples
javalibgdx

AABB detecting edge collision [libGDX]


I've searched the whole web for a response, but I've found nothing. anyways, what I'd want to do is implement square collisions, but I want to know on which edges a square is colliding with another one. for example, I want to check if the player collides with the up edge of a square or a left edge of a square.


Solution

  • This was littel painfull as it is java but here is the solution. All we care about, if two rectangles intersect, is size of the resulting rectangle. Each time we compare its width and height to get the best edge of colision.

    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);
    }