コード例 #1
0
 public override void fillRoom(LevelGenerator ourGenerator, ExitConstraint requiredExits)
 {
     for (int x = 0; x < LevelGenerator.ROOM_WIDTH; x++)
     {
         for (int y = 0; y < LevelGenerator.ROOM_HEIGHT; y++)
         {
             // figure out if this location is at the edge of the room.
             bool isEdgeLocation = x == 0 ||
                                   y == 0 ||
                                   x == LevelGenerator.ROOM_WIDTH - 1 ||
                                   y == LevelGenerator.ROOM_HEIGHT - 1;
             if (!isEdgeLocation)
             {
                 if (Random.Range(0f, 1f) < .10f)
                 {
                     Tile.spawnTile(directTile, transform, x, y);
                 }
             }
             if (isEdgeLocation && !isExitLocation(x, y, requiredExits))
             {
                 Tile.spawnTile(ourGenerator.normalWallPrefab, transform, x, y);
             }
         }
     }
 }
コード例 #2
0
    public bool isExitLocation(int x, int y, ExitConstraint requiredExits)
    {
        int upExitX = LevelGenerator.ROOM_WIDTH / 2;
        int upExitY = LevelGenerator.ROOM_HEIGHT - 1;

        int rightExitX = LevelGenerator.ROOM_WIDTH - 1;
        int rightExitY = LevelGenerator.ROOM_HEIGHT / 2;

        int downExitX = LevelGenerator.ROOM_WIDTH / 2;
        int downExitY = 0;

        int leftExitX = 0;
        int leftExitY = LevelGenerator.ROOM_HEIGHT / 2;

        if (requiredExits.upExitRequired && x == upExitX && y == upExitY)
        {
            return(true);
        }
        if (requiredExits.rightExitRequired && x == rightExitX && y == rightExitY)
        {
            return(true);
        }
        if (requiredExits.downExitRequired && x == downExitX && y == downExitY)
        {
            return(true);
        }
        if (requiredExits.leftExitRequired && x == leftExitX && y == leftExitY)
        {
            return(true);
        }

        return(false);
    }
コード例 #3
0
    protected void generateWalls(LevelGenerator ourGenerator, ExitConstraint requiredExits)
    {
        // Basically we go over the border and determining where to spawn walls.
        bool[,] wallMap = new bool[LevelGenerator.ROOM_WIDTH, LevelGenerator.ROOM_HEIGHT];
        for (int x = 0; x < LevelGenerator.ROOM_WIDTH; x++)
        {
            for (int y = 0; y < LevelGenerator.ROOM_HEIGHT; y++)
            {
                if (x == 0 || x == LevelGenerator.ROOM_WIDTH - 1 ||
                    y == 0 || y == LevelGenerator.ROOM_HEIGHT - 1)
                {
                    if (x == LevelGenerator.ROOM_WIDTH / 2 &&
                        y == LevelGenerator.ROOM_HEIGHT - 1 &&
                        requiredExits.upExitRequired)
                    {
                        wallMap[x, y] = false;
                    }
                    else if (x == LevelGenerator.ROOM_WIDTH - 1 &&
                             y == LevelGenerator.ROOM_HEIGHT / 2 &&
                             requiredExits.rightExitRequired)
                    {
                        wallMap[x, y] = false;
                    }
                    else if (x == LevelGenerator.ROOM_WIDTH / 2 &&
                             y == 0 &&
                             requiredExits.downExitRequired)
                    {
                        wallMap[x, y] = false;
                    }
                    else if (x == 0 &&
                             y == LevelGenerator.ROOM_HEIGHT / 2 &&
                             requiredExits.leftExitRequired)
                    {
                        wallMap[x, y] = false;
                    }
                    else
                    {
                        wallMap[x, y] = Random.value <= borderWallProbability;
                    }
                    continue;
                }
                wallMap[x, y] = false;
            }
        }

        // Now actually spawn all the walls.
        for (int x = 0; x < LevelGenerator.ROOM_WIDTH; x++)
        {
            for (int y = 0; y < LevelGenerator.ROOM_HEIGHT; y++)
            {
                if (wallMap[x, y])
                {
                    Tile.spawnTile(ourGenerator.normalWallPrefab, transform, x, y);
                }
            }
        }
    }
