3
\$\begingroup\$

I'm trying to create rooms dynamically by creating them in random places and checking if they do overlap each other. The idea is that if the new room intersects with another one, it must be recreated so it doesn't intersect with anyone.

This is the room creating loop:

void GenerateBasicLevel(){
    roomsList = new List<Room> ();
    int initX = 0, initY = 0;
    for (int roomsCreated = 0; roomsCreated < 10; roomsCreated ++) {
        //Room size
        height = Random.Range (minSize, maxSize);
        width = Random.Range (minSize, maxSize);
        if(roomsCreated == 0){
            initX = 1;
            initY = 1;
        }else{
            bool loopBreaker = true;
            while(loopBreaker){
                initX = Random.Range(0,mapWidth);
                initY = Random.Range(0,mapHeight);
                foreach(Room r in roomsList){
                    loopBreaker = RoomIntersects(initX - 1, initX + width +1, initY - 1,initY + height + 1,r);
                    if(loopBreaker){
                        Debug.Log ("I do intersect");
                        break;
                    }
                }
            }
        }
        roomsList.Add(new Room(initX - 1,initX + width + 1,initY - 1,initY + height + 1,floorTiles,wallTile));

    }}

This is the Intersect checker function:

bool RoomIntersects(int x1, int x2, int y1, int y2, Room cR){
        if (x1 <= cR.x2 && x1 >= cR.x1 && y1 >= cR.y1 && y1 <= cR.y2)
            return true;
        else if (x2 <= cR.x2 && x2 >= cR.x1 && y1 >= cR.y1 && y1 <= cR.y2)
            return true;
        else if (x1 <= cR.x2 && x1 >= cR.x1 && y2 >= cR.y1 && y2 <= cR.y2)
            return true;
        else if (x2 <= cR.x2 && x2 >= cR.x1 && y2 >= cR.y1 && y2 <= cR.y2)
            return true;
        else
           return false;
    }

Rooms are objects with just 4 parameters: x1,x2,y1,y2.

This is my final result, overlaping rooms: http://i.imgur.com/xNrqc3C.png

\$\endgroup\$
2
\$\begingroup\$

The problem is with your RoomIntersects() function. If no corner of the new room is within the existing room, then your function will return false. What about when only the edge of the room overlaps and crosses completely across the existing room? In your picture. I would expect that the rooms beneath the overlapping rooms are the ones that were added after the overlapping ones.

bool RoomIntersects(int x1, int x2, int y1, int y2, Room cR){
    // left-top corner of room1 is within room2
    if (x1 <= cR.x2 && x1 >= cR.x1 && y1 >= cR.y1 && y1 <= cR.y2)
        return true;
    // right-top corner of room1 is within room2
    else if (x2 <= cR.x2 && x2 >= cR.x1 && y1 >= cR.y1 && y1 <= cR.y2)
        return true;
    // left-bottom corner of room1 is within room2
    else if (x1 <= cR.x2 && x1 >= cR.x1 && y2 >= cR.y1 && y2 <= cR.y2)
        return true;
    // right-bottom corner of room1 is within room2
    else if (x2 <= cR.x2 && x2 >= cR.x1 && y2 >= cR.y1 && y2 <= cR.y2)
        return true;
    else
       return false;
}

Here is a simpler, more efficient way (and correct way) to write your box intersection test. This is called AABB (axis aligned bounding box) collision detection. You can do it the other way also (by testing for inclusion), but this is cleaner and actually faster since there are less tests that need to be done.

bool RoomIntersects(int x1, int x2, int y1, int y2, Room cR) {
    // test for exclusion instead of inclusion
    if (x1 >= cR.x2) return false; // room1.left edge is greater than room2.right edge
    if (x2 <= cR.x1) return false; // room1.right edge is less than room2.left edge
    if (y1 >= cR.y2) return false; // room1.top edge is greater than room2.bottom edge
    if (y2 <= cR.y1) return false; // room1.bottom edge is less than room2.top edge
    return true; // rooms are intersecting
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.