/// <summary> /// 获取墙壁游戏对象 /// </summary> /// <param name="labyrinthStruct">迷宫结构</param> /// <param name="pixel">迷宫结构中每一个单位的宽度</param> /// <returns></returns> private static GameObject GetWall(LabyrinthOutputStruct labyrinthStruct, int pixel) { GameObject wallObj = new GameObject("Wall"); //墙壁预设体 GameObject[] wallPrefabs = new[] { Resources.Load <GameObject>("Dungeon/wall1"), Resources.Load <GameObject>("Dungeon/wall2") }; //墙壁拐角预设体(0 为内拐,1为外拐) GameObject[] wallCornersPrefabs = new[] { Resources.Load <GameObject>("Dungeon/wall_corner_in"), Resources.Load <GameObject>("Dungeon/wall_corner_out") }; //墙壁中间穿插预设体 GameObject[] wallInsertsPrefabs = new[] { Resources.Load <GameObject>("Dungeon/wall_in_1"), Resources.Load <GameObject>("Dungeon/wall_in_2"), Resources.Load <GameObject>("Dungeon/wall_in_3"), Resources.Load <GameObject>("Dungeon/wall_in_4") }; //获取一个起点 Vector2 entry = labyrinthStruct.entrys[0]; LabyrinthRoadStruct labyrinthRoadStruct = labyrinthStruct.GetRoad(entry); List <WallCornerStruct> wallCornerStructs = new List <WallCornerStruct>(); //创建道路的墙壁 CreateRoadWall(labyrinthStruct.random, pixel, wallObj, wallPrefabs, wallCornerStructs, null, labyrinthRoadStruct); //创建区域的墙壁 CreateRangeWall(labyrinthStruct.random, pixel, wallObj, wallPrefabs, wallCornerStructs, labyrinthStruct.labyrinthRangeStructs); //创建拐角与连接点 int insertsPrefabsLength = wallInsertsPrefabs.Length; int cornerIndex = 0; foreach (WallCornerStruct wallCornerStruct in wallCornerStructs) { GameObject selectPrefab = null; switch (wallCornerStruct.cornerType) { case WallCornerStruct.CornerEnum.In: selectPrefab = wallCornersPrefabs[0]; break; case WallCornerStruct.CornerEnum.Out: selectPrefab = wallCornersPrefabs[1]; break; case WallCornerStruct.CornerEnum.Connect: selectPrefab = wallInsertsPrefabs[labyrinthStruct.random.Next(0, insertsPrefabsLength)]; break; } if (selectPrefab != null) { GameObject createObj = GameObject.Instantiate <GameObject>(selectPrefab); createObj.name = "wall_" + wallCornerStruct.cornerType + "_" + cornerIndex++; createObj.transform.position = wallCornerStruct.pos; createObj.transform.eulerAngles = new Vector3(0, wallCornerStruct.angle, 0); createObj.transform.SetParent(wallObj.transform); } } return(wallObj); }
/// <summary> /// 创建道路墙壁 /// </summary> /// <param name="random">随机对象</param> /// <param name="pixel">没单位的宽度</param> /// <param name="parent">父物体</param> /// <param name="wallPrefabs">墙壁预设体</param> /// <param name="wallCornerStructs">拐弯处结果,函数内部填充</param> /// <param name="parentRoadStruct">父道路结构</param> /// <param name="thisRoadStruct">当前道路结构</param> private static void CreateRoadWall( System.Random random, int pixel, GameObject parent, GameObject[] wallPrefabs, List <WallCornerStruct> wallCornerStructs, LabyrinthRoadStruct parentRoadStruct, LabyrinthRoadStruct thisRoadStruct) { //各个方向是否存在墙壁 bool up = true, down = true, left = true, right = true; //使用当前道路结构的位置减去父道路结构的位置,计算通路方向,有通路则改变对应的值为false Action <Vector2> ChangeBool = (v) => { if (v.x > 0.5f) { left = false; return; } if (v.x < -0.5f) { right = false; return; } if (v.y > 0.5f) { down = false; return; } if (v.y < -0.5f) { up = false; return; } }; if (parentRoadStruct != null) { Vector2 v = thisRoadStruct.value - parentRoadStruct.value; ChangeBool(v); if (thisRoadStruct.type == LabyrinthPiecemealType.Door)//如果该点是门 { if (!up) { down = false; } if (!down) { up = false; } if (!left) { right = false; } if (!right) { left = false; } } } foreach (LabyrinthRoadStruct child in thisRoadStruct.nextRoad) { Vector2 v = thisRoadStruct.value - child.value; ChangeBool(v); } int wallLength = wallPrefabs.Length; if (up)//上方存在墙体 { for (int i = 0; i < pixel - 1; i++) { int r = random.Next(0, wallLength); GameObject createObj = GameObject.Instantiate <GameObject>(wallPrefabs[r]); createObj.name = "wall_" + thisRoadStruct.value.x + "_" + thisRoadStruct.value.y + "_up_" + i; createObj.transform.position = new Vector3( thisRoadStruct.value.x * pixel + i + 1f, 0, thisRoadStruct.value.y * pixel + pixel ); createObj.transform.eulerAngles = new Vector3(0, 180, 0); createObj.transform.SetParent(parent.transform); } //设置连接墙 if (!left && thisRoadStruct.type != LabyrinthPiecemealType.Door)//如果左侧不存在墙体,并且该点不是门 { WallCornerStruct wallCornerStruct = new WallCornerStruct() { angle = 180, cornerType = WallCornerStruct.CornerEnum.Connect, pos = new Vector3(thisRoadStruct.value.x * pixel, 0, thisRoadStruct.value.y * pixel + pixel) }; if (!wallCornerStructs.Contains(wallCornerStruct)) { wallCornerStructs.Add(wallCornerStruct); } } if (!right && thisRoadStruct.type != LabyrinthPiecemealType.Door)//如果右测不存在墙体,并且该点不是门 { WallCornerStruct wallCornerStruct = new WallCornerStruct() { angle = 180, cornerType = WallCornerStruct.CornerEnum.Connect, pos = new Vector3(thisRoadStruct.value.x * pixel + pixel, 0, thisRoadStruct.value.y * pixel + pixel) }; if (!wallCornerStructs.Contains(wallCornerStruct)) { wallCornerStructs.Add(wallCornerStruct); } } //设置拐角 if (left)//如果左侧也存在墙体,左上角内角度 { WallCornerStruct wallCornerStruct = new WallCornerStruct() { angle = 90, cornerType = WallCornerStruct.CornerEnum.In, pos = new Vector3(thisRoadStruct.value.x * pixel, 0, thisRoadStruct.value.y * pixel + pixel) }; int index = wallCornerStructs.IndexOf(wallCornerStruct); if (index < 0 || wallCornerStructs[index].cornerType == WallCornerStruct.CornerEnum.Connect) { if (index >= 0) { wallCornerStructs.RemoveAt(index); } wallCornerStructs.Add(wallCornerStruct); } } if (right)//如果右侧也存在墙体,右上角内角度 { WallCornerStruct wallCornerStruct = new WallCornerStruct() { angle = 180, cornerType = WallCornerStruct.CornerEnum.In, pos = new Vector3(thisRoadStruct.value.x * pixel + pixel, 0, thisRoadStruct.value.y * pixel + pixel) }; int index = wallCornerStructs.IndexOf(wallCornerStruct); if (index < 0 || wallCornerStructs[index].cornerType == WallCornerStruct.CornerEnum.Connect) { if (index >= 0) { wallCornerStructs.RemoveAt(index); } wallCornerStructs.Add(wallCornerStruct); } } } else//上方不存在墙体 { if (!left)//左侧也不存在墙体,左上角外角度 { WallCornerStruct wallCornerStruct = new WallCornerStruct() { angle = 90, cornerType = WallCornerStruct.CornerEnum.Out, pos = new Vector3(thisRoadStruct.value.x * pixel, 0, thisRoadStruct.value.y * pixel + pixel) }; int index = wallCornerStructs.IndexOf(wallCornerStruct); if (index < 0 || wallCornerStructs[index].cornerType == WallCornerStruct.CornerEnum.Connect) { if (index >= 0) { wallCornerStructs.RemoveAt(index); } wallCornerStructs.Add(wallCornerStruct); } } if (!right)//右侧也不存在墙体,右上角外角度 { WallCornerStruct wallCornerStruct = new WallCornerStruct() { angle = 180, cornerType = WallCornerStruct.CornerEnum.Out, pos = new Vector3(thisRoadStruct.value.x * pixel + pixel, 0, thisRoadStruct.value.y * pixel + pixel) }; int index = wallCornerStructs.IndexOf(wallCornerStruct); if (index < 0 || wallCornerStructs[index].cornerType == WallCornerStruct.CornerEnum.Connect) { if (index >= 0) { wallCornerStructs.RemoveAt(index); } wallCornerStructs.Add(wallCornerStruct); } } } if (down)//下方存在墙体 { for (int i = 0; i < pixel - 1; i++) { int r = random.Next(0, wallLength); GameObject createObj = GameObject.Instantiate <GameObject>(wallPrefabs[r]); createObj.name = "wall_" + thisRoadStruct.value.x + "_" + thisRoadStruct.value.y + "_down_" + i; createObj.transform.position = new Vector3( thisRoadStruct.value.x * pixel + i + 1, 0, thisRoadStruct.value.y * pixel ); createObj.transform.eulerAngles = new Vector3(0, 0, 0); createObj.transform.SetParent(parent.transform); } //设置连接墙 if (!left && thisRoadStruct.type != LabyrinthPiecemealType.Door)//如果左侧不存在墙体,并且该点不是门 { WallCornerStruct wallCornerStruct = new WallCornerStruct() { angle = 0, cornerType = WallCornerStruct.CornerEnum.Connect, pos = new Vector3(thisRoadStruct.value.x * pixel, 0, thisRoadStruct.value.y * pixel) }; if (!wallCornerStructs.Contains(wallCornerStruct)) { wallCornerStructs.Add(wallCornerStruct); } } if (!right && thisRoadStruct.type != LabyrinthPiecemealType.Door)//如果右测不存在墙体,并且该点不是门 { WallCornerStruct wallCornerStruct = new WallCornerStruct() { angle = 0, cornerType = WallCornerStruct.CornerEnum.Connect, pos = new Vector3(thisRoadStruct.value.x * pixel + pixel, 0, thisRoadStruct.value.y * pixel) }; if (!wallCornerStructs.Contains(wallCornerStruct)) { wallCornerStructs.Add(wallCornerStruct); } } //设置拐角 if (left)//如果左侧也存在墙体,左下角内角度 { WallCornerStruct wallCornerStruct = new WallCornerStruct() { angle = 0, cornerType = WallCornerStruct.CornerEnum.In, pos = new Vector3(thisRoadStruct.value.x * pixel, 0, thisRoadStruct.value.y * pixel) }; int index = wallCornerStructs.IndexOf(wallCornerStruct); if (index < 0 || wallCornerStructs[index].cornerType == WallCornerStruct.CornerEnum.Connect) { if (index >= 0) { wallCornerStructs.RemoveAt(index); } wallCornerStructs.Add(wallCornerStruct); } } if (right)//如果右侧也存在墙体,右下角内角度 { WallCornerStruct wallCornerStruct = new WallCornerStruct() { angle = -90, cornerType = WallCornerStruct.CornerEnum.In, pos = new Vector3(thisRoadStruct.value.x * pixel + pixel, 0, thisRoadStruct.value.y * pixel) }; int index = wallCornerStructs.IndexOf(wallCornerStruct); if (index < 0 || wallCornerStructs[index].cornerType == WallCornerStruct.CornerEnum.Connect) { if (index >= 0) { wallCornerStructs.RemoveAt(index); } wallCornerStructs.Add(wallCornerStruct); } } } else//下方不存在墙体 { if (!left)//左侧也不存在墙体,左下角内角度 { WallCornerStruct wallCornerStruct = new WallCornerStruct() { angle = 0, cornerType = WallCornerStruct.CornerEnum.Out, pos = new Vector3(thisRoadStruct.value.x * pixel, 0, thisRoadStruct.value.y * pixel) }; int index = wallCornerStructs.IndexOf(wallCornerStruct); if (index < 0 || wallCornerStructs[index].cornerType == WallCornerStruct.CornerEnum.Connect) { if (index >= 0) { wallCornerStructs.RemoveAt(index); } wallCornerStructs.Add(wallCornerStruct); } } if (!right)//右侧也不存在墙体,右下角内角度 { WallCornerStruct wallCornerStruct = new WallCornerStruct() { angle = -90, cornerType = WallCornerStruct.CornerEnum.Out, pos = new Vector3(thisRoadStruct.value.x * pixel + pixel, 0, thisRoadStruct.value.y * pixel) }; int index = wallCornerStructs.IndexOf(wallCornerStruct); if (index < 0 || wallCornerStructs[index].cornerType == WallCornerStruct.CornerEnum.Connect) { if (index >= 0) { wallCornerStructs.RemoveAt(index); } wallCornerStructs.Add(wallCornerStruct); } } } if (left)//左侧存在墙体 { for (int i = 0; i < pixel - 1; i++) { int r = random.Next(0, wallLength); GameObject createObj = GameObject.Instantiate <GameObject>(wallPrefabs[r]); createObj.name = "wall_" + thisRoadStruct.value.x + "_" + thisRoadStruct.value.y + "_left_" + i; createObj.transform.position = new Vector3( thisRoadStruct.value.x * pixel, 0, thisRoadStruct.value.y * pixel + i + 1 ); createObj.transform.eulerAngles = new Vector3(0, 90, 0); createObj.transform.SetParent(parent.transform); } //设置连接墙 if (!up && thisRoadStruct.type != LabyrinthPiecemealType.Door)//如果上方不存在墙体,并且该点不是门 { WallCornerStruct wallCornerStruct = new WallCornerStruct() { angle = 90, cornerType = WallCornerStruct.CornerEnum.Connect, pos = new Vector3(thisRoadStruct.value.x * pixel, 0, thisRoadStruct.value.y * pixel + pixel) }; if (!wallCornerStructs.Contains(wallCornerStruct)) { wallCornerStructs.Add(wallCornerStruct); } } if (!down && thisRoadStruct.type != LabyrinthPiecemealType.Door)//如果下方不存在墙体,并且该点不是门 { WallCornerStruct wallCornerStruct = new WallCornerStruct() { angle = 90, cornerType = WallCornerStruct.CornerEnum.Connect, pos = new Vector3(thisRoadStruct.value.x * pixel, 0, thisRoadStruct.value.y * pixel) }; if (!wallCornerStructs.Contains(wallCornerStruct)) { wallCornerStructs.Add(wallCornerStruct); } } } if (right)//右侧存在墙体 { for (int i = 0; i < pixel - 1; i++) { int r = random.Next(0, wallLength); GameObject createObj = GameObject.Instantiate <GameObject>(wallPrefabs[r]); createObj.name = "wall_" + thisRoadStruct.value.x + "_" + thisRoadStruct.value.y + "_right_" + i; createObj.transform.position = new Vector3( thisRoadStruct.value.x * pixel + pixel, 0, thisRoadStruct.value.y * pixel + i + 1 ); createObj.transform.eulerAngles = new Vector3(0, -90, 0); createObj.transform.SetParent(parent.transform); } //设置连接墙 if (!up && thisRoadStruct.type != LabyrinthPiecemealType.Door)//如果上方不存在墙体,并且该点不是门 { WallCornerStruct wallCornerStruct = new WallCornerStruct() { angle = -90, cornerType = WallCornerStruct.CornerEnum.Connect, pos = new Vector3(thisRoadStruct.value.x * pixel + pixel, 0, thisRoadStruct.value.y * pixel + pixel) }; if (!wallCornerStructs.Contains(wallCornerStruct)) { wallCornerStructs.Add(wallCornerStruct); } } if (!down && thisRoadStruct.type != LabyrinthPiecemealType.Door)//如果下方不存在墙体,并且该点不是门 { WallCornerStruct wallCornerStruct = new WallCornerStruct() { angle = -90, cornerType = WallCornerStruct.CornerEnum.Connect, pos = new Vector3(thisRoadStruct.value.x * pixel + pixel, 0, thisRoadStruct.value.y * pixel) }; if (!wallCornerStructs.Contains(wallCornerStruct)) { wallCornerStructs.Add(wallCornerStruct); } } } //继续便利子节点 foreach (LabyrinthRoadStruct child in thisRoadStruct.nextRoad) { CreateRoadWall(random, pixel, parent, wallPrefabs, wallCornerStructs, thisRoadStruct, child); } }
/// <summary> /// 通过一个起点,计算从这个点通向所有点的通路 /// </summary> /// <param name="entry">起点位置</param> /// <returns></returns> public LabyrinthRoadStruct GetRoad(Vector2 entry) { int x = (int)entry.x; int y = (int)entry.y; if (x < labyrinthData.GetLength(0) - 1 && y < labyrinthData.GetLength(1) - 1 && x > 0 && y > 0) { if (labyrinthData[x, y] == LabyrinthPiecemealType.Road) { //检测这个点是否可以被延伸 Func <int, int, int, int, bool> CanCheck = (checkX, checkY, parentX, parentY) => { if (checkX == parentX && checkY == parentY) { return(false); } return(labyrinthData[checkX, checkY] == LabyrinthPiecemealType.Road || labyrinthData[checkX, checkY] == LabyrinthPiecemealType.Door); }; //创建一个新的节点 Func <int, int, LabyrinthRoadStruct, LabyrinthRoadStruct> CreateNew = (checkX, checkY, parent) => { LabyrinthRoadStruct create = new LabyrinthRoadStruct(); create.value = new Vector2(checkX, checkY); create.parent = parent; create.type = labyrinthData[checkX, checkY]; return(create); }; //移动到下一个节点 Action <LabyrinthRoadStruct> MoveNext = null; MoveNext = (parent) => { int _x = (int)parent.value.x; int _y = (int)parent.value.y; int _parentX = _x; int _parentY = _y; if (parent.parent != null) { _parentX = (int)parent.parent.value.x; _parentY = (int)parent.parent.value.y; } List <LabyrinthRoadStruct> nextList = new List <LabyrinthRoadStruct>(); if (CanCheck(_x - 1, _y, _parentX, _parentY)) { nextList.Add(CreateNew(_x - 1, _y, parent)); } if (CanCheck(_x + 1, _y, _parentX, _parentY)) { nextList.Add(CreateNew(_x + 1, _y, parent)); } if (CanCheck(_x, _y - 1, _parentX, _parentY)) { nextList.Add(CreateNew(_x, _y - 1, parent)); } if (CanCheck(_x, _y + 1, _parentX, _parentY)) { nextList.Add(CreateNew(_x, _y + 1, parent)); } parent.nextRoad = nextList.ToArray(); foreach (LabyrinthRoadStruct item in parent.nextRoad) { MoveNext(item); } }; LabyrinthRoadStruct labyrinthRoadStruct = new LabyrinthRoadStruct(); labyrinthRoadStruct.value = entry; MoveNext(labyrinthRoadStruct); return(labyrinthRoadStruct); } } return(null); }