Ejemplo n.º 1
0
    public virtual void generateCombinedRoomModeLevel()
    {
        float totalRoomWidth  = Tile.TILE_SIZE * ROOM_WIDTH;
        float totalRoomHeight = Tile.TILE_SIZE * ROOM_HEIGHT;

        Room[,] roomGrid = new Room[numXRooms, numYRooms];

        GameObject borderObjects = new GameObject("border_objects");

        borderObjects.transform.parent        = GameManager.instance.transform;
        borderObjects.transform.localPosition = Vector3.zero;

        int         currentRoomX = Random.Range(0, numXRooms);
        int         currentRoomY = 0;
        List <Room> criticalPath = new List <Room>();


        Dir[] possibleDirsToPath = new Dir[] { Dir.Left, Dir.Left, Dir.Right, Dir.Right, Dir.Up };
        Dir   currentDir         = GlobalFuncs.randElem(possibleDirsToPath);
        Dir   entranceDir        = oppositeDir(currentDir);
        // Keep going in our current direction until we hit a will
        bool       makingCriticalPath = true;
        GameObject roomToSpawn        = startRoomPrefab;

        // This is based on Spelunky's method of building a critical path.
        // This code is kind of a mess and could likely be easily improved.=
        while (makingCriticalPath)
        {
            // Let's figure out what our required exits are going to be.
            Dir exitDir   = Dir.Up;
            int nextRoomX = currentRoomX;
            int nextRoomY = currentRoomY;
            if (currentDir == Dir.Up)
            {
                if (currentRoomY >= numYRooms - 1)
                {
                    makingCriticalPath = false;
                }
                else
                {
                    exitDir    = Dir.Up;
                    currentDir = GlobalFuncs.randElem(new Dir[] { Dir.Left, Dir.Right });
                    nextRoomY++;
                }
            }
            else if (currentDir == Dir.Left)
            {
                if (currentRoomX <= 0)
                {
                    if (currentRoomY >= numYRooms - 1)
                    {
                        makingCriticalPath = false;
                    }
                    else
                    {
                        exitDir    = Dir.Up;
                        currentDir = Dir.Right;
                        nextRoomY++;
                    }
                }
                else
                {
                    // Move on if we randomly choose to
                    if (Random.Range(0, 5) == 0)
                    {
                        if (currentRoomY >= numYRooms - 1)
                        {
                            makingCriticalPath = false;
                        }
                        else
                        {
                            exitDir = Dir.Up;
                            nextRoomY++;
                        }
                    }
                    else
                    {
                        exitDir = Dir.Left;
                        nextRoomX--;
                    }
                }
            }
            else if (currentDir == Dir.Right)
            {
                if (currentRoomX >= numXRooms - 1)
                {
                    if (currentRoomY >= numYRooms - 1)
                    {
                        makingCriticalPath = false;
                    }
                    else
                    {
                        exitDir    = Dir.Up;
                        currentDir = Dir.Left;
                        nextRoomY++;
                    }
                }
                else
                {
                    if (Random.Range(0, 5) == 0)
                    {
                        if (currentRoomY >= numYRooms - 1)
                        {
                            makingCriticalPath = false;
                        }
                        else
                        {
                            exitDir = Dir.Up;
                            nextRoomY++;
                        }
                    }
                    else
                    {
                        exitDir = Dir.Right;
                        nextRoomX++;
                    }
                }
            }


            if (!makingCriticalPath)
            {
                roomToSpawn = exitRoomPrefab;
            }

            Room           room          = null;
            ExitConstraint requiredExits = new ExitConstraint();
            if (roomToSpawn == startRoomPrefab)
            {
                requiredExits.addDirConstraint(exitDir);
                room = Room.generateRoom(roomToSpawn, this, currentRoomX, currentRoomY, requiredExits);
                GameManager.instance.currentRoom = room;
            }
            else if (!makingCriticalPath)
            {
                requiredExits.addDirConstraint(entranceDir);
                room = Room.generateRoom(roomToSpawn, this, currentRoomX, currentRoomY, requiredExits);
            }
            else
            {
                requiredExits.addDirConstraint(entranceDir);
                requiredExits.addDirConstraint(exitDir);
                room = Room.generateRoom(roomToSpawn, this, currentRoomX, currentRoomY, requiredExits);
            }

            roomGrid[currentRoomX, currentRoomY] = room;
            criticalPath.Add(room);
            currentRoomX = nextRoomX;
            currentRoomY = nextRoomY;
            entranceDir  = oppositeDir(exitDir);
            roomToSpawn  = nextRoomToSpawn();
        }

        for (int x = 0; x < numXRooms; x++)
        {
            for (int y = 0; y < numYRooms; y++)
            {
                if (roomGrid[x, y] == null)
                {
                    roomGrid[x, y] = Room.generateRoom(nextRoomToSpawn(), this, x, y, ExitConstraint.None);
                }
                float roomLeftX   = totalRoomWidth * x - Tile.TILE_SIZE / 2;
                float roomRightX  = totalRoomWidth * (x + 1) + Tile.TILE_SIZE / 2;
                float roomBottomY = totalRoomHeight * y - Tile.TILE_SIZE / 2;
                float roomTopY    = totalRoomHeight * (y + 1) + Tile.TILE_SIZE / 2;

                if (x == 0 && y == 0)
                {
                    Vector2 bottomLeftWallGrid = Tile.toGridCoord(roomLeftX, roomBottomY);
                    spawnTileOutsideRoom(indestructibleWallPrefab, borderObjects.transform, (int)bottomLeftWallGrid.x, (int)bottomLeftWallGrid.y);
                }
                if (x == 0 && y == numYRooms - 1)
                {
                    Vector2 topLeftWallGrid = Tile.toGridCoord(roomLeftX, roomTopY);
                    spawnTileOutsideRoom(indestructibleWallPrefab, borderObjects.transform, (int)topLeftWallGrid.x, (int)topLeftWallGrid.y);
                }
                if (x == numXRooms - 1 && y == numYRooms - 1)
                {
                    Vector2 topRightWallGrid = Tile.toGridCoord(roomRightX, roomTopY);
                    spawnTileOutsideRoom(indestructibleWallPrefab, borderObjects.transform, (int)topRightWallGrid.x, (int)topRightWallGrid.y);
                }
                if (x == numXRooms - 1 && y == 0)
                {
                    Vector2 bottomRightWallGrid = Tile.toGridCoord(roomRightX, roomBottomY);
                    spawnTileOutsideRoom(indestructibleWallPrefab, borderObjects.transform, (int)bottomRightWallGrid.x, (int)bottomRightWallGrid.y);
                }

                if (x == 0)
                {
                    GameObject wallObj = Instantiate(verticalBorderWallPrefab) as GameObject;
                    wallObj.transform.parent   = borderObjects.transform;
                    wallObj.transform.position = new Vector3(roomLeftX, (roomTopY + roomBottomY) / 2f, 0);
                }
                if (x == numXRooms - 1)
                {
                    GameObject wallObj = Instantiate(verticalBorderWallPrefab) as GameObject;
                    wallObj.transform.parent   = borderObjects.transform;
                    wallObj.transform.position = new Vector3(roomRightX, (roomTopY + roomBottomY) / 2f, 0);
                }
                if (y == 0)
                {
                    GameObject wallObj = Instantiate(horizontalBorderWallPrefab) as GameObject;
                    wallObj.transform.parent   = borderObjects.transform;
                    wallObj.transform.position = new Vector3((roomLeftX + roomRightX) / 2f, roomBottomY, 0);
                }
                if (y == numYRooms - 1)
                {
                    GameObject wallObj = Instantiate(horizontalBorderWallPrefab) as GameObject;
                    wallObj.transform.parent   = borderObjects.transform;
                    wallObj.transform.position = new Vector3((roomLeftX + roomRightX) / 2f, roomTopY, 0);
                }
            }
        }


        GameManager.instance.roomGrid      = roomGrid;
        GameManager.instance.borderObjects = borderObjects;

        // Now as a final step, if we're doing chaos mode, we need to randomly rearrange all spawned tiles (that aren't walls, players, or exits)
        if (GameManager.gameMode == GameManager.GameMode.Chaos)
        {
            List <Tile> tilesToRearrange = new List <Tile>();
            // Go through each room looking for tiles.
            for (int x = 0; x < numXRooms; x++)
            {
                for (int y = 0; y < numYRooms; y++)
                {
                    Room room = roomGrid[x, y];
                    foreach (Tile tile in room.GetComponentsInChildren <Tile>(true))
                    {
                        if (tile.hasTag(TileTags.Player | TileTags.Wall | TileTags.Exit))
                        {
                            continue;
                        }
                        tilesToRearrange.Add(tile);
                    }
                }
            }

            // Now we have a list of tiles, let's randomly shuffle their locations.
            for (int i = 0; i < tilesToRearrange.Count * 4; i++)
            {
                Tile tile1 = GlobalFuncs.randElem(tilesToRearrange);
                Tile tile2 = GlobalFuncs.randElem(tilesToRearrange);

                Transform tile1OldParent   = tile1.transform.parent;
                Vector2   tile1OldPosition = tile1.transform.localPosition;

                tile1.transform.parent        = tile2.transform.parent;
                tile1.transform.localPosition = new Vector3(tile2.transform.localPosition.x, tile2.transform.localPosition.y, tile1.transform.localPosition.z);

                tile2.transform.parent        = tile1OldParent;
                tile2.transform.localPosition = new Vector3(tile1OldPosition.x, tile1OldPosition.y, tile2.transform.localPosition.z);
            }
        }
    }
