Пример #1
0
    IEnumerator RenderDungeon()
    {
        tiles.DisableAll();

        for (int x = 0; x < dungeonWidth; x++)
        {
            for (int y = 0; y < dungeonHeight; y++)
            {
                if (dungeon[x, y] == 2)
                {
                    dungeon[x, y] = 0;
                }
                if (dungeon[x, y] == 1)
                {
                    ObjectPool.PooledObject tile = tiles.GetObjectFromPool;
                    tile.SetActive(true);
                    tile.scale    = Vector3.one;
                    tile.position = new Vector3(
                        x - (dungeonWidth / 2) + (tile.scale.x / 2),
                        y - (dungeonHeight / 2) + (tile.scale.y / 2)
                        );
                }
            }
            yield return(null);
        }
    }
Пример #2
0
    IEnumerator GenerateDungeon()
    {
        if (dungeonHeight % 2 == 0)
        {
            throw new System.FormatException("dungeonHeight should be an odd number");
        }
        if (dungeonWidth % 2 == 0)
        {
            throw new System.FormatException("roomMaxDimension should be an odd number");
        }
        if (roomMinDimension % 2 == 0)
        {
            throw new System.FormatException("roomMinDimension should be an odd number");
        }
        if (roomMaxDimension % 2 == 0)
        {
            throw new System.FormatException("roomMaxDimension should be an odd number");
        }
        if (tileSize % 2 == 0)
        {
            throw new System.FormatException("tileSize should be an odd number");
        }

        isGenerating       = true;
        retryCount         = 0;
        dungeonRect        = Rect.zero;
        dungeonRect.height = dungeonHeight - 2; // minus 2 to give a 1 unit edge padding around the whole dungeon
        dungeonRect.width  = dungeonWidth - 2;  // minus 2 to give a 1 unit edge padding around the whole dungeon
        dungeonRect.center = transform.position;
        if (tiles != null)
        {
            tiles.ClearPool();
        }

        Camera.main.orthographicSize = Mathf.Max(dungeonWidth / 2, dungeonHeight / 2) + 2;
        dungeon = new IntGrid(dungeonWidth, dungeonHeight);
        tiles   = new ObjectPool(roomPrefab, dungeonWidth * dungeonHeight, false, false, transform);

        // make retryAttempts attempts to place rooms randomly within the dungeon
        while (retryCount < retryAttempts)
        {
            Vector2 randomPosition = new Vector2(ClampValueToOddNumber(Random.Range(0, dungeonWidth) - dungeonWidth / 2f), ClampValueToOddNumber(Random.Range(0, dungeonHeight) - dungeonHeight / 2f));
            Vector2 randomScale    = new Vector2(ClampValueToOddNumber(Random.Range(roomMinDimension, roomMaxDimension)), ClampValueToOddNumber(Random.Range(roomMinDimension, roomMaxDimension)));

            Collider2D overlapBox = Physics2D.OverlapBox(randomPosition, randomScale + (Vector2.one * minDistanceBetweenRooms * 2), 0f);
            if (overlapBox == null && IsRoomInBounds(randomPosition, randomScale))
            {
                ObjectPool.PooledObject room = tiles.GetObjectFromPool;
                room.SetActive(true);
                room.position = randomPosition;
                room.scale    = randomScale;
                yield return(new WaitForSeconds(0.1f));
            }
            else
            {
                retryCount++;
            }
        }

        // carve out the rooms from the array of cells and disable the rooms in the pool
        foreach (KeyValuePair <string, ObjectPool.PooledObject> entry in tiles.GetObjectPool)
        {
            if (entry.Value.activeInHierarchy)
            {
                Vector3    roomPositionOffset = new Vector3(dungeonWidth / 2f, dungeonHeight / 2f);
                GameObject room  = entry.Value.gameObject;
                Vector3    scale = room.transform.localScale;
                for (float x = -scale.x / 2; x <= scale.x / 2; x++)
                {
                    for (float y = -scale.y / 2; y <= scale.y / 2; y++)
                    {
                        Point point = new Point((int)x, (int)y) + room.transform.position + roomPositionOffset;
                        dungeon[point.x, point.y] = 2;
                    }
                }

                tiles.Disable(entry.Key);
                yield return(null);
            }
        }

        // generate the maze in the empty space of the dungeon
        dungeon = new Maze(dungeon, true).mazeGrid;

        yield return(StartCoroutine(RenderDungeon()));

        yield return(StartCoroutine(StartFloodFill()));

        yield return(StartCoroutine(RenderDungeon()));

        yield return(StartCoroutine(RemoveDeadEnds()));

        yield return(StartCoroutine(RenderDungeon()));

        isGenerating = false;
    }