コード例 #4
0
 public override void fillRoom(LevelGenerator ourGenerator, ExitConstraint requiredExits)
 {
     // It's very likely you'll want to do different generation methods depending on which required exits you receive
     // Here's an example of randomly choosing between two generation methods.
     if (Random.value <= 0.5f)
     {
         roomGenerationVersionOne(ourGenerator, requiredExits);
     }
     else
     {
         roomGenerationVersionTwo(ourGenerator, requiredExits);
     }
 }
コード例 #5
0
ファイル: Room.cs プロジェクト: williamchendev/StoneSoup
    // The fillRoom function is the one you'll need to override to fill your rooms.
    // It takes the LevelGenerator as a parameter so you have access to more global prefabs (like walls)
    // Additionaly, it takes an array of exits that need to exist (your room will have required exits if it's on the critical path).
    // For an exit to "exist", there can't be a wall in the center part of that edge of the room.

    // This implementation pulls a designed room out of a text file.
    public virtual void fillRoom(LevelGenerator ourGenerator, ExitConstraint requiredExits)
    {
        string initialGridString = designedRoomFile.text;

        string[] rows   = initialGridString.Trim().Split('\n');
        int      width  = rows[0].Trim().Split(',').Length;
        int      height = rows.Length;

        if (height != LevelGenerator.ROOM_HEIGHT)
        {
            throw new UnityException(string.Format("Error in room by {0}. Wrong height, Expected: {1}, Got: {2}", roomAuthor, LevelGenerator.ROOM_HEIGHT, height));
        }
        if (width != LevelGenerator.ROOM_WIDTH)
        {
            throw new UnityException(string.Format("Error in room by {0}. Wrong width, Expected: {1}, Got: {2}", roomAuthor, LevelGenerator.ROOM_WIDTH, width));
        }
        int[,] indexGrid = new int[width, height];
        for (int r = 0; r < height; r++)
        {
            string   row  = rows[height - r - 1];
            string[] cols = row.Trim().Split(',');
            for (int c = 0; c < width; c++)
            {
                indexGrid[c, r] = int.Parse(cols[c]);
            }
        }

        for (int i = 0; i < width; i++)
        {
            for (int j = 0; j < height; j++)
            {
                int tileIndex = indexGrid[i, j];
                if (tileIndex == 0)
                {
                    continue;                     // 0 is nothing.
                }
                GameObject tileToSpawn;
                if (tileIndex < LevelGenerator.LOCAL_START_INDEX)
                {
                    tileToSpawn = ourGenerator.globalTilePrefabs[tileIndex - 1];
                }
                else
                {
                    tileToSpawn = localTilePrefabs[tileIndex - LevelGenerator.LOCAL_START_INDEX];
                }
                Tile.spawnTile(tileToSpawn, transform, i, j);
            }
        }
    }
コード例 #6
0
 public bool obeysExitConstraints(ExitConstraint constraint)
 {
     if (constraint.upExitRequired && !has_up_exit)
     {
         return(false);
     }
     if (constraint.rightExitRequired && !has_right_exit)
     {
         return(false);
     }
     if (constraint.leftExitRequired && !has_left_exit)
     {
         return(false);
     }
     if (constraint.downExitRequired && !has_down_exit)
     {
         return(false);
     }
     if (constraint.upExitRequired && constraint.rightExitRequired && !has_up_right_path)
     {
         return(false);
     }
     if (constraint.upExitRequired && constraint.downExitRequired && !has_up_down_path)
     {
         return(false);
     }
     if (constraint.upExitRequired && constraint.leftExitRequired && !has_up_left_path)
     {
         return(false);
     }
     if (constraint.leftExitRequired && constraint.rightExitRequired && !has_left_right_path)
     {
         return(false);
     }
     if (constraint.downExitRequired && constraint.rightExitRequired && !has_down_right_path)
     {
         return(false);
     }
     if (constraint.downExitRequired && constraint.leftExitRequired && !has_down_left_path)
     {
         return(false);
     }
     return(true);
 }
