示例#1
0
    public TileBase[,] BuildCorridor(Vector2Int corridorStart, Vector2Int corridorEnd, Dir dir)
    {
        Dictionary <string, TileBase> tileDict = TileLoader.LoadCorridor("Color", 1);

        TileBase[,] corridor;
        bool hor = false;

        switch (dir)
        {
        case Dir.LEFT:
        case Dir.RIGHT:
            corridor = new TileBase[Math.Abs(corridorEnd.x - corridorStart.x), 2 + corridorWidth];
            hor      = true;
            break;

        case Dir.UP:
        case Dir.DOWN:
            corridor = new TileBase[2 + corridorWidth, Math.Abs(corridorEnd.y - corridorStart.y)];
            hor      = false;
            break;

        default:
            corridor = new TileBase[0, 0];
            break;
        }

        int width  = corridor.GetLength(0);
        int height = corridor.GetLength(1);

        if (hor)
        {
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < 2 + corridorWidth; y++)
                {
                    if (x == 0)
                    {
                        if (y == 0)
                        {
                            corridor[x, y] = tileDict["horBotLeft"];
                        }
                        else if (y == 1 + corridorWidth)
                        {
                            corridor[x, y] = tileDict["horTopLeft"];
                        }
                    }
                    else if (x == width - 1)
                    {
                        if (y == 0)
                        {
                            corridor[x, y] = tileDict["horBotRight"];
                        }
                        else if (y == 1 + corridorWidth)
                        {
                            corridor[x, y] = tileDict["horTopRight"];
                        }
                    }
                    else
                    {
                        if (y == 0)
                        {
                            corridor[x, y] = tileDict["top"];
                        }
                        else if (y == 1 + corridorWidth)
                        {
                            corridor[x, y] = tileDict["bot"];
                        }
                    }
                }
            }
        }
        else
        {
            for (int x = 0; x < 2 + corridorWidth; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    if (y == 0)
                    {
                        if (x == 0)
                        {
                            corridor[x, y] = tileDict["vertBotLeft"];
                        }
                        else if (x == 1 + corridorWidth)
                        {
                            corridor[x, y] = tileDict["vertBotRight"];
                        }
                    }
                    else if (y == height - 1)
                    {
                        if (x == 0)
                        {
                            corridor[x, y] = tileDict["vertTopLeft"];
                        }
                        else if (x == 1 + corridorWidth)
                        {
                            corridor[x, y] = tileDict["vertTopRight"];
                        }
                    }
                    else
                    {
                        if (x == 0)
                        {
                            corridor[x, y] = tileDict["right"];
                        }
                        else if (x == 1 + corridorWidth)
                        {
                            corridor[x, y] = tileDict["left"];
                        }
                    }
                }
            }
        }


        return(corridor);
    }