Ejemplo n.º 2
0
    public virtual void generateSingleRoomModeLevel()
    {
        // We add 2 to the tile width/height here to make room for the padding areas.
        float totalRoomWidth  = (Tile.TILE_SIZE) * (ROOM_WIDTH + 1);
        float totalRoomHeight = (Tile.TILE_SIZE) * (ROOM_HEIGHT + 1);

        Room[,] roomGrid = new Room[numXRooms, numYRooms];

        GameObject borderObjects = new GameObject("border_objects");

        borderObjects.transform.parent        = GameManager.instance.transform;
        borderObjects.transform.localPosition = Vector3.zero;

        int         currentRoomX = Random.Range(0, numXRooms);
        int         currentRoomY = 0;
        List <Room> criticalPath = new List <Room>();


        Dir[] possibleDirsToPath = new Dir[] { Dir.Left, Dir.Left, Dir.Right, Dir.Right, Dir.Up };
        Dir   currentDir         = GlobalFuncs.randElem(possibleDirsToPath);
        Dir   entranceDir        = oppositeDir(currentDir);
        // Keep going in our current direction until we hit a will
        bool       makingCriticalPath = true;
        GameObject roomToSpawn        = startRoomPrefab;

        while (makingCriticalPath)
        {
            // Let's figure out what our required exits are going to be.
            Dir exitDir   = Dir.Up;
            int nextRoomX = currentRoomX;
            int nextRoomY = currentRoomY;
            if (currentDir == Dir.Up)
            {
                if (currentRoomY >= numYRooms - 1)
                {
                    makingCriticalPath = false;
                }
                else
                {
                    exitDir    = Dir.Up;
                    currentDir = GlobalFuncs.randElem(new Dir[] { Dir.Left, Dir.Right });
                    nextRoomY++;
                }
            }
            else if (currentDir == Dir.Left)
            {
                if (currentRoomX <= 0)
                {
                    if (currentRoomY >= numYRooms - 1)
                    {
                        makingCriticalPath = false;
                    }
                    else
                    {
                        exitDir    = Dir.Up;
                        currentDir = Dir.Right;
                        nextRoomY++;
                    }
                }
                else
                {
                    // Move on if we randomly choose to
                    if (Random.Range(0, 4) == 0)
                    {
                        if (currentRoomY >= numYRooms - 1)
                        {
                            makingCriticalPath = false;
                        }
                        else
                        {
                            exitDir = Dir.Up;
                            nextRoomY++;
                        }
                    }
                    else
                    {
                        exitDir = Dir.Left;
                        nextRoomX--;
                    }
                }
            }
            else if (currentDir == Dir.Right)
            {
                if (currentRoomX >= numXRooms - 1)
                {
                    if (currentRoomY >= numYRooms - 1)
                    {
                        makingCriticalPath = false;
                    }
                    else
                    {
                        exitDir    = Dir.Up;
                        currentDir = Dir.Left;
                        nextRoomY++;
                    }
                }
                else
                {
                    if (Random.Range(0, 4) == 0)
                    {
                        if (currentRoomY >= numYRooms - 1)
                        {
                            makingCriticalPath = false;
                        }
                        else
                        {
                            exitDir = Dir.Up;
                            nextRoomY++;
                        }
                    }
                    else
                    {
                        exitDir = Dir.Right;
                        nextRoomX++;
                    }
                }
            }


            if (!makingCriticalPath)
            {
                roomToSpawn = exitRoomPrefab;
            }

            Room           room          = null;
            ExitConstraint requiredExits = new ExitConstraint();
            if (roomToSpawn == startRoomPrefab)
            {
                requiredExits.addDirConstraint(exitDir);
                room = Room.generateRoom(roomToSpawn, this, currentRoomX, currentRoomY, requiredExits);
                GameManager.instance.currentRoom = room;
            }
            else if (!makingCriticalPath)
            {
                requiredExits.addDirConstraint(entranceDir);
                room = Room.generateRoom(roomToSpawn, this, currentRoomX, currentRoomY, requiredExits);
            }
            else
            {
                requiredExits.addDirConstraint(entranceDir);
                requiredExits.addDirConstraint(exitDir);
                room = Room.generateRoom(roomToSpawn, this, currentRoomX, currentRoomY, requiredExits);
            }


            roomGrid[currentRoomX, currentRoomY] = room;
            criticalPath.Add(room);
            currentRoomX = nextRoomX;
            currentRoomY = nextRoomY;
            entranceDir  = oppositeDir(exitDir);
            roomToSpawn  = nextRoomToSpawn();
        }

        for (int x = 0; x < numXRooms; x++)
        {
            for (int y = 0; y < numYRooms; y++)
            {
                if (roomGrid[x, y] == null)
                {
                    roomGrid[x, y] = Room.generateRoom(nextRoomToSpawn(), this, x, y, ExitConstraint.None);
                }
                if (roomGrid[x, y] != GameManager.instance.currentRoom)
                {
                    roomGrid[x, y].gameObject.SetActive(false);
                }
                float roomLeftX   = totalRoomWidth * x - Tile.TILE_SIZE / 2;
                float roomRightX  = totalRoomWidth * (x + 1) - Tile.TILE_SIZE / 2;
                float roomBottomY = totalRoomHeight * y - Tile.TILE_SIZE / 2;
                float roomTopY    = totalRoomHeight * (y + 1) - Tile.TILE_SIZE / 2;

                // Always spawn a lower left wall.
                Vector2 bottomLeftWallGrid = Tile.toGridCoord(roomLeftX, roomBottomY);
                spawnTileOutsideRoom(indestructibleWallPrefab, borderObjects.transform, (int)bottomLeftWallGrid.x, (int)bottomLeftWallGrid.y);
                if (y == numYRooms - 1)
                {
                    // Spawn an upper left wall if we're at the top
                    Vector2 topLeftWallGrid = Tile.toGridCoord(roomLeftX, roomTopY);
                    spawnTileOutsideRoom(indestructibleWallPrefab, borderObjects.transform, (int)topLeftWallGrid.x, (int)topLeftWallGrid.y);
                }
                if (x == numXRooms - 1)
                {
                    // Spawn a lower right wall if we're at the right
                    Vector2 bottomRightWallGrid = Tile.toGridCoord(roomRightX, roomBottomY);
                    spawnTileOutsideRoom(indestructibleWallPrefab, borderObjects.transform, (int)bottomRightWallGrid.x, (int)bottomRightWallGrid.y);
                }
                if (x == numXRooms - 1 && y == numYRooms - 1)
                {
                    // Spawn an upper right wall only if we're the upper right corner
                    Vector2 topRightWallGrid = Tile.toGridCoord(roomRightX, roomTopY);
                    spawnTileOutsideRoom(indestructibleWallPrefab, borderObjects.transform, (int)topRightWallGrid.x, (int)topRightWallGrid.y);
                }

                // Now spawn the walls and the transitions objects.
                if (x > 0)
                {
                    GameObject transitionObj = Instantiate(verticalTransitionPrefab) as GameObject;
                    transitionObj.transform.parent   = borderObjects.transform;
                    transitionObj.transform.position = new Vector3(roomLeftX, (roomBottomY + roomTopY) / 2f, 0);
                }
                else
                {
                    GameObject wallObj = Instantiate(verticalBorderWallPrefab) as GameObject;
                    wallObj.transform.parent   = borderObjects.transform;
                    wallObj.transform.position = new Vector3(roomLeftX, (roomTopY + roomBottomY) / 2f, 0);
                }
                if (x == numXRooms - 1)
                {
                    GameObject wallObj = Instantiate(verticalBorderWallPrefab) as GameObject;
                    wallObj.transform.parent   = borderObjects.transform;
                    wallObj.transform.position = new Vector3(roomRightX, (roomTopY + roomBottomY) / 2f, 0);
                }

                if (y > 0)
                {
                    GameObject transitionObj = Instantiate(horizontalTransitionPrefab) as GameObject;
                    transitionObj.transform.parent   = borderObjects.transform;
                    transitionObj.transform.position = new Vector3((roomLeftX + roomRightX) / 2f, roomBottomY, 0);
                }
                else
                {
                    GameObject wallObj = Instantiate(horizontalBorderWallPrefab) as GameObject;
                    wallObj.transform.parent   = borderObjects.transform;
                    wallObj.transform.position = new Vector3((roomLeftX + roomRightX) / 2f, roomBottomY, 0);
                }
                if (y == numYRooms - 1)
                {
                    GameObject wallObj = Instantiate(horizontalBorderWallPrefab) as GameObject;
                    wallObj.transform.parent   = borderObjects.transform;
                    wallObj.transform.position = new Vector3((roomLeftX + roomRightX) / 2f, roomTopY, 0);
                }
            }
        }

        GameManager.instance.roomGrid      = roomGrid;
        GameManager.instance.borderObjects = borderObjects;


        // Finally, activate the letterbox
        float letterBoxTop    = ((ROOM_HEIGHT + 2) * Tile.TILE_SIZE) / 2 + Tile.TILE_SIZE / 2f;
        float letterBoxBottom = -((ROOM_HEIGHT + 2) * Tile.TILE_SIZE) / 2 + Tile.TILE_SIZE / 2f;
        float letterBoxRight  = ((ROOM_WIDTH + 2) * Tile.TILE_SIZE) / 2;
        float letterBoxLeft   = -letterBoxRight;

        GameManager.instance.letterBox.activateLetterBox(letterBoxTop, letterBoxRight, letterBoxBottom, letterBoxLeft);
    }