コード例 #7
0
    public override void fillRoom(LevelGenerator ourGenerator, ExitConstraint requiredExits)
    {
        _wallMap = new bool[LevelGenerator.ROOM_WIDTH, LevelGenerator.ROOM_HEIGHT];
        for (int x = 0; x < LevelGenerator.ROOM_WIDTH; x++)
        {
            for (int y = 0; y < LevelGenerator.ROOM_HEIGHT; y++)
            {
                _wallMap[x, y] = false;
            }
        }

        List <Vector2> maybeWallPoints = new List <Vector2>(LevelGenerator.ROOM_WIDTH * LevelGenerator.ROOM_HEIGHT);

        int numWalls = Random.Range(minWalls, maxWalls + 1);

        for (int i = 0; i < numWalls; i++)
        {
            maybeWallPoints.Clear();

            for (int x = 0; x < LevelGenerator.ROOM_WIDTH; x++)
            {
                for (int y = 0; y < LevelGenerator.ROOM_HEIGHT; y++)
                {
                    if (!_wallMap[x, y])
                    {
                        maybeWallPoints.Add(new Vector2(x, y));
                    }
                }
            }

            GlobalFuncs.shuffle(maybeWallPoints);
            maybeWallPoints.Sort(compareWallPoints);

            Vector2 wallPoint = geometricPick(maybeWallPoints);

            Tile.spawnTile(ourGenerator.normalWallPrefab, transform, (int)wallPoint.x, (int)wallPoint.y);
            _wallMap[(int)wallPoint.x, (int)wallPoint.y] = true;
        }

        //saveRoomToFile();
    }
コード例 #8
0
    public override void fillRoom(LevelGenerator ourGenerator, ExitConstraint requiredExits)
    {
        base.fillRoom(ourGenerator, requiredExits);
        foreach (SearchVertex vertex in _closed)
        {
            // Only look at vertices that were dead ends and weren't neighboring the exits.
            if (!vertex.isDeadEnd)
            {
                continue;
            }

            bool closeToExit = false;
            foreach (Vector2Int exitPoint in requiredExits.requiredExitLocations())
            {
                int manDistanceToExit = (int)Mathf.Abs(exitPoint.x - vertex.gridPos.x) + (int)Mathf.Abs(exitPoint.y - vertex.gridPos.y);
                if (manDistanceToExit <= 1)
                {
                    closeToExit = true;
                    break;
                }
            }
            if (closeToExit)
            {
                continue;
            }

            // Spawn the arrow traps depending on if we're open to the left or the right.
            if (vertex.parent.gridPos.x < vertex.gridPos.x)
            {
                Tile.spawnTile(faceLeftArrowTrapPrefab, transform, (int)vertex.gridPos.x, (int)vertex.gridPos.y);
            }
            else if (vertex.parent.gridPos.x > vertex.gridPos.x)
            {
                Tile.spawnTile(faceRightArrowTrapPrefab, transform, (int)vertex.gridPos.x, (int)vertex.gridPos.y);
            }
        }
    }
コード例 #9
0
/*    void Start() {
 *      // Find all Texture2Ds that have 'co' in their filename, that are labelled with 'architecture' and are placed in 'MyAwesomeProps' folder
 *      mapChoices = Resources.LoadAll("Assets/Rooms/Editor", typeof(TextAsset));
 *
 *      foreach (Object roomOrient in mapChoices){
 *          gfg_validatedRoom oneOption = defaultRoomPrefab.GetComponent<gfg_validatedRoom>();
 *          oneOption.designedRoomFile = (TextAsset)roomOrient;
 *          roomOptions.Add(oneOption);
 *      }
 *  }*/
    public override Room createRoom(ExitConstraint requiredExits)
    {
        return(defaultRoomPrefab.GetComponent <Room>().createRoom(requiredExits));

        /*List<Room> roomsThatMeetConstraints = new List<Room>();
         *
         * foreach (GameObject roomPrefab in roomOptions){
         *  gfg_validatedRoom validatedRoom = roomPrefab.GetComponent<gfg_validatedRoom>();
         *  if (roomPrefab == null){
         *      throw new UnityException("tried to f**k up daddy");;
         *  }
         *  validatedRoom.validateRoom();
         *  if (validatedRoom.obeysExitConstraints(requiredExits)){{
         *      roomsThatMeetConstraints.Add(validatedRoom);
         *  }}
         * }
         *
         * if (roomsThatMeetConstraints.Count <= 0){
         *  return defaultRoomPrefab.GetComponent<Room>().createRoom(requiredExits);
         * }
         *
         * Room roomToCreate = GlobalFuncs.randElem(roomsThatMeetConstraints);
         * return roomToCreate.createRoom(requiredExits);*/
    }