示例#2
0
    public TileBase[,] GenBigRoom(TileBase[,] roomTiles, Vector2Int pos, Dir dir)
    {
        // ROOM GEN
        int  subRoomWidth  = random.Next(roomSize.x, roomSize.y);
        int  subRoomHeight = random.Next(roomSize.x, roomSize.y);
        Rect subRoomRect   = findRoomRect(pos, subRoomWidth, subRoomHeight, dir);

        // Room overlaps with existing room
        if (checkRoomCollision(subRoomRect))
        {
            return(new TileBase[0, 0]);
        }

        Rect bigRoomRect = new Rect(0, 0, maxSize.x, maxSize.y);

        // Room is out of bounds
        if (!(RectContains(bigRoomRect, subRoomRect)))
        {
            return(new TileBase[0, 0]);
        }

        // Add new room
        rooms.Add(subRoomRect);
        if (tempCorridor.xMax != 0 || tempCorridor.yMax != 0)
        {
            corridors.Add(tempCorridor);
        }


        TileBase[,] subRoomTiles = BuildRoom(subRoomWidth, subRoomHeight);
        ArrayUtils.Merge2DArrays(roomTiles, subRoomTiles,
                                 new Vector2Int((int)subRoomRect.xMin, (int)subRoomRect.yMin));

        // Terminate if max room count reached
        if (rooms.Count > roomCount.y)
        {
            return(roomTiles);
        }

        // CORRIDOR GEN

        // Select new dir (can't be opposite of previous)
        Dir[] dirs;
        switch (dir)
        {
        case Dir.LEFT: dirs = new Dir[3] {
                Dir.LEFT, Dir.UP, Dir.DOWN
        }; break;

        case Dir.RIGHT: dirs = new Dir[3] {
                Dir.UP, Dir.DOWN, Dir.RIGHT
        }; break;

        case Dir.UP: dirs = new Dir[3] {
                Dir.LEFT, Dir.RIGHT, Dir.UP
        }; break;

        case Dir.DOWN: dirs = new Dir[3] {
                Dir.LEFT, Dir.RIGHT, Dir.DOWN
        }; break;

        default: dirs = new Dir[3]; break;
        }
        Stack <Dir> shuffledDirs = new Stack <Dir>(dirs.OrderBy(x => random.Next()).ToArray());

        // Try dirs until something works. If nothing works, ¯\_(ツ)_/¯
        TileBase[,] recursedTiles = new TileBase[0, 0];
        while (shuffledDirs.Count > 0)
        {
            Dir newDir = shuffledDirs.Pop();

            // Find corridorStart (center of exit wall)
            Vector2Int corridorStart;
            switch (newDir)
            {
            case Dir.LEFT: corridorStart =
                new Vector2Int((int)subRoomRect.xMin + 1, (int)(subRoomRect.yMin + subRoomHeight / 2) - 1);
                break;

            case Dir.RIGHT: corridorStart =
                new Vector2Int((int)subRoomRect.xMax - 1, (int)(subRoomRect.yMin + subRoomHeight / 2) - 1);
                break;

            case Dir.UP: corridorStart =
                new Vector2Int((int)(subRoomRect.xMin + subRoomWidth / 2) - 1, (int)(subRoomRect.yMax - 1));
                break;

            case Dir.DOWN: corridorStart =
                new Vector2Int((int)(subRoomRect.xMin + subRoomWidth / 2) - 1, (int)(subRoomRect.yMin + 1));
                break;

            default: corridorStart = Vector2Int.zero; break;
            }

            // Find corridorEnd
            int        corridorTileLength = random.Next(corridorLength.x, corridorLength.y);
            Vector2Int corridorEnd        = corridorStart + directions[newDir] * corridorTileLength;

            // FIXME: We build the corridor early to construct the rect for collision detection
            // Rect construction should be decoupled from buildCorridor
            TileBase[,] corridorTiles = BuildCorridor(corridorStart, corridorEnd, newDir);
            switch (newDir)
            {
            case Dir.LEFT:
            case Dir.DOWN:
                tempCorridor = new Rect(corridorEnd.x, corridorEnd.y, corridorTiles.GetLength(0), corridorTiles.GetLength(1));
                break;

            case Dir.RIGHT:
            case Dir.UP:
                tempCorridor = new Rect(corridorStart.x, corridorStart.y, corridorTiles.GetLength(0), corridorTiles.GetLength(1));
                break;

            default: tempCorridor = Rect.zero; break;
            }

            if (checkCorridorCollision(tempCorridor))
            {
                continue;
            }

            // Recurse (attempt to place room at corridor end)
            recursedTiles = GenBigRoom((TileBase[, ])roomTiles.Clone(), corridorEnd - directions[newDir], newDir);

            // Recursion was unable to place room: try another direction
            if (recursedTiles.GetLength(0) == 0)
            {
                continue;
            }
            ;

            // Recursion succeeded, stop trying directions
            // Merge in recursed rooms & corridors
            ArrayUtils.Merge2DArrays(roomTiles, recursedTiles, Vector2Int.zero);

            switch (newDir)
            {
            case Dir.LEFT:
            case Dir.DOWN:
                ArrayUtils.Merge2DArrays(roomTiles, corridorTiles, corridorEnd, true);
                break;

            case Dir.RIGHT:
            case Dir.UP:
                ArrayUtils.Merge2DArrays(roomTiles, corridorTiles, corridorStart, true);
                break;
            }

            break;
        }

        return(roomTiles);
    }