Ejemplo n.º 1
0
        IEnumerator GenerateDungeonAsync()
        {
            yield return(null);

            startTime = Time.realtimeSinceStartup;

            if (maxRoomPlaceAttempts < minRoomCount)
            {
                maxRoomPlaceAttempts = minRoomCount;
            }

            #region Clear existing tiles
            if (tiles != null)
            {
                for (int x = 0; x < tiles.GetLength(0); x++)
                {
                    for (int y = 0; y < tiles.GetLength(1); y++)
                    {
                        Destroy(tiles[x, y].gameObject);
                    }
                }
            }
            #endregion

            #region Generate new tiles with default values
            tiles = new Tile[width, height];
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    tiles[x, y] = Instantiate(tilePrefab, this.transform);
                    tiles[x, y].gameObject.name = string.Format("Tile({0}, {1})", x, y);
                    tiles[x, y].x           = x;
                    tiles[x, y].y           = y;
                    tiles[x, y].parentArray = tiles;
                }
            }
            #endregion

            #region Generate dungeon rooms
            rooms = new List <DungeonRoom>();

            // If min and max are swapped, swap them back
            if (minRoomSize > maxRoomSize)
            {
                int t = minRoomSize;
                minRoomSize = maxRoomSize;
                maxRoomSize = t;
            }

            #region Create random amount of rooms
            DungeonRoom temp;
            int         targetRoomCount = Random.Range(minRoomCount, maxRoomCount + 1);
            for (int r = 0; r < maxRoomPlaceAttempts; r++)
            {
                temp = DungeonRoom.GenerateNewRoom(minRoomSize, maxRoomSize, width, height);
                if (rooms.Count > 0)
                {
                    bool overlap = false;
                    for (int i = 0; i < rooms.Count; i++)
                    {
                        overlap |= DungeonRoom.OverlapCheck(rooms[i], temp);
                    }
                    if (overlap)
                    {
                        continue;
                    }
                }

                // Mark room tiles as such
                for (int x = temp.left; x <= temp.right; x++)
                {
                    for (int y = temp.bottom; y <= temp.top; y++)
                    {
                        tiles[x, y].availability = TileAvailability.Room;
                    }
                }

                rooms.Add(temp);
                if (rooms.Count >= targetRoomCount)
                {
                    break;
                }
            }
            #endregion

            foreach (DungeonRoom room in rooms)
            {
                yield return(StartCoroutine(SetupRoomTiles(room)));
            }
            #endregion

            #region Generate corridors using recursive backtracker, making sure to fill any islands
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    if (tiles[x, y].availability == TileAvailability.Empty)
                    {
                        yield return(StartCoroutine(RecursiveCorridorGenerator(x, y)));
                    }
                }
            }
            #endregion

            #region Mark all dead ends
            deadEnds = new List <Vector2Int>();
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    switch (tiles[x, y].corridors)
                    {
                    case Directions.North:
                    case Directions.East:
                    case Directions.South:
                    case Directions.West:
                        deadEnds.Add(new Vector2Int(x, y));
                        break;
                    }
                }
            }
            #endregion

            #region Use regresion to eliminate some of the dead ends
            #endregion

            #region Make entrances into rooms
            #endregion

            lastDungeonTime = Time.realtimeSinceStartup - startTime;
            timeText.text   = string.Format("Dungeon generated in {0:F3} seconds.", lastDungeonTime);

            dungeonCompleteCallback?.Invoke();

            isRunning = false;
        }
Ejemplo n.º 2
0
 public static bool OverlapCheck(DungeonRoom d1, DungeonRoom d2)
 {
     return(((d1.right >= d2.left) && (d1.left <= d2.right)) &&
            ((d1.top >= d2.bottom) && (d1.bottom <= d2.top)));
 }