// 计算点周围可以选择的点 private List <NodeOffset> ClacRoundPoint(PathNode pn) { var mapWidth = this.Width; var mapHeight = this.Height; var tiles = this.GetTiles(); RoundNodes.Clear(); for (int i = 0; i < offsets.Length; ++i) { NodeOffset offset = offsets[i]; int x = pn.grid.x + offset.x; if (x < 0 || x >= mapWidth) { continue; } int y = pn.grid.z + offset.y; if (y < 0 || y >= mapHeight) { continue; } int index = y * mapWidth + x; if (closeDic.ContainsKey(index)) { continue; } if (!CanWalk(tiles[x, y])) { continue; } // 忽略拐角拌脚点 斜方向 if (Mathf.Abs(offset.y) + Mathf.Abs(offset.x) > 1) { if (!CanWalk(tiles[x, y - offset.y]) || !CanWalk(tiles[x - offset.x, y])) { continue; } } RoundNodes.Add(offset); } return(RoundNodes); }
public bool GetPathDistance(int fromGridX, int fromGridZ, int toGridX, int toGridZ, out List <MapGrid> path) { var mapWidth = this.Width; var mapHeight = this.Height; //var tiles = this.GetTiles(); path = new List <MapGrid>(); if (CanWalk(tiles[fromGridX, fromGridZ]) == false) { return(false); } if (CanWalk(tiles[toGridX, toGridZ]) == false) { return(false); } // 同一个点也导出路径 if (fromGridX == toGridX && fromGridZ == toGridZ) { path.Add(new MapGrid() { x = fromGridX, z = fromGridZ }); path.Add(new MapGrid() { x = toGridX, z = toGridZ }); return(true); } ClearPath(); PathNode pnTo = new PathNode();//m_PathNodePool.Alloc(); pnTo.Init(toGridZ * mapWidth + toGridX, 0, 0, 0); PathNode pnFrom = new PathNode();//m_PathNodePool.Alloc(); pnFrom.Init(fromGridZ * mapWidth + fromGridX, 0, 0, 0); openDic.Add(pnFrom.index, pnFrom); InsertToList(pnFrom); totalDic.Add(pnFrom.index, pnFrom); while (openDic.Count > 0) { if (open_list.First == null) { break; } PathNode pn = open_list.First.Value; if (pn == null) { break; } closeDic.Add(pn.index, pn); openDic.Remove(pn.index); RemoveFromList(pn); if (pn.index == pnTo.index) { break; } List <NodeOffset> offsets = ClacRoundPoint(pn); if (offsets.Count <= 0) { openDic.Remove(pn.index); RemoveFromList(pn); continue; } for (int i = 0; i < offsets.Count; ++i) { NodeOffset offset = offsets[i]; int x = pn.grid.x + offset.x; if (x < 0 || x >= mapWidth) { continue; } int y = pn.grid.z + offset.y; if (y < 0 || y >= mapHeight) { continue; } int index = y * mapWidth + x; if (closeDic.ContainsKey(index)) { continue; } PathNode pntmp = null; float g = pn.g + offset.distance; //if (openDic.ContainsKey(index)) if (openDic.TryGetValue(index, out pntmp)) { pntmp = openDic[index]; if (g < pntmp.g) { pntmp.parentIndex = pn.index; RemoveFromList(pntmp); pntmp.setG(g); InsertToList(pntmp); } } else { pntmp = new PathNode();//m_PathNodePool.Alloc(); pntmp.Init(index, pn.index, 0, 0); openDic[index] = pntmp; totalDic[index] = pntmp; pntmp.h = GetDistance(pntmp, pnTo);//Math.Abs(Vector2.Distance(pntmp.position, pnTo.position)); pntmp.setG(g); InsertToList(pntmp); } } } if (!closeDic.ContainsKey(pnTo.index)) { return(false); } List <MapGrid> tmpPath = new List <MapGrid>(); PathNode node = closeDic[pnTo.index]; while (node != null) { tmpPath.Add(node.grid); if (node.parentIndex == 0) { break; } node = totalDic[node.parentIndex]; } tmpPath.Reverse_NoHeapAlloc(); // 路径反转 path = tmpPath; ClearPath(); return(true); }
public List <MapGrid> GetPath(int fromGridX, int fromGridZ, int toGridX, int toGridZ, TileType validType) { List <MapGrid> path = new List <MapGrid>(); if ((this[fromGridX, fromGridZ] & validType) == 0) { return(path); } if ((this[toGridX, toGridZ] & validType) == 0) { return(path); } // 同一个点也导出路径 if (fromGridX == toGridX && fromGridZ == toGridZ) { path.Add(new MapGrid() { x = fromGridX, z = fromGridZ }); path.Add(new MapGrid() { x = toGridX, z = toGridZ }); return(path); } PathNode pnFrom = new PathNode(fromGridZ * gridXNum + fromGridX, 0, 0, 0, this); PathNode pnTo = new PathNode(toGridZ * gridXNum + toGridX, 0, 0, 0, this); Dictionary <int, PathNode> totalDic = new Dictionary <int, PathNode>(); Dictionary <int, PathNode> openDic = new Dictionary <int, PathNode>(); Dictionary <int, PathNode> closeDic = new Dictionary <int, PathNode>(); openDic.Add(pnFrom.index, pnFrom); totalDic.Add(pnFrom.index, pnFrom); float disCornor = Mathf.Sqrt(MapGrid.Width * MapGrid.Width + MapGrid.Height * MapGrid.Height); NodeOffset[] offsets = new NodeOffset[] { new NodeOffset(gridXNum - 1, disCornor), new NodeOffset(gridXNum, MapGrid.Height), new NodeOffset(gridXNum + 1, disCornor), new NodeOffset(-1, MapGrid.Width), new NodeOffset(1, MapGrid.Width), new NodeOffset(-gridXNum - 1, disCornor), new NodeOffset(-gridXNum, MapGrid.Height), new NodeOffset(-gridXNum + 1, disCornor) }; while (openDic.Count > 0) { PathNode pn = null; foreach (KeyValuePair <int, PathNode> t in openDic) { if (pn == null) { pn = t.Value; } if (t.Value.f < pn.f) { pn = t.Value; } } closeDic.Add(pn.index, pn); openDic.Remove(pn.index); if (pn.index == pnTo.index) { break; } foreach (NodeOffset offset in offsets) { int index = pn.index + offset.offset; if (index < 0 || index > grids.Length) { continue; } if (closeDic.ContainsKey(index)) { continue; } if ((grids[index] & validType) == 0) { continue; } PathNode pntmp = null; float g = pn.g + offset.distance; if (openDic.ContainsKey(index)) { pntmp = openDic[index]; if (g < pntmp.g) { pntmp.parentIndex = pn.index; pntmp.setG(g); } } else { pntmp = new PathNode(index, pn.index, 0, 0, this); openDic[index] = pntmp; totalDic[index] = pntmp; pntmp.h = Mathf.Abs(Vector3.Distance(pntmp.position, pnTo.position)); pntmp.setG(g); } } } if (!closeDic.ContainsKey(pnTo.index)) { return(path); } List <MapGrid> tmpPath = new List <MapGrid>(); PathNode node = closeDic[pnTo.index]; while (node != null) { tmpPath.Add(node.grid); if (node.parentIndex == 0) { break; } node = totalDic[node.parentIndex]; } path = LinePathEx(tmpPath, validType); return(path); }
public List<MapGrid> GetPath(int fromGridX, int fromGridZ, int toGridX, int toGridZ, TileType validType) { List<MapGrid> path = new List<MapGrid>(); if ((this[fromGridX, fromGridZ] & validType) == 0) return path; if ((this[toGridX, toGridZ] & validType) == 0) return path; // 同一个点也导出路径 if(fromGridX == toGridX && fromGridZ == toGridZ) { path.Add(new MapGrid(){x = fromGridX, z = fromGridZ}); path.Add(new MapGrid(){x = toGridX, z = toGridZ}); return path; } PathNode pnFrom = new PathNode(fromGridZ * gridXNum + fromGridX, 0, 0, 0, this); PathNode pnTo = new PathNode(toGridZ * gridXNum + toGridX, 0, 0, 0, this); Dictionary<int, PathNode> totalDic = new Dictionary<int, PathNode>(); Dictionary<int, PathNode> openDic = new Dictionary<int, PathNode>(); Dictionary<int, PathNode> closeDic = new Dictionary<int, PathNode>(); openDic.Add(pnFrom.index, pnFrom); totalDic.Add(pnFrom.index, pnFrom); float disCornor = Mathf.Sqrt(MapGrid.Width * MapGrid.Width + MapGrid.Height * MapGrid.Height); NodeOffset[] offsets = new NodeOffset[]{new NodeOffset(gridXNum-1, disCornor), new NodeOffset(gridXNum, MapGrid.Height),new NodeOffset(gridXNum+1, disCornor), new NodeOffset(-1, MapGrid.Width), new NodeOffset(1, MapGrid.Width), new NodeOffset(-gridXNum-1, disCornor), new NodeOffset(-gridXNum, MapGrid.Height),new NodeOffset(-gridXNum+1, disCornor)}; while(openDic.Count > 0) { PathNode pn = null; foreach(KeyValuePair<int, PathNode> t in openDic) { if (pn == null) pn = t.Value; if (t.Value.f < pn.f) pn = t.Value; } closeDic.Add(pn.index, pn); openDic.Remove(pn.index); if (pn.index == pnTo.index) break; foreach(NodeOffset offset in offsets) { int index = pn.index + offset.offset; if (index < 0 || index > grids.Length) continue; if (closeDic.ContainsKey(index)) continue; if ((grids[index] & validType) == 0) continue; PathNode pntmp = null; float g = pn.g + offset.distance; if (openDic.ContainsKey(index)) { pntmp = openDic[index]; if (g < pntmp.g) { pntmp.parentIndex = pn.index; pntmp.setG(g); } } else { pntmp = new PathNode(index, pn.index, 0, 0, this); openDic[index] = pntmp; totalDic[index] = pntmp; pntmp.h = Mathf.Abs(Vector3.Distance(pntmp.position, pnTo.position)); pntmp.setG(g); } } } if(!closeDic.ContainsKey(pnTo.index)) return path; List<MapGrid> tmpPath = new List<MapGrid>(); PathNode node = closeDic[pnTo.index]; while(node != null) { tmpPath.Add(node.grid); if(node.parentIndex == 0) break; node = totalDic[node.parentIndex]; } path = LinePathEx(tmpPath, validType); return path; }