예제 #1
0
        public static List <RoomInfo> GenerateLevel()
        {
            Random.InitState(1370);

            RoomInfo[,] roomLayout = new RoomInfo[MAX_SIZE, MAX_SIZE];
            List <RoomInfo> rooms = new List <RoomInfo>();

            System.Action <Vector2Int, RoomInfo> addRoom = (pos, room) =>
            {
                rooms.Add(room);
                roomLayout[pos.x, pos.y] = room;
            };

            System.Func <int, int, bool> isRoomPresent = (posx, posy) => IsInBounds(posx, posy) && roomLayout[posx, posy] != null;

            var startPos  = GetRandVec2Int(0, MAX_SIZE, 0, MAX_SIZE);
            int roomCount = Random.Range(MIN_ROOMS, MAX_ROOMS);

            addRoom(startPos, new RoomInfo(RoomInfo.RoomTypes.Start, startPos));

            while (rooms.Count < roomCount)
            {
                var randRoom  = rooms[Random.Range(0, rooms.Count)];
                var randDir   = GetRandomDir();
                var targetPos = randRoom.Position + randDir;
                if (IsInBounds(targetPos.x, targetPos.y) && roomLayout[targetPos.x, targetPos.y] == null)
                {
                    addRoom(targetPos, new RoomInfo(RoomInfo.RoomTypes.Normal, targetPos));
                }
            }

            foreach (var room in rooms)
            {
                room.HasConnectionRight = isRoomPresent(room.Position.x + 1, room.Position.y);
                room.HasConnectionTop   = isRoomPresent(room.Position.x, room.Position.y + 1);
                room.HasConnectionLeft  = isRoomPresent(room.Position.x - 1, room.Position.y);
                room.HasConnectionDown  = isRoomPresent(room.Position.x, room.Position.y - 1);
            }

            // Calculate dists
            var frontier  = new Queue <RoomInfo>();
            var startRoom = rooms[0];

            startRoom.DistFromStart = -1;
            frontier.Enqueue(startRoom);

            System.Action <RoomInfo, int> enqueNext = (potentialRoom, currDist) =>
            {
                if (potentialRoom.DistFromStart != 0)
                {
                    return;
                }
                potentialRoom.DistFromStart = currDist + 1;
                frontier.Enqueue(potentialRoom);
            };

            RoomInfo curr = null;

            while (frontier.Count > 0)
            {
                curr = frontier.Dequeue();
                if (curr.HasConnectionRight)
                {
                    enqueNext(roomLayout[curr.Position.x + 1, curr.Position.y], curr.DistFromStart);
                }
                if (curr.HasConnectionTop)
                {
                    enqueNext(roomLayout[curr.Position.x, curr.Position.y + 1], curr.DistFromStart);
                }
                if (curr.HasConnectionLeft)
                {
                    enqueNext(roomLayout[curr.Position.x - 1, curr.Position.y], curr.DistFromStart);
                }
                if (curr.HasConnectionDown)
                {
                    enqueNext(roomLayout[curr.Position.x, curr.Position.y - 1], curr.DistFromStart);
                }
            }

            startRoom.DistFromStart = 0;
            curr.RoomType           = RoomInfo.RoomTypes.Finish;

            return(rooms);
        }
예제 #2
0
 public DetailedRoomInfo(RoomInfo roomInfo, int width, int height)
 {
     RoomInfo   = roomInfo;
     RoomLayout = new LevelTile[width, height];
     Spawns     = new List <Vector2Int>();
 }