コード例 #10
0
    public override Room createRoom(ExitConstraint requiredExits)
    {
        // We're going to choose a room based on which ones appear to fit the requirements.
        _validRooms.Clear();

        foreach (GameObject roomPrefab in roomChoices)
        {
            apt283SearchRoom searchRoom = roomPrefab.GetComponent <apt283SearchRoom>();

            if (requiredExits.upExitRequired && !searchRoom.doesEntranceExist(Dir.Up))
            {
                continue;
            }
            if (requiredExits.rightExitRequired && !searchRoom.doesEntranceExist(Dir.Right))
            {
                continue;
            }
            if (requiredExits.downExitRequired && !searchRoom.doesEntranceExist(Dir.Down))
            {
                continue;
            }
            if (requiredExits.leftExitRequired && !searchRoom.doesEntranceExist(Dir.Left))
            {
                continue;
            }

            if (requiredExits.upExitRequired &&
                requiredExits.rightExitRequired &&
                !searchRoom.doesPathExist(Dir.Up, Dir.Right))
            {
                continue;
            }
            if (requiredExits.upExitRequired &&
                requiredExits.downExitRequired &&
                !searchRoom.doesPathExist(Dir.Up, Dir.Down))
            {
                continue;
            }
            if (requiredExits.upExitRequired &&
                requiredExits.leftExitRequired &&
                !searchRoom.doesPathExist(Dir.Up, Dir.Left))
            {
                continue;
            }
            if (requiredExits.rightExitRequired &&
                requiredExits.downExitRequired &&
                !searchRoom.doesPathExist(Dir.Right, Dir.Down))
            {
                continue;
            }
            if (requiredExits.rightExitRequired &&
                requiredExits.leftExitRequired &&
                !searchRoom.doesPathExist(Dir.Right, Dir.Down))
            {
                continue;
            }
            if (requiredExits.downExitRequired &&
                requiredExits.leftExitRequired &&
                !searchRoom.doesPathExist(Dir.Down, Dir.Left))
            {
                continue;
            }

            _validRooms.Add(searchRoom);
        }

        Room chosenRoom = GlobalFuncs.randElem(_validRooms);

        return(chosenRoom.createRoom(requiredExits));
    }
コード例 #11
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);
    }
コード例 #12
0
    public override Room createRoom(ExitConstraint requiredExits)
    {
        GameObject roomPrefab = GlobalFuncs.randElem(roomChoices);

        return(roomPrefab.GetComponent <Room>().createRoom(requiredExits));
    }
コード例 #13
0
ファイル: Room.cs プロジェクト: williamchendev/StoneSoup
    // The create room function actually instantiates a relevant prefab for a room.
    // A good question you might have is why there's a separate function for creating rooms and why we don't
    // just instantiate the provided room prefab.
    // The reason is we sometimes want to make a room that instantiates OTHER room prefabs
    // For example, a room might want to randomly select from other rooms when generating.
    public virtual Room createRoom(ExitConstraint requiredExits)
    {
        GameObject roomObj = Instantiate(gameObject);

        return(roomObj.GetComponent <Room>());
    }
コード例 #14
0
ファイル: Room.cs プロジェクト: williamchendev/StoneSoup
    // This is the function used by the level generator to generate the whole room.
    // It makes use of the "createRoom" and "fillRoom" functions to decide what sort of room to create and also how to fill it
    public static Room generateRoom(GameObject roomPrefab, LevelGenerator ourGenerator, int roomX, int roomY, ExitConstraint requiredExits)
    {
        Room newRoom = roomPrefab.GetComponent <Room>().createRoom(requiredExits);

        float totalRoomWidth  = Tile.TILE_SIZE * LevelGenerator.ROOM_WIDTH;
        float totalRoomHeight = Tile.TILE_SIZE * LevelGenerator.ROOM_HEIGHT;

        if (GameManager.gameMode == GameManager.GameMode.SingleRoom)
        {
            totalRoomWidth  = Tile.TILE_SIZE * (LevelGenerator.ROOM_WIDTH + 1);
            totalRoomHeight = Tile.TILE_SIZE * (LevelGenerator.ROOM_HEIGHT + 1);
        }



        newRoom.transform.parent        = GameManager.instance.transform;
        newRoom.transform.localPosition = new Vector3(totalRoomWidth * roomX, totalRoomHeight * roomY, 0);

        newRoom.roomGridX = roomX;
        newRoom.roomGridY = roomY;

        newRoom.fillRoom(ourGenerator, requiredExits);

        return(newRoom);
    }
コード例 #15
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);
            }
        }
    }
コード例 #16
0
 protected void roomGenerationVersionOne(LevelGenerator ourGenerator, ExitConstraint requiredExits)
 {
     // In this version of room generation, I only generate the walls.
     generateWalls(ourGenerator, requiredExits);
 }
コード例 #17
0
    protected void roomGenerationVersionTwo(LevelGenerator ourGenerator, ExitConstraint requiredExits)
    {
        // In this version of room generation, I generate walls and then other stuff.
        generateWalls(ourGenerator, requiredExits);
        // Inside the borders I make some rocks and enemies.
        int numRocks   = Random.Range(minNumRocks, maxNumRocks + 1);
        int numEnemies = Random.Range(minNumEnemies, maxNumEnemies + 1);

        // First, let's make an array keeping track of where we've spawned objects already.
        bool[,] occupiedPositions = new bool[LevelGenerator.ROOM_WIDTH, LevelGenerator.ROOM_HEIGHT];
        for (int x = 0; x < LevelGenerator.ROOM_WIDTH; x++)
        {
            for (int y = 0; y < LevelGenerator.ROOM_HEIGHT; y++)
            {
                if (x == 0 || x == LevelGenerator.ROOM_WIDTH - 1 ||
                    y == 0 || y == LevelGenerator.ROOM_HEIGHT - 1)
                {
                    // All border zones are occupied.
                    occupiedPositions[x, y] = true;
                }
                else
                {
                    occupiedPositions[x, y] = false;
                }
            }
        }

        // Now we spawn rocks and enemies in random locations
        List <Vector2> possibleSpawnPositions = new List <Vector2>(LevelGenerator.ROOM_WIDTH * LevelGenerator.ROOM_HEIGHT);

        for (int i = 0; i < numRocks; i++)
        {
            possibleSpawnPositions.Clear();
            for (int x = 0; x < LevelGenerator.ROOM_WIDTH; x++)
            {
                for (int y = 0; y < LevelGenerator.ROOM_HEIGHT; y++)
                {
                    if (occupiedPositions[x, y])
                    {
                        continue;
                    }
                    possibleSpawnPositions.Add(new Vector2(x, y));
                }
            }
            if (possibleSpawnPositions.Count > 0)
            {
                Vector2 spawnPos = GlobalFuncs.randElem(possibleSpawnPositions);
                Tile.spawnTile(rockPrefab, transform, (int)spawnPos.x, (int)spawnPos.y);
                occupiedPositions[(int)spawnPos.x, (int)spawnPos.y] = true;
            }
        }
        for (int i = 0; i < numEnemies; i++)
        {
            possibleSpawnPositions.Clear();
            for (int x = 0; x < LevelGenerator.ROOM_WIDTH; x++)
            {
                for (int y = 0; y < LevelGenerator.ROOM_HEIGHT; y++)
                {
                    if (occupiedPositions[x, y])
                    {
                        continue;
                    }
                    possibleSpawnPositions.Add(new Vector2(x, y));
                }
            }
            if (possibleSpawnPositions.Count > 0)
            {
                Vector2 spawnPos = GlobalFuncs.randElem(possibleSpawnPositions);
                Tile.spawnTile(enemyPrefab, transform, (int)spawnPos.x, (int)spawnPos.y);
                occupiedPositions[(int)spawnPos.x, (int)spawnPos.y] = true;
            }
        }
    }
コード例 #18
0
    public override void fillRoom(LevelGenerator ourGenerator, ExitConstraint requiredExits)
    {
        bool[,] wallMap = new bool[LevelGenerator.ROOM_WIDTH, LevelGenerator.ROOM_HEIGHT];

        // Start completely filled with walls.
        for (int x = 0; x < LevelGenerator.ROOM_WIDTH; x++)
        {
            for (int y = 0; y < LevelGenerator.ROOM_HEIGHT; y++)
            {
                wallMap[x, y] = true;
            }
        }

        bool    foundStartPos = false;
        Vector2 startPos      = new Vector2(Random.Range(0, LevelGenerator.ROOM_WIDTH), Random.Range(0, LevelGenerator.ROOM_HEIGHT));

        foreach (Vector2Int exitLocation in requiredExits.requiredExitLocations())
        {
            wallMap[exitLocation.x, exitLocation.y] = false;
            if (!foundStartPos)
            {
                startPos      = exitLocation;
                foundStartPos = true;
            }
        }

        _agenda.Clear();
        _closed.Clear();

        SearchVertex startVertex = new SearchVertex();

        startVertex.gridPos = startPos;
        startVertex.parent  = null;

        _agenda.Add(startVertex);

        while (_agenda.Count > 0)
        {
            SearchVertex currentVertex = _agenda[_agenda.Count - 1];
            _agenda.RemoveAt(_agenda.Count - 1);
            if (listContainsVertex(_closed, currentVertex.gridPos))
            {
                continue;
            }


            _closed.Add(currentVertex);

            _neighbors.Clear();

            Vector2 neighborPos = currentVertex.gridPos + Vector2.up * 2;
            if (inGrid(neighborPos) &&
                !listContainsVertex(_closed, neighborPos))
            {
                _neighbors.Add(neighborPos);
            }
            neighborPos = currentVertex.gridPos + Vector2.right * 2;
            if (inGrid(neighborPos) &&
                !listContainsVertex(_closed, neighborPos))
            {
                _neighbors.Add(neighborPos);
            }
            neighborPos = currentVertex.gridPos - Vector2.up * 2;
            if (inGrid(neighborPos) &&
                !listContainsVertex(_closed, neighborPos))
            {
                _neighbors.Add(neighborPos);
            }
            neighborPos = currentVertex.gridPos - Vector2.right * 2;
            if (inGrid(neighborPos) &&
                !listContainsVertex(_closed, neighborPos))
            {
                _neighbors.Add(neighborPos);
            }


            if (_neighbors.Count > 0)
            {
                GlobalFuncs.shuffle(_neighbors);
            }
            else
            {
                currentVertex.isDeadEnd = true;
            }
            foreach (Vector2 neighbor in _neighbors)
            {
                SearchVertex neighborVertex = new SearchVertex();
                neighborVertex.gridPos = neighbor;
                neighborVertex.parent  = currentVertex;
                _agenda.Add(neighborVertex);
            }
        }

        // Now go through the closed set and carve out space for all of the neighbors.
        foreach (SearchVertex vertex in _closed)
        {
            if (vertex.parent == null)
            {
                wallMap[(int)vertex.gridPos.x, (int)vertex.gridPos.y] = false;
                continue;
            }

            int currentX = (int)vertex.gridPos.x;
            int currentY = (int)vertex.gridPos.y;
            wallMap[currentX, currentY] = false;


            Vector2 endPos  = vertex.parent.gridPos;
            int     targetX = (int)endPos.x;
            int     targetY = (int)endPos.y;

            while (currentX != targetX || currentY != targetY)
            {
                if (currentX < targetX)
                {
                    currentX++;
                }
                else if (currentX > targetX)
                {
                    currentX--;
                }

                if (currentY < targetY)
                {
                    currentY++;
                }
                else if (currentY > targetY)
                {
                    currentY--;
                }

                wallMap[currentX, currentY] = false;
            }
        }

        // Now we remove some extra walls
        List <Vector2> wallLocations = new List <Vector2>();

        for (int i = 0; i < extraWallsToRemove; i++)
        {
            wallLocations.Clear();
            for (int x = 0; x < LevelGenerator.ROOM_WIDTH; x++)
            {
                for (int y = 0; y < LevelGenerator.ROOM_HEIGHT; y++)
                {
                    if (wallMap[x, y])
                    {
                        wallLocations.Add(new Vector2(x, y));
                    }
                }
            }

            if (wallLocations.Count > 1)
            {
                Vector2 wallToRemove = GlobalFuncs.randElem(wallLocations);
                wallMap[(int)wallToRemove.x, (int)wallToRemove.y] = false;
            }
        }

        for (int x = 0; x < LevelGenerator.ROOM_WIDTH; x++)
        {
            for (int y = 0; y < LevelGenerator.ROOM_HEIGHT; y++)
            {
                if (wallMap[x, y])
                {
                    Tile.spawnTile(ourGenerator.normalWallPrefab, transform, x, y);
                }
            }
        }
    }