using System.Collections.Generic; using UnityEngine; using Game.Map; public class PathNode { public Vector3 position; public MapNode mapNode; public int distance; public byte state; public PathNode progenitor; public PathNode rearguard; public Listchildren; public PathNode(Vector3 position, MapNode mapNode) { this.position = position; this.mapNode = mapNode; children = new List (); } } public class PathNodeManager { private static PathNodeManager _instance; public static PathNodeManager Instance { get { if (_instance == null) { _instance = new PathNodeManager(); } return _instance; } } private Dictionary m_PathDic; private PathNodeManager() { m_PathDic = new Dictionary (); } public PathNode InstancePathNode(Vector3 pos, MapNode mapNode) { PathNode node = new PathNode(pos, mapNode); if (m_PathDic.ContainsKey(pos)) { if (mapNode != null && m_PathDic[pos].mapNode != null) { m_PathDic[pos].mapNode = mapNode; } } else { m_PathDic.Add(pos, node); } return m_PathDic[pos]; } public void InitPathNode() { List tempList = new List (MazeManager.Instance.MapNodeDic.Values); for (int i = 0; i < tempList.Count; i++) { Vector2 index = tempList[i].index; Vector3 p0 = (new Vector3(index.x, 0, index.y)) * MazeManager.unitSize; MapNode mapNode = tempList[i]; if (tempList[i].roadType == RoadType.Room || tempList[i].roadType == RoadType.Hall) { PathNode node1 = InstancePathNode(p0 + new Vector3(-2, 0, -2), mapNode); PathNode node2 = InstancePathNode(p0 + new Vector3(-2, 0, -1), mapNode); PathNode node3 = InstancePathNode(p0 + new Vector3(-2, 0, 0), mapNode); PathNode node4 = InstancePathNode(p0 + new Vector3(-2, 0, 1), mapNode); PathNode node5 = InstancePathNode(p0 + new Vector3(-2, 0, 2), mapNode); PathNode node6 = InstancePathNode(p0 + new Vector3(-1, 0, -2), mapNode); PathNode node7 = InstancePathNode(p0 + new Vector3(-1, 0, -1), mapNode); PathNode node8 = InstancePathNode(p0 + new Vector3(-1, 0, 0), mapNode); PathNode node9 = InstancePathNode(p0 + new Vector3(-1, 0, 1), mapNode); PathNode node10 = InstancePathNode(p0 + new Vector3(-1, 0, 2), mapNode); PathNode node11 = InstancePathNode(p0 + new Vector3(0, 0, -2), mapNode); PathNode node12 = InstancePathNode(p0 + new Vector3(0, 0, -1), mapNode); PathNode node13 = InstancePathNode(p0, mapNode); PathNode node14 = InstancePathNode(p0 + new Vector3(0, 0, 1), mapNode); PathNode node15 = InstancePathNode(p0 + new Vector3(0, 0, 2), mapNode); PathNode node16 = InstancePathNode(p0 + new Vector3(1, 0, -2), mapNode); PathNode node17 = InstancePathNode(p0 + new Vector3(1, 0, -1), mapNode); PathNode node18 = InstancePathNode(p0 + new Vector3(1, 0, 0), mapNode); PathNode node19 = InstancePathNode(p0 + new Vector3(1, 0, 1), mapNode); PathNode node20 = InstancePathNode(p0 + new Vector3(1, 0, 2), mapNode); PathNode node21 = InstancePathNode(p0 + new Vector3(2, 0, -2), mapNode); PathNode node22 = InstancePathNode(p0 + new Vector3(2, 0, -1), mapNode); PathNode node23 = InstancePathNode(p0 + new Vector3(2, 0, 0), mapNode); PathNode node24 = InstancePathNode(p0 + new Vector3(2, 0, 1), mapNode); PathNode node25 = InstancePathNode(p0 + new Vector3(2, 0, 2), mapNode); node1.children.Add(node2); node1.children.Add(node6); node2.children.Add(node1); node2.children.Add(node3); node2.children.Add(node7); node3.children.Add(node2); node3.children.Add(node4); node3.children.Add(node8); node4.children.Add(node3); node4.children.Add(node5); node4.children.Add(node9); node5.children.Add(node4); node5.children.Add(node10); node6.children.Add(node1); node6.children.Add(node7); node6.children.Add(node11); node7.children.Add(node2); node7.children.Add(node6); node7.children.Add(node8); node7.children.Add(node12); node8.children.Add(node3); node8.children.Add(node7); node8.children.Add(node9); node8.children.Add(node13); node9.children.Add(node4); node9.children.Add(node8); node9.children.Add(node10); node9.children.Add(node14); node10.children.Add(node5); node10.children.Add(node9); node10.children.Add(node15); node11.children.Add(node6); node11.children.Add(node12); node11.children.Add(node16); node12.children.Add(node7); node12.children.Add(node11); node12.children.Add(node13); node12.children.Add(node17); node13.children.Add(node8); node13.children.Add(node12); node13.children.Add(node14); node13.children.Add(node18); node14.children.Add(node9); node14.children.Add(node13); node14.children.Add(node15); node14.children.Add(node19); node15.children.Add(node10); node15.children.Add(node14); node15.children.Add(node20); node16.children.Add(node11); node16.children.Add(node17); node16.children.Add(node21); node17.children.Add(node12); node17.children.Add(node16); node17.children.Add(node18); node17.children.Add(node22); node18.children.Add(node13); node18.children.Add(node17); node18.children.Add(node19); node18.children.Add(node23); node19.children.Add(node14); node19.children.Add(node18); node19.children.Add(node20); node19.children.Add(node24); node20.children.Add(node15); node20.children.Add(node19); node20.children.Add(node25); node21.children.Add(node16); node21.children.Add(node22); node22.children.Add(node17); node22.children.Add(node21); node22.children.Add(node23); node23.children.Add(node18); node23.children.Add(node22); node23.children.Add(node24); node24.children.Add(node19); node24.children.Add(node23); node24.children.Add(node25); node25.children.Add(node20); node25.children.Add(node24); if ((tempList[i].doors & 1) == 1 && tempList[i].place != 4) { node23.children.Add(InstancePathNode(p0 + new Vector3(3, 0, 0), null)); } if ((tempList[i].doors & 2) == 2 && tempList[i].place != 3) { node3.children.Add(InstancePathNode(p0 + new Vector3(-3, 0, 0),null)); } if ((tempList[i].doors & 4) == 4 && tempList[i].place != 2) { node11.children.Add(InstancePathNode(p0 + new Vector3(0, 0, -3),null)); } if ((tempList[i].doors & 8) == 8 && tempList[i].place != 1) { node15.children.Add(InstancePathNode(p0 + new Vector3(0, 0, 3),null)); } } else if (tempList[i].roadType == RoadType.Way) { PathNode node = InstancePathNode(p0, mapNode); if ((tempList[i].doors & 1) == 1) { PathNode node1 = InstancePathNode(p0 + new Vector3(1, 0, 0), mapNode); PathNode node2 = InstancePathNode(p0 + new Vector3(2, 0, 0), mapNode); PathNode node3 = InstancePathNode(p0 + new Vector3(3, 0, 0),null); node.children.Add(node1); node1.children.Add(node); node1.children.Add(node2); node2.children.Add(node1); node2.children.Add(node3); } if ((tempList[i].doors & 2) == 2) { PathNode node1 = InstancePathNode(p0 + new Vector3(-1, 0, 0), mapNode); PathNode node2 = InstancePathNode(p0 + new Vector3(-2, 0, 0), mapNode); PathNode node3 = InstancePathNode(p0 + new Vector3(-3, 0, 0),null); node.children.Add(node1); node1.children.Add(node); node1.children.Add(node2); node2.children.Add(node1); node2.children.Add(node3); } if ((tempList[i].doors & 4) == 4) { PathNode node1 = InstancePathNode(p0 + new Vector3(0, 0, -1), mapNode); PathNode node2 = InstancePathNode(p0 + new Vector3(0, 0, -2), mapNode); PathNode node3 = InstancePathNode(p0 + new Vector3(0, 0, -3),null); node.children.Add(node1); node1.children.Add(node); node1.children.Add(node2); node2.children.Add(node1); node2.children.Add(node3); } if ((tempList[i].doors & 8) == 8) { PathNode node1 = InstancePathNode(p0 + new Vector3(0, 0, 1), mapNode); PathNode node2 = InstancePathNode(p0 + new Vector3(0, 0, 2), mapNode); PathNode node3 = InstancePathNode(p0 + new Vector3(0, 0, 3),null); node.children.Add(node1); node1.children.Add(node); node1.children.Add(node2); node2.children.Add(node1); node2.children.Add(node3); } } else if (tempList[i].roadType == RoadType.Hall) { } } } public void SetPathNode(Vector3 pos) { if (m_PathDic.ContainsKey(pos)) { m_PathDic.Remove(pos); } else { Debug.Log("!!!!!!!!!!!!!!!!!!!!不在路径节点字典里" + pos); } List temp = new List (m_PathDic.Values); for (int i = 0; i < temp.Count; i++) { for (int j = 0; j < temp[i].children.Count; j++) { if (temp[i].children[j].position == pos) { temp[i].children.RemoveAt(j); } } } } public Vector3 GetPosInteger(Vector3 pos) { return new Vector3(Mathf.RoundToInt(pos.x), 0, Mathf.RoundToInt(pos.z)); } public Stack GetShortestPath(Vector3 origin,Vector3 destination) { List PathNodeList = new List (m_PathDic.Values); Stack tempStack = new Stack (); Queue tempQueue = new Queue (); PathNode node = null; for (int i = 0; i < PathNodeList.Count; i++) { PathNodeList[i].distance = int.MaxValue; PathNodeList[i].state = 0; PathNodeList[i].progenitor = null; PathNodeList[i].rearguard = null; } PathNode startNode = null; if (m_PathDic.ContainsKey(origin)) { startNode = m_PathDic[origin]; } else { Debug.Log("!!!!!!!!!!!!!!!!!!!!!!不在PathNode字典" + origin); } startNode.distance = 0; startNode.state = 0; startNode.progenitor = null; startNode.rearguard = null; tempQueue.Enqueue(startNode); while (tempQueue.Count > 0 && node == null) { PathNode tempNode = tempQueue.Dequeue(); foreach (PathNode item in tempNode.children) { if (item.state == 0) { item.state = 1; if (MazeManager.Instance.OccupyPosDic.ContainsValue(new Vector2(item.position.x,item.position.z)) && !VectorTool.ApproximatelyXZ(item.position, PlayerController.Instance.TargetPos, 0.1f)) continue; item.distance = tempNode.distance + 1; item.progenitor = tempNode; if (VectorTool.ApproximatelyXZ(item.position, GetPosInteger(destination), 0.1f)) { node = item; break; } tempQueue.Enqueue(item); } } tempNode.state = 2; } while (node != null && node.progenitor != null) { tempStack.Push(node.position); node = node.progenitor; } return tempStack; } public List GetRoomPathNode(MapNode node) { List PathNodeList = new List (m_PathDic.Values); List OccupyPosList = new List (MazeManager.Instance.OccupyPosDic.Values); List CurrentPosList = new List (); for (int i = 0; i < PathNodeList.Count; i++) { if (PathNodeList[i].mapNode == node) { CurrentPosList.Add(PathNodeList[i].position); } } return CurrentPosList; } }
********************************
using System.Collections.Generic; using UnityEngine; namespace Game.Map { public enum NodeType { Error, Empty, Boss, Path } public enum RoadType { Error = 0, ////// 走廊 /// Way = 65, ////// 普通房间 /// Room = 66, ////// 大厅 /// Hall = 67, ////// Boss房 /// Boss = 68, } public enum RoomType { Error, ////// 被锁的房间 /// Locked, ////// 机关房 /// OrganRoom, ////// 宝藏 /// TreasureRoom, ////// 有一个宝箱的房间 /// TreasureBox, ////// 矿石房 /// OreHeapRoom, ////// 草药房 /// HerbRoom, } ////// 地图上的每个节点 /// public class MapNode : MonoBehaviour { public string IconName; public Vector2 index; public Vector2 position; public GameObject build; ////// 道路类型 /// A:走廊,B:房间,C:大厅,D:Boss房 /// public RoadType roadType; ////// 房间类型,roadType必定为‘B’ /// A:被锁,B:机关房,C:宝藏房,D,宝箱房 /// public RoomType roomType; ////// 正确的机关的下标 /// 0,左上,顺时针旋转 /// public int keyOrganIndex; public OrganBehaviour[] Organs; public MapNode parent; public Listchildren; public int distance; public int doors; public byte place; public NodeType nodeType; /// /// 门 /// public int[] doorsData; ////// 带锁的门 /// public GameObject[] lockDoors; ////// 房间里的物品 /// public ListGoods; /// /// 采集点 /// public CollectionBehaviour[] Collection; ////// 房间里的怪物 /// public Listmonsters; /// /// 地图房间 /// public int MapRoom; public ListMapIcon; public List MapMonster; /// /// 地图房间 /// public int MiniMapRoom; public ListMiniMapIcon; public List MiniMapMonster; private Vector3 m_startPos; public Vector3 StartPos { get { return m_startPos; } } public void Init(Vector2 pos) { this.index = pos; parent = null; roomType = 0; //children = new List (); distance = 0; place = 0; this.nodeType = NodeType.Empty; doors = 0; doorsData = new int[4]; lockDoors = new GameObject[4]; Goods = new List (); MapRoom = -1; MapIcon = new List (); MapMonster = new List (); MiniMapRoom = -1; MiniMapIcon = new List (); MiniMapMonster = new List (); } private void Start() { m_startPos = transform.position; index = MazeManager.Instance.GetPosAsKey(transform.position); MazeManager.Instance.AddMapNode(this); MiniMap.Instance.NewCreateMiniMap(this); HideOnFar(); //gameObject.SetActive(false); } private void SetRoadType() { if (name.Contains("A")) { roadType = RoadType.Way; } else if (name.Contains("B")) { roadType = RoadType.Room; } else if (name.Contains("C")) { roadType = RoadType.Hall; } else { roadType = RoadType.Boss; } } private void HideMonsters() { if (monsters == null) return; for (int i = 0; i < monsters.Count; i++) { monsters[i].gameObject.SetActive(false); } } private void MonstersActive() { if (monsters == null) return; for (int i = 0; i < monsters.Count; i++) { monsters[i].gameObject.SetActive(true); monsters[i].Init(true); MonsterManager.Instance.AddMonster(monsters[i]); } } /// /// 废弃代码 /// private void TreasureBoxsActive() { if (Goods == null) return; for (int i = 0; i < Goods.Count; i++) { TreasureBox box = Goods[i]; box.gameObject.SetActive(true); //box.Init(box.transform.position,transform.localEulerAngles,BoxType.Close); MiniMap.Instance.CreateBoxIcon(this, gameObject); } } public void Refresh() { SetRoadType(); CreateWallPoster(); CreateDoorframeOfRoom(); } public void CreateWallPoster() { Transform room = transform; if (Random.Range(0, 10) < 3 || roadType == RoadType.Way || roadType == RoadType.Boss) return; int length = roadType == RoadType.Boss ? Random.Range(3, 10) : Random.Range(1, 3); for (int i = 0; i < length; i++) { string posterName = "LevelArt/" + MazeManager.SceneType + "/WallPoster" + (Random.Range(0, 2) == 1 ? "" : "2"); GameObject prefab = ResourcesManager.Instance.LoadResource(posterName) as GameObject; GameObject poster = Instantiate(prefab); poster.transform.SetParent(room); poster.transform.localPosition = Vector3.zero; int temp = Random.Range(0, 4); int dir = 1 << temp; switch (roadType) { case RoadType.Way: //node.PastePosterOnTheWay(poster.transform, dir); break; case RoadType.Room: PastePosterOnTheRoom(poster.transform, dir); break; case RoadType.Hall: PastePosterOnTheRoom(poster.transform, dir); break; default: break; } } } private const float posterPos = 2.495f; ////// 在房间内贴广告 /// /// /// /// public void PastePosterOnTheRoom(Transform poster, int dir) { float temp = 0; if ((doors & dir) == dir)//this wall has a door { if (roadType == RoadType.Hall && place == dir) { temp = Random.Range(0, 2) == 1 ? 2 : -2; } else { temp = Random.Range(0, 2) == 1 ? Random.Range(-2f, -1f) : Random.Range(1f, 2f); } } else { temp = Random.Range(-2, 2); } switch (dir) { case 1: poster.localPosition = new Vector3(posterPos, 0, temp); poster.localEulerAngles = new Vector3(0, 270, 0); break; case 2: poster.localPosition = new Vector3(-posterPos, 0, temp); poster.localEulerAngles = new Vector3(0, 90, 0); break; case 4: poster.localPosition = new Vector3(temp, 0, -posterPos); poster.localEulerAngles = Vector3.zero; break; case 8: poster.localPosition = new Vector3(temp, 0, posterPos); poster.localEulerAngles = new Vector3(0, 180, 0); break; default: Debug.LogError("dir Error:" + dir); break; } } ////// 创建门框 /// public void CreateDoorframeOfRoom() { Transform room = transform; /* * 只有走廊没有门框 * 房间与房间相连时,父节点生成门框 */ if (roadType != RoadType.Way) { Vector3 pos; int angle; int actor = roadType == RoadType.Boss ? 3 : 1; if ((doors & 1) == 1 && (parent == null || parent.roadType == RoadType.Way || parent.index.x <= index.x))//right { angle = 180; pos = new Vector3(2.5f * actor, 0, 0); CreateOneDoorframe(room, pos, angle, actor); } if ((doors & 2) == 2 && (parent == null || parent.roadType == RoadType.Way || parent.index.x >= index.x))//left { angle = 0; pos = new Vector3(-2.5f * actor, 0, 0); CreateOneDoorframe(room, pos, angle, actor); } if ((doors & 4) == 4 && (parent == null || parent.roadType == RoadType.Way || parent.index.y >= index.y))//down { angle = -90; pos = new Vector3(0, 0, -2.5f * actor); CreateOneDoorframe(room, pos, angle, actor); } if ((doors & 8) == 8 && (parent == null || parent.roadType == RoadType.Way || parent.index.y <= index.y))//up { angle = 90; pos = new Vector3(0, 0, 2.5f * actor); CreateOneDoorframe(room, pos, angle, actor); } } } private void CreateOneDoorframe(Transform room, Vector3 pos, int angle, int actor) { GameObject prefab = ResourcesManager.Instance. LoadResource("LevelArt/" + MazeManager.SceneType + "/" + "Doorframe" + (actor == 3 ? "2" : "")) as GameObject; GameObject doorframe = Instantiate(prefab); doorframe.transform.SetParent(room); doorframe.transform.localPosition = pos; doorframe.transform.localEulerAngles = new Vector3(0, angle, 0); } public void SetStart(MapNode node) { ListmapNodes = new List (); for (int i = 0; i < children.Count; i++) { if (children[i] != null) { mapNodes.Add(children[i]); } children[i] = null; } if (parent != null && parent != node) mapNodes.Add(parent); parent = node; if (node != null) { for (int i = 0; i < mapNodes.Count; i++) { if (mapNodes[i] == node) { mapNodes.RemoveAt(i); } } } for (int i = 0; i < mapNodes.Count; i++) { children[i] = mapNodes[i]; } //for (int i = 0; i < children.Length; i++) //{ // MapNode mapNode = children[i]; // if (node == null && mapNode == null) // { // children[i] = parent; // parent = null; // } // if (mapNode == null) continue; // if (mapNode == node) // { // children[i] = parent; // parent = node; // } //} for (int i = 0; i < children.Count; i++) { if (children[i] != null) { children[i].SetStart(this); } } } public void ShowOnStartPos() { transform.position = m_startPos; } public void HideOnFar() { transform.position = new Vector3(transform.position.x, transform.position.y + 1000, transform.position.z); } } }