zoukankan      html  css  js  c++  java
  • Unity_Dungeonize 随机生成迷宫

       本文对随机生成迷宫的实现思路进行记录,其作用在于为游戏过程提供随机性以及节省开发周期,下面是Dungeonize的结构

      随机迷宫的生成主要包括几个阶段

      

    1.生成房间体结构,为墙体,自定义房间,自定义物体生成平台

     1     for (var i = 0; i < room_count; i++) {
     2                 Room room = new Room (); 
     3                 if (rooms.Count == 0) {
     4                     //初始房间生成玩家和任务事件监听
     5                     room.x = (int)Mathf.Floor (map_size / 2f);
     6                     room.y = (int)Mathf.Floor (map_size / 2f); //Random.Range(10,20);
     7                     room.w = Random.Range (min_size, max_size);
     8                     if (room.w % 2 == 0) room.w += 1;
     9                     room.h = Random.Range (min_size, max_size);
    10                     if (room.h % 2 == 0) room.h += 1;
    11                     room.branch = 0;
    12                     lastRoom = room;
    13                 } else {
    14                     int branch = 0;
    15                     if (collision_count == 0) {
    16                         branch = Random.Range (5, 20); //complexity
    17                     }
    18                     room.branch = branch;
    19 
    20                     lastRoom = rooms [rooms.Count - 1];
    21                     int lri = 1;
    22 
    23                     while (lastRoom.dead_end) {
    24                         lastRoom = rooms [rooms.Count - lri++];
    25                     }
    26 
    27 
    28                     if (direction == "set") {
    29                         string newRandomDirection = directions[Random.Range(0, directions.Count)];
    30                         direction = newRandomDirection;
    31                         while (direction == oldDirection)
    32                         {
    33                             newRandomDirection = directions[Random.Range(0, directions.Count)];
    34                             direction = newRandomDirection;
    35                         }
    36 
    37                     }
    38                     this.roomMarginTemp = Random.RandomRange(0, this.roomMargin - 1);
    39                     //邻接方位生成房间
    40                     if (direction == "y") {
    41                         room.x = lastRoom.x + lastRoom.w + Random.Range (3, 5) + this.roomMarginTemp;
    42                         room.y = lastRoom.y;
    43                     } else if (direction == "-y") {
    44                         room.x = lastRoom.x - lastRoom.w - Random.Range (3, 5) - this.roomMarginTemp;
    45                         room.y = lastRoom.y;
    46                     } else if (direction == "x") {
    47                         room.y = lastRoom.y + lastRoom.h + Random.Range (3, 5) + this.roomMarginTemp;
    48                         room.x = lastRoom.x;
    49                     } else if (direction == "-x") {
    50                         room.y = lastRoom.y - lastRoom.h - Random.Range (3, 5) - this.roomMarginTemp;
    51                         room.x = lastRoom.x;
    52                     }
    53 
    54                     room.w = Random.Range (min_size, max_size);
    55                     if (room.w % 2 == 0) room.w += 1;
    56 
    57                     room.h = Random.Range (min_size, max_size);
    58                     if (room.h % 2 == 0) room.h += 1;
    59 
    60                     room.connectedTo = lastRoom;
    61                 }

      在随机产生生成房间体后,生成墙体形成一个完整的房间结构,为之后prefab提供空间

    //wall 
    for
    (int x = 0; x < map_size_x -1; x++) { for (int y = 0; y < map_size_y -1; y++) { if (map [x, y].type == 0) { if (map [x + 1, y].type == 1 || map [x + 1, y].type == 3) { //west map [x, y].type = 11; map [x, y].room = map [x + 1, y].room; } if (x > 0) { if (map [x - 1, y].type == 1 || map [x - 1, y].type == 3) { //east map [x, y].type = 9; map [x, y].room = map [x - 1, y].room; } } if (map [x, y + 1].type == 1 || map [x, y + 1].type == 3) { //south map [x, y].type = 10; map [x, y].room = map [x, y + 1].room; } if (y > 0) { if (map [x, y - 1].type == 1 || map [x, y - 1].type == 3) { //north map [x, y].type = 8; map [x, y].room = map [x, y - 1].room; } } } } }

    通过list存储方位参数

    //tile types for ease
            public static List<int> roomsandfloors = new List<int> { 1, 3 };
            public static List<int> corners = new List<int> {4,5,6,7};
            public static List<int> walls = new List<int> {8,9,10,11};  //wall direction 
            private static List<string> directions = new List<string> {"x","y","-y","-x"}; //,"-y"};
            

    根据lis存储过道结构

     1     //corners
     2             for (int x = 0; x < map_size_x -1; x++) {
     3                 for (int y = 0; y < map_size_y -1; y++) {
     4                     if (walls.Contains (map [x, y + 1].type) && walls.Contains (map [x + 1, y].type) && roomsandfloors.Contains (map [x + 1, y + 1].type)) { //north
     5                         map [x, y].type = 4;
     6                         map [x, y].room = map [x + 1, y + 1].room;
     7                     }
     8                     if (y > 0) {
     9                         if (walls.Contains (map [x + 1, y].type) && walls.Contains (map [x, y - 1].type) && roomsandfloors.Contains (map [x + 1, y - 1].type)) { //north
    10                             map [x, y].type = 5;
    11                             map [x, y].room = map [x + 1, y - 1].room;
    12 
    13                         }
    14                     }
    15                     if (x > 0) {
    16                         if (walls.Contains (map [x - 1, y].type) && walls.Contains (map [x, y + 1].type) && roomsandfloors.Contains (map [x - 1, y + 1].type)) { //north
    17                             map [x, y].type = 7;
    18                             map [x, y].room = map [x - 1, y + 1].room;
    19 
    20                         }
    21                     }
    22                     if (x > 0 && y > 0) {
    23                         if (walls.Contains (map [x - 1, y].type) && walls.Contains (map [x, y - 1].type) && roomsandfloors.Contains (map [x - 1, y - 1].type)) { //north
    24                             map [x, y].type = 6;
    25                             map [x, y].room = map [x - 1, y - 1].room;
    26 
    27                         }
    28                     }
    29                     /* door corners --- a bit problematic in this version */
    30                     if (map [x, y].type == 3) { 
    31                         if (map [x + 1, y].type == 1) {
    32                             map [x, y + 1].type = 11;
    33                             map [x, y - 1].type = 11;
    34                         } else if (Dungeon.map [x - 1, y].type == 1) {
    35                             map [x, y + 1].type = 9;
    36                             map [x, y - 1].type = 9;
    37                         }
    38                     }
    39 
    40                 }
    41             }

     这样一个房间体的完整结构已经创建完毕,之后对迷宫结构生成地下城结构

            for (var y = 0; y < Dungeon.map_size_y; y++) {
                for (var x = 0; x < Dungeon.map_size_x; x++) {
                    int tile = Dungeon.map [x, y].type;
                    int orientation = Dungeon.map[x, y].orientation;
                    GameObject created_tile;
                    Vector3 tile_location;
                    if (!makeIt3d) {
                        tile_location = new Vector3 (x * tileScaling, y * tileScaling, 0);
                    } else {
                        tile_location = new Vector3 (x * tileScaling, 0, y * tileScaling);
                    }
    
                    created_tile = null;
                    if (tile == 1) {
                        GameObject floorPrefabToUse = floorPrefab;
                        Room room = Dungeon.map[x,y].room;
                        if(room != null){
                            foreach(CustomRoom customroom in customRooms){
                                if(customroom.roomId == room.room_id){
                                    floorPrefabToUse = customroom.floorPrefab;
                                    break;
                                }
                            }
                        }
    
                        created_tile = GameObject.Instantiate (floorPrefabToUse, tile_location, Quaternion.identity) as GameObject;
                    }
                    
                    if ( Dungeon.walls.Contains(tile)) {
                        GameObject wallPrefabToUse = wallPrefab;
                        Room room = Dungeon.map[x,y].room;
                        if(room != null){
                            foreach(CustomRoom customroom in customRooms){
                                if(customroom.roomId == room.room_id){
                                    wallPrefabToUse = customroom.wallPrefab;
                                    break;
                                }
                            }
                        }
    
                        created_tile = GameObject.Instantiate (wallPrefabToUse, tile_location, Quaternion.identity) as GameObject;
                        if(!makeIt3d){
                            created_tile.transform.Rotate(Vector3.forward  * (-90 * (tile -4)));
                        }
                        else{
                            created_tile.transform.Rotate(Vector3.up  * (-90 * (tile -4)));
                        }
                    }
                    
                    if (tile == 3) {
                        if (corridorFloorPrefab)
                        {
                            created_tile = GameObject.Instantiate(corridorFloorPrefab, tile_location, Quaternion.identity) as GameObject;
                        }
                        else
                        {
                            created_tile = GameObject.Instantiate(floorPrefab, tile_location, Quaternion.identity) as GameObject;
                        }
    
                        if (orientation == 1 && makeIt3d)
                        {
                            created_tile.transform.Rotate(Vector3.up * (-90));
                        }
    
                    }
    
                    if (Dungeon.corners.Contains(tile)) {
                        GameObject cornerPrefabToUse = cornerPrefab;
                        Room room = Dungeon.map[x,y].room;
                        if(room != null){
                            foreach(CustomRoom customroom in customRooms){
                                if(customroom.roomId == room.room_id){
                                    cornerPrefabToUse = customroom.cornerPrefab;
                                    break;
                                }
                            }
                        }
    
    
                        if(cornerPrefabToUse){ //there was a bug in this line. A good man helped for fix.
                            created_tile = GameObject.Instantiate (cornerPrefabToUse, tile_location, Quaternion.identity) as GameObject;
                            if(cornerRotation){
                                if(!makeIt3d){
                                    created_tile.transform.Rotate(Vector3.forward  * (-90 * (tile -4)));
                                }
                                else{
                                    created_tile.transform.Rotate(Vector3.up  * (-90 * (tile -4)));
                                }
                            }
                        }
                        else{
                            created_tile = GameObject.Instantiate (wallPrefab, tile_location, Quaternion.identity) as GameObject;
                        }
                    }
                    
                    if (created_tile) {
                        created_tile.transform.parent = transform;
                    }
                }
            }

      迷宫生成后,需要对房间内容进行添加,随机的物品以及房间为玩家提供游玩条件,特定的内容包含战斗条件或者任务条件

    //Spawn Objects;
            List<SpawnList> spawnedObjectLocations = new List<SpawnList> ();
    
            //OTHERS
            for (int x = 0; x < Dungeon.map_size_x; x++) {
                for (int y = 0; y < Dungeon.map_size_y; y++) {
                    if (Dungeon.map [x, y].type == 1 &&
                            ((Dungeon.startRoom != Dungeon.map [x, y].room && Dungeon.goalRoom != Dungeon.map [x, y].room) || maximumRoomCount <= 3)) {
                        var location = new SpawnList ();
    
                        location.x = x;
                        location.y = y;
                        if (Dungeon.walls.Contains(Dungeon.map[x + 1, y].type)) {
                            location.byWall = true;
                            location.wallLocation = "S";
                        }
                        else if (Dungeon.walls.Contains(Dungeon.map[x - 1, y].type))
                        {
                            location.byWall = true;
                            location.wallLocation = "N";
                        }
                        else if (Dungeon.walls.Contains(Dungeon.map[x, y + 1].type)) {
                            location.byWall = true;
                            location.wallLocation = "W";
                        }
                        else if (Dungeon.walls.Contains(Dungeon.map [x, y - 1].type)) {
                            location.byWall = true;
                            location.wallLocation = "E";
                        }
    
                        if (Dungeon.map [x + 1, y].type == 3 || Dungeon.map [x - 1, y].type == 3 || Dungeon.map [x, y + 1].type == 3 || Dungeon.map [x, y - 1].type == 3) {
                            location.byCorridor = true;
                        }
                        if (Dungeon.map [x + 1, y + 1].type == 3 || Dungeon.map [x - 1, y - 1].type == 3 || Dungeon.map [x - 1, y + 1].type == 3 || Dungeon.map [x + 1, y - 1].type == 3) {
                            location.byCorridor = true;
                        }
                        location.room = Dungeon.map[x,y].room;
    
                        int roomCenterX = (int)Mathf.Floor(location.room.w / 2) + location.room.x;
                        int roomCenterY = (int)Mathf.Floor(location.room.h / 2) + location.room.y;
    
                        if(x == roomCenterX + 1 && y == roomCenterY + 1 )
                        {
                            location.inTheMiddle = true;
                        } 
                        spawnedObjectLocations.Add (location);
                    }
                    else if (Dungeon.map [x, y].type == 3) {
                        var location = new SpawnList ();
                        location.x = x;
                        location.y = y;    
    
                        if (Dungeon.map [x + 1, y].type == 1 ) {
                            location.byCorridor = true;
                            location.asDoor = 4;
                            location.room = Dungeon.map[x + 1,y].room;
    
                            spawnedObjectLocations.Add (location);
                        }
                        else if(Dungeon.map [x - 1, y].type == 1){
                            location.byCorridor = true;
                            location.asDoor = 2;
                            location.room = Dungeon.map[x - 1,y].room;
    
                            spawnedObjectLocations.Add (location);    
                        }
                        else if (Dungeon.map [x, y + 1].type == 1 ){
                            location.byCorridor = true;
                            location.asDoor = 1;
                            location.room = Dungeon.map[x,y + 1].room;
    
                            spawnedObjectLocations.Add (location);
                        }
                        else if (Dungeon.map [x, y - 1].type == 1){
                            location.byCorridor = true;
                            location.asDoor = 3;
                            location.room = Dungeon.map[x,y - 1].room;
    
                            spawnedObjectLocations.Add (location);                    
                        }
                    }
                }
            }
            
    这样就能生成基本的随机模型

    2d ver

    3d ver
    也可以根据需求进行修改
  • 相关阅读:
    C语言——第四次作业(2)
    C语言——第三次作业(2)
    C语言——第二次作业(2)
    C语言——第一次作业(2)
    C语言——第0次作业(二)
    高级软件工程第九次作业:东理三剑客团队作业-随笔7
    高级软件工程第九次作业:东理三剑客团队作业-随笔6
    高级软件工程第九次作业:东理三剑客团队作业-随笔5
    高级软件工程第九次作业:东理三剑客团队作业-随笔4
    高级软件工程第九次作业:东理三剑客团队作业-随笔3
  • 原文地址:https://www.cnblogs.com/EraserHead/p/12200614.html
Copyright © 2011-2022 走看看