Перекрытие прямоугольника в Java - PullRequest
0 голосов
/ 14 ноября 2018

Я пытаюсь сделать генератор случайных карт.Он должен создавать комнаты произвольного размера с произвольными координатами и удалять комнату, которую он перекрывает с другими комнатами.Однако проверка перекрытия не работает.Вот соответствующие части кода:

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

    }
}

А затем класс комнаты:

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

}

Итак, я проверял это, и он удаляетнесколько комнат каждый раз, но всегда есть некоторые, которые накладываются в зависимости от количества комнат, конечно.Должно быть какое-то глупое простое решение, которого я сейчас не вижу ... Кроме того, почему он не генерирует комнаты, если я не добавляю первую вручную?Спасибо

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

Для вашей первой проблемы, когда вы инициализировали первую комнату, вам не нужно это делать.

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

Вам просто нужно проверить первую комнату и не нужно проверять наложение, как естьпервая комната.Что касается второй проблемы, вы можете вернуть true в первый раз, когда обнаружите пересечение, в противном случае вернуть false в конце цикла.

Код для вашей справки.

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;
}
}
0 голосов
/ 14 ноября 2018

Ваша проблема в этой функции overlaps:

overlap = false;

То, что происходит в вашем коде, заключается в том, что вы продолжаете проверять комнаты, если они перекрываются или нет, но если вы найдете одну, которая перекрывается, вы продолжаете идти. И затем, когда вы находите комнату, которая перекрывается , а не , вы сбрасываете флаг. По сути код эквивалентен только проверке последней комнаты.

Полностью уберите флаг перекрытия. Вместо overlap = true; в оператор ставится return true; (потому что на данный момент мы знаем, что хотя бы одна комната перекрывается). Не делайте ничего, когда узнаете, что комната не пересекается с другой комнатой (в цикле). В конце, после цикла for просто return false; Факт, что выполнение кода дошло до этой точки, означает, что нет перекрывающейся комнаты (иначе она только что вернулась бы уже)

Примечание: я считаю, что условие !r2.intersects(r1) && !r1.intersects(r2) является избыточным. .intersects(r) должен быть коммутативным, что означает, что r1.intersects(r2) и r2.intersects(r1) дают одинаковые результаты.

...