javaprocedural-generationroguelike

Rectangle overlapping in Java


I'm trying to make a random map generator. It should create a random sized rooms at random coordinates, and remove the room it it overlaps with other rooms. However, the overlap checking isn't working. Here are the relevant parts of code:

public static void generateMap() {
    rooms[0] = new Room(0,10,10,5); // For some reason doesn't work without this?
    for (int i=0;i<ROOMS;i++) {
        int x = randomWithRange(0,WIDTH);
        int y = randomWithRange(0,HEIGHT);
        int height = randomWithRange(MINROOMSIZE,MAXROOMSIZE);
        int width = randomWithRange(MINROOMSIZE,MAXROOMSIZE);
        while (x+width > WIDTH) {
            x--;
        }
        while (y+height > HEIGHT) {
            y--;
        }
        Room room = new Room(x,y,width,height);
        if (room.overlaps(rooms) == false) {
            rooms[i] = room;
        }

    }
}

And then the Room class:

import java.awt.*;

public class Room {
    int x;
    int y;
    int height;
    int width;

public Room(int rx, int ry, int rwidth, int rheight) {
    x = rx;
    y = ry;
    height = rheight;
    width = rwidth;
}
boolean overlaps(Room[] roomlist) {
    boolean overlap = true;
    Rectangle r1 = new Rectangle(x,y,width,height);
    if (roomlist != null) {
        for (int i=0;i<roomlist.length;i++) {
            if (roomlist[i] != null) {
                Rectangle r2 = new Rectangle(roomlist[i].x,roomlist[i].y,roomlist[i].width,roomlist[i].height);
                if (!r2.intersects(r1) && !r1.intersects(r2)) {
                    overlap = false;
                }
                else {
                    overlap = true;
                }
            }                
        }
    }
    return overlap;
}

}

So I've been testing this, and it removes a few rooms each time, but there's always some that are overlapping depending on the number of rooms of course. There must be some stupid easy solution I just can't see right now... Also, why doesn't it generate any rooms unless I manually add the first one? Thanks


Solution

  • For your first issue where you have initialized first room, you don't have to do that.

    rooms[0] = new Room(0,10,10,5); // For some reason doesn't work without this?
    

    You just need to check for first room and no need to check for overlap as it is the first room. For the second issue, you can return true at the first time you find an intersect otherwise return false at the end of the loop.

    Code for your reference.

    class Room {
    int x;
    int y;
    int height;
    int width;
    
    public Room(int rx, int ry, int rwidth, int rheight) {
        x = rx;
        y = ry;
        height = rheight;
        width = rwidth;
    }
    
    boolean overlaps(Room[] roomlist) {
        Rectangle r1 = new Rectangle(x, y, width, height);
        if (roomlist != null) {
            for (int i = 0; i < roomlist.length; i++) {
                if (roomlist[i] != null) {
                    Rectangle r2 = new Rectangle(roomlist[i].x, roomlist[i].y, roomlist[i].width, roomlist[i].height);
                    if (r2.intersects(r1)) {
                        return true;
                    } 
                }
            }
        }
        return false;
    }
    }
    
    public class RoomGenerator {
    private static final int ROOMS = 10;
    private static final int WIDTH = 1200;
    private static final int HEIGHT = 1000;
    private static final int MINROOMSIZE = 10;
    private static final int MAXROOMSIZE = 120;
    
    public static void main(String[] args) {
        generateMap();
    }
    
    public static void generateMap() {
        Room rooms[] = new Room[10];
        for (int i = 0; i < ROOMS; i++) {
            int x = randomWithRange(0, WIDTH);
            int y = randomWithRange(0, HEIGHT);
            int height = randomWithRange(MINROOMSIZE, MAXROOMSIZE);
            int width = randomWithRange(MINROOMSIZE, MAXROOMSIZE);
            while (x + width > WIDTH) {
                x--;
            }
            while (y + height > HEIGHT) {
                y--;
            }
            Room room = new Room(x, y, width, height);
            if( i ==0)
            {
                rooms[0] = room;
            }else if (room.overlaps(rooms) == false) {
                rooms[i] = room;
            }
        }
    }
    
    private static int randomWithRange(int min, int max) {
        // TODO Auto-generated method stub
        Random r = new Random();
        return r.nextInt((max - min) + 1) + min;
    }
    }