Unity_Dungeonize 随机生成迷宫

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

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

  Unity_Dungeonize 随机生成迷宫

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

     for (var i = ; i < room_count; i++) {
Room room = new Room ();
if (rooms.Count == ) {
//初始房间生成玩家和任务事件监听
room.x = (int)Mathf.Floor (map_size / 2f);
room.y = (int)Mathf.Floor (map_size / 2f); //Random.Range(10,20);
room.w = Random.Range (min_size, max_size);
if (room.w % == ) room.w += ;
room.h = Random.Range (min_size, max_size);
if (room.h % == ) room.h += ;
room.branch = ;
lastRoom = room;
} else {
int branch = ;
if (collision_count == ) {
branch = Random.Range (, ); //complexity
}
room.branch = branch; lastRoom = rooms [rooms.Count - ];
int lri = ; while (lastRoom.dead_end) {
lastRoom = rooms [rooms.Count - lri++];
} if (direction == "set") {
string newRandomDirection = directions[Random.Range(, directions.Count)];
direction = newRandomDirection;
while (direction == oldDirection)
{
newRandomDirection = directions[Random.Range(, directions.Count)];
direction = newRandomDirection;
} }
this.roomMarginTemp = Random.RandomRange(, this.roomMargin - );
//邻接方位生成房间
if (direction == "y") {
room.x = lastRoom.x + lastRoom.w + Random.Range (, ) + this.roomMarginTemp;
room.y = lastRoom.y;
} else if (direction == "-y") {
room.x = lastRoom.x - lastRoom.w - Random.Range (, ) - this.roomMarginTemp;
room.y = lastRoom.y;
} else if (direction == "x") {
room.y = lastRoom.y + lastRoom.h + Random.Range (, ) + this.roomMarginTemp;
room.x = lastRoom.x;
} else if (direction == "-x") {
room.y = lastRoom.y - lastRoom.h - Random.Range (, ) - this.roomMarginTemp;
room.x = lastRoom.x;
} room.w = Random.Range (min_size, max_size);
if (room.w % == ) room.w += ; room.h = Random.Range (min_size, max_size);
if (room.h % == ) room.h += ; room.connectedTo = lastRoom;
}

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

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

通过list存储方位参数

//tile types for ease
public static List<int> roomsandfloors = new List<int> { , };
public static List<int> corners = new List<int> {,,,};
public static List<int> walls = new List<int> {,,,};  //wall direction
private static List<string> directions = new List<string> {"x","y","-y","-x"}; //,"-y"};

根据lis存储过道结构

     //corners
for (int x = ; x < map_size_x -; x++) {
for (int y = ; y < map_size_y -; y++) {
if (walls.Contains (map [x, y + ].type) && walls.Contains (map [x + , y].type) && roomsandfloors.Contains (map [x + , y + ].type)) { //north
map [x, y].type = ;
map [x, y].room = map [x + , y + ].room;
}
if (y > ) {
if (walls.Contains (map [x + , y].type) && walls.Contains (map [x, y - ].type) && roomsandfloors.Contains (map [x + , y - ].type)) { //north
map [x, y].type = ;
map [x, y].room = map [x + , y - ].room; }
}
if (x > ) {
if (walls.Contains (map [x - , y].type) && walls.Contains (map [x, y + ].type) && roomsandfloors.Contains (map [x - , y + ].type)) { //north
map [x, y].type = ;
map [x, y].room = map [x - , y + ].room; }
}
if (x > && y > ) {
if (walls.Contains (map [x - , y].type) && walls.Contains (map [x, y - ].type) && roomsandfloors.Contains (map [x - , y - ].type)) { //north
map [x, y].type = ;
map [x, y].room = map [x - , y - ].room; }
}
/* door corners --- a bit problematic in this version */
if (map [x, y].type == ) {
if (map [x + , y].type == ) {
map [x, y + ].type = ;
map [x, y - ].type = ;
} else if (Dungeon.map [x - , y].type == ) {
map [x, y + ].type = ;
map [x, y - ].type = ;
}
} }
}

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

        for (var y = ; y < Dungeon.map_size_y; y++) {
for (var x = ; 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, );
} else {
tile_location = new Vector3 (x * tileScaling, , y * tileScaling);
} created_tile = null;
if (tile == ) {
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 * (- * (tile -)));
}
else{
created_tile.transform.Rotate(Vector3.up * (- * (tile -)));
}
} if (tile == ) {
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 == && makeIt3d)
{
created_tile.transform.Rotate(Vector3.up * (-));
} } 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 * (- * (tile -)));
}
else{
created_tile.transform.Rotate(Vector3.up * (- * (tile -)));
}
}
}
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 = ; x < Dungeon.map_size_x; x++) {
for (int y = ; y < Dungeon.map_size_y; y++) {
if (Dungeon.map [x, y].type == &&
((Dungeon.startRoom != Dungeon.map [x, y].room && Dungeon.goalRoom != Dungeon.map [x, y].room) || maximumRoomCount <= )) {
var location = new SpawnList (); location.x = x;
location.y = y;
if (Dungeon.walls.Contains(Dungeon.map[x + , y].type)) {
location.byWall = true;
location.wallLocation = "S";
}
else if (Dungeon.walls.Contains(Dungeon.map[x - , y].type))
{
location.byWall = true;
location.wallLocation = "N";
}
else if (Dungeon.walls.Contains(Dungeon.map[x, y + ].type)) {
location.byWall = true;
location.wallLocation = "W";
}
else if (Dungeon.walls.Contains(Dungeon.map [x, y - ].type)) {
location.byWall = true;
location.wallLocation = "E";
} if (Dungeon.map [x + , y].type == || Dungeon.map [x - , y].type == || Dungeon.map [x, y + ].type == || Dungeon.map [x, y - ].type == ) {
location.byCorridor = true;
}
if (Dungeon.map [x + , y + ].type == || Dungeon.map [x - , y - ].type == || Dungeon.map [x - , y + ].type == || Dungeon.map [x + , y - ].type == ) {
location.byCorridor = true;
}
location.room = Dungeon.map[x,y].room; int roomCenterX = (int)Mathf.Floor(location.room.w / ) + location.room.x;
int roomCenterY = (int)Mathf.Floor(location.room.h / ) + location.room.y; if(x == roomCenterX + && y == roomCenterY + )
{
location.inTheMiddle = true;
}
spawnedObjectLocations.Add (location);
}
else if (Dungeon.map [x, y].type == ) {
var location = new SpawnList ();
location.x = x;
location.y = y; if (Dungeon.map [x + , y].type == ) {
location.byCorridor = true;
location.asDoor = ;
location.room = Dungeon.map[x + ,y].room; spawnedObjectLocations.Add (location);
}
else if(Dungeon.map [x - , y].type == ){
location.byCorridor = true;
location.asDoor = ;
location.room = Dungeon.map[x - ,y].room; spawnedObjectLocations.Add (location);
}
else if (Dungeon.map [x, y + ].type == ){
location.byCorridor = true;
location.asDoor = ;
location.room = Dungeon.map[x,y + ].room; spawnedObjectLocations.Add (location);
}
else if (Dungeon.map [x, y - ].type == ){
location.byCorridor = true;
location.asDoor = ;
location.room = Dungeon.map[x,y - ].room; spawnedObjectLocations.Add (location);
}
}
}
}

这样就能生成基本的随机模型
Unity_Dungeonize 随机生成迷宫
2d ver
Unity_Dungeonize 随机生成迷宫
3d ver
也可以根据需求进行修改
上一篇:rhel yum报错


下一篇:canvas——随机生成迷宫