// Update is called once per frame void Update() { if (_isShouldMove) { //可以移动 Grid.NodeItem node = m_PathList [m_MoveIndex]; Vector2 position = transform.position; if (Vector2.Distance(node.pos, position) < 0.1f) { //距离够近,可以下一步 if (m_MoveIndex == m_PathList.Count - 1) { //走到尽头 _isShouldMove = false; if (m_MoveFinishCallBack != null) { m_MoveFinishCallBack(); } } m_MoveIndex++; } else { transform.position = Vector2.MoveTowards(position, node.pos, m_MoveSpeed * Time.deltaTime); } } }
// 获取 H private int getNodesH(Grid.NodeItem a, Grid.NodeItem b) { int cntX = Mathf.Abs(a.x - b.x); int cntY = Mathf.Abs(a.y - b.y); return((cntX + cntY) * 10); }
private void UpdateMoveData() { if (((this.findpath.Count > 0) && !this.issamepos(this.findpath[0])) && GameLogic.Release.MapCreatorCtrl.Bomberman_is_danger(this.findpath[0])) { this.Find(); } if (this.findpath.Count > 0) { this.UpdateDirection(); Vector3 vector = this.nextpos - base.m_Entity.position; if (vector.magnitude < 0.1f) { this.findpath.RemoveAt(0); if (this.findpath.Count > 0) { Grid.NodeItem item = this.findpath[0]; this.nextpos = GameLogic.Release.MapCreatorCtrl.GetWorldPosition(item.x, item.y); this.UpdateDirection(); } } } else { base.End(); } }
private void UpdateMoveData() { if (this.target != null) { if (this.findpath.Count > 0) { this.UpdateDirection(); Vector3 vector = this.nextpos - base.m_Entity.position; if (vector.magnitude < 0.2f) { this.findpath.RemoveAt(0); if (this.findpath.Count > 0) { Grid.NodeItem item = this.findpath[0]; this.nextpos = GameLogic.Release.MapCreatorCtrl.GetWorldPosition(item.x, item.y); this.UpdateDirection(); } } } else { this.nextpos = this.target.position; this.UpdateDirection(); } } }
private int getDistanceNodes(Grid.NodeItem a, Grid.NodeItem b) { int num = Mathf.Abs((int)(a.x - b.x)); int num2 = Mathf.Abs((int)(a.y - b.y)); return((num + num2) * 10); }
void AStarFinding(Vector3 start, Vector3 end) { Grid.NodeItem startNode = grid.getNodeItem(start); Grid.NodeItem endNode = grid.getNodeItem(end); List <Grid.NodeItem> openList = new List <Grid.NodeItem> (); HashSet <Grid.NodeItem> closeSet = new HashSet <Grid.NodeItem> (); openList.Add(startNode); while (openList.Count > 0) { Grid.NodeItem currNode = openList [0]; for (int i = 0; i < openList.Count; i++) { if (openList [i].fCost <= currNode.fCost && openList [i].hCost < currNode.hCost) { currNode = openList [i]; } } openList.Remove(currNode); closeSet.Add(currNode); if (currNode == endNode) { GeneratePath(startNode, endNode); return; } foreach (var item in grid.getNeighborhood(currNode, 1)) { if (item.isWall || closeSet.Contains(item)) { continue; } int newG = currNode.gCost + MeasureWithDiagnol(currNode, item); // 如果距离更小,或者原来不在开始列表中 if (newG < item.gCost || !openList.Contains(item)) { item.gCost = newG; item.hCost = MeasureWithDiagnol(item, endNode); item.parent = currNode; // 如果节点是新加入的,将它加入打开列表中 if (!openList.Contains(item)) { openList.Add(item); } } } } GeneratePath(startNode, null); }
private void Find() { if (this.target != null) { this.findpath = GameLogic.Release.Path.FindingPath(base.m_Entity.position, this.endpos); if (this.findpath.Count > 0) { Grid.NodeItem item = this.findpath[0]; this.nextpos = GameLogic.Release.MapCreatorCtrl.GetWorldPosition(item.x, item.y); this.UpdateDirection(); } } }
//可以不使用sqrt操作的测量,但不能使用曼哈顿距离 public int MeasureWithDiagnol(Grid.NodeItem a, Grid.NodeItem b) { int hDiff = Mathf.Abs(b.y - a.y); int wDiff = Mathf.Abs(b.x - a.x); if (hDiff >= wDiff) { return(14 * wDiff + 10 * (hDiff - wDiff)); } else { return(14 * hDiff + 10 * (wDiff - hDiff)); } }
// 获取两个节点之间的距离【对角线估价法】 int getDistanceNodes(Grid.NodeItem a, Grid.NodeItem b) { int cntX = Mathf.Abs(a.x - b.x); int cntY = Mathf.Abs(a.y - b.y); // 判断到底是那个轴相差的距离更远 if (cntX > cntY) { return(14 * cntY + 10 * (cntX - cntY)); } else { return(14 * cntX + 10 * (cntY - cntX)); } }
private List <Grid.NodeItem> generatePath(Grid.NodeItem startNode, Grid.NodeItem endNode) { List <Grid.NodeItem> lines = new List <Grid.NodeItem>(); if (endNode != null) { for (Grid.NodeItem item = endNode; item != startNode; item = item.parent) { lines.Add(item); } lines.Reverse(); } this.grid.updatePath(lines); return(lines); }
// 获取两个节点之间的距离 int getDistanceNodes(Grid.NodeItem a, Grid.NodeItem b) { int cntX = Mathf.Abs(a.x - b.x); int cntY = Mathf.Abs(a.y - b.y); // 判断到底是那个轴相差的距离更远 /*if (cntX > cntY) { * return 14 * cntY + 10 * (cntX - cntY); * } else { * return 14 * cntX + 10 * (cntY - cntX); * }*/ return((int)(Mathf.Sqrt(cntX * cntX + cntY * cntY)) * 10); }
//生成路径 void GeneratePath(Grid.NodeItem start, Grid.NodeItem end) { List <Grid.NodeItem> path = new List <Grid.NodeItem> (); if (end != null) { Grid.NodeItem temp = end; while (temp != start) { path.Add(temp); temp = temp.parent; } path.Reverse(); } grid.UpdatePath(path); }
// 生成路径 void generatePath(Grid.NodeItem startNode, Grid.NodeItem endNode) { List <Grid.NodeItem> path = new List <Grid.NodeItem>(); if (endNode != null) { Grid.NodeItem temp = endNode; while (temp != startNode) { path.Add(temp); temp = temp.parent; } // 反转路径 path.Reverse(); } // 更新路径 grid.updatePath(path); }
private void Find() { if (this.target != null) { Vector2Int num = GameLogic.Release.MapCreatorCtrl.Bomberman_get_safe_near(base.m_Entity.position); this.findpath = GameLogic.Release.Path.FindingPath(base.m_Entity.position, GameLogic.Release.MapCreatorCtrl.GetWorldPosition(num)); if (this.findpath.Count == 0) { GameLogic.Release.MapCreatorCtrl.RandomItemSide(base.m_Entity, this.range, out float num2, out float num3); this.endpos = new Vector3(num2, 0f, num3); this.findpath = GameLogic.Release.MapCreatorCtrl.Bomberman_find_path(base.m_Entity.position, this.endpos); } if (this.findpath.Count > 0) { Grid.NodeItem item = this.findpath[0]; this.checkpos = new Vector2Int(item.x, item.y); this.nextpos = GameLogic.Release.MapCreatorCtrl.GetWorldPosition(item.x, item.y); this.UpdateDirection(); } } }
// 获取 G private int getNodesG(Grid.NodeItem a, Grid.NodeItem b) { int cntX = Mathf.Abs(a.x - b.x); int cntY = Mathf.Abs(a.y - b.y); // 判断到底是那个轴相差的距离更远 if ((cntX == 0 && cntY == 1) || (cntX == 1 && cntY == 0)) { return(10); } else if (cntX == 1 && cntY == 1) { return(14); } else { Debug.LogError(" getNodesG Error"); } return(-1); }
// 生成路径 void generatePath(Grid.NodeItem startNode, Grid.NodeItem endNode) { List <Grid.NodeItem> path = new List <Grid.NodeItem>(); if (endNode != null) { Grid.NodeItem temp = endNode; while (temp != startNode) { path.Add(temp); temp = temp.parent; } // 反转路径 path.Reverse(); } // 更新路径 grid.updatePath(path); if (path.Count > 0) { m_Planner.SendMessage("OnHandleMessageMove", path); } }
// A*寻路 void FindingPath(Vector3 s, Vector3 e) { Grid.NodeItem startNode = grid.getItem(s); Grid.NodeItem endNode = grid.getItem(e); List <Grid.NodeItem> openSet = new List <Grid.NodeItem>(); // 开放集合:用来存放所有被考虑最短路径的节点 HashSet <Grid.NodeItem> closeSet = new HashSet <Grid.NodeItem>(); // 封闭集合:用来存放已经判定过最短路径的节点 openSet.Add(startNode); while (openSet.Count > 0) { Grid.NodeItem curNode = openSet[0]; // 这一步主要从开放列表中选取fCost及hCost最小的最优点 for (int i = 0, max = openSet.Count; i < max; i++) { if (openSet[i].fCost <= curNode.fCost && openSet[i].hCost < curNode.hCost) { curNode = openSet[i]; } } openSet.Remove(curNode); closeSet.Add(curNode); // 找到的目标节点,回溯路径,退出 if (curNode == endNode) { generatePath(startNode, endNode); return; } // 判断周围相邻节点,相邻节点如果不在开放列表中,加入开放列表,设置父节点为当前节点; // 相邻节点的gCost如果比经过当前节点计算的gCost大,更新这个相邻节点的gCost,并重新计算hCost,设置父节点为当前节点,如果不在开放列表中,加入开饭列表; // 主要是刷新相邻节点的gCost、hCost、父节点以及开放列表 List <Grid.NodeItem> nearNodes = grid.getNeibourhood(curNode); foreach (var item in nearNodes) { // 如果是墙或者已经在封闭列表中 if (item.isWall || closeSet.Contains(item)) { continue; } // 计算当前相领节点经当前节点与开始节点距离gCost int newCost = curNode.gCost + getDistanceNodes(curNode, item); // 如果距离更小,或者原来不在开放列表中 if (newCost < item.gCost || !openSet.Contains(item)) { // 更新与开始节点的距离 item.gCost = newCost; // 更新与终点节点的距离 item.hCost = getDistanceNodes(item, endNode); // 更新父节点为当前选定的节点 item.parent = curNode; // 如果节点不在开放列表中,将它加入开放列表中 if (!openSet.Contains(item)) { openSet.Add(item); } } } } generatePath(startNode, null); }
public List <Grid.NodeItem> FindingPath(Vector3 s, Vector3 e) { Grid.NodeItem item = this.grid.getItem(s); Grid.NodeItem endNode = this.grid.getItem(e); List <Grid.NodeItem> toRelease = ListPool <Grid.NodeItem> .Get(); HashSet <Grid.NodeItem> set = HashSetPool <Grid.NodeItem> .Get(); toRelease.Add(item); List <Grid.NodeItem> list2 = new List <Grid.NodeItem>(); while (toRelease.Count > 0) { Grid.NodeItem item3 = toRelease[0]; int num = 0; int count = toRelease.Count; while (num < count) { if ((toRelease[num].fCost <= item3.fCost) && (toRelease[num].hCost < item3.hCost)) { item3 = toRelease[num]; } num++; } toRelease.Remove(item3); set.Add(item3); if (item3 == endNode) { list2 = this.generatePath(item, endNode); break; } List <Grid.NodeItem> list3 = this.grid.getNeibourhood(item3); for (int i = 0; i < list3.Count; i++) { Grid.NodeItem item4 = list3[i]; if (!item4.isWall && !set.Contains(item4)) { int num4 = item3.gCost + this.getDistanceNodes(item3, item4); if ((num4 < item4.gCost) || !toRelease.Contains(item4)) { item4.gCost = num4; item4.hCost = this.getDistanceNodes(item4, endNode); item4.parent = item3; if (!toRelease.Contains(item4)) { toRelease.Add(item4); } } } } } if (list2.Count == 0) { list2 = this.generatePath(item, null); } ListPool <Grid.NodeItem> .Release(toRelease); HashSetPool <Grid.NodeItem> .Release(set); return(list2); }
private void Find() { if (this.target != null) { List <Vector2Int> list = new List <Vector2Int>(); Vector2Int roomXY = GameLogic.Release.MapCreatorCtrl.GetRoomXY(this.target.position); int[,] findPathRect = GameLogic.Release.MapCreatorCtrl.GetFindPathRect(); int width = GameLogic.Release.MapCreatorCtrl.width; int height = GameLogic.Release.MapCreatorCtrl.height; if ((roomXY.x <= (((float)width) / 2f)) && (roomXY.y <= (((float)height) / 2f))) { int x = (width / 2) + 1; int num5 = width; while (x < num5) { int y = (height / 2) + 1; int num7 = height; while (y < num7) { if (findPathRect[x, y] == 0) { list.Add(new Vector2Int(x, y)); } y++; } x++; } } else if ((roomXY.x <= (((float)width) / 2f)) && (roomXY.y > (((float)height) / 2f))) { int x = (width / 2) + 1; int num9 = width; while (x < num9) { int y = 0; int num11 = height / 2; while (y < num11) { if (findPathRect[x, y] == 0) { list.Add(new Vector2Int(x, y)); } y++; } x++; } } else if ((roomXY.x > (((float)width) / 2f)) && (roomXY.y <= (((float)height) / 2f))) { int x = 0; int num13 = width / 2; while (x < num13) { int y = (height / 2) + 1; int num15 = height; while (y < num15) { if (findPathRect[x, y] == 0) { list.Add(new Vector2Int(x, y)); } y++; } x++; } } else { int x = 0; int num17 = width / 2; while (x < num17) { int y = 0; int num19 = height / 2; while (y < num19) { if (findPathRect[x, y] == 0) { list.Add(new Vector2Int(x, y)); } y++; } x++; } } int num20 = GameLogic.Random(0, list.Count); Vector2Int num21 = list[num20]; this.nextpos = GameLogic.Release.MapCreatorCtrl.GetWorldPosition(num21.x, num21.y); this.findpath = GameLogic.Release.Path.FindingPath(base.m_Entity.position, this.nextpos); if (this.findpath.Count > 0) { Grid.NodeItem item = this.findpath[0]; this.nextpos = GameLogic.Release.MapCreatorCtrl.GetWorldPosition(item.x, item.y); this.UpdateDirection(); } } }
private bool issamepos(Grid.NodeItem item) => ((item.x == this.checkpos.x) && (item.y == this.checkpos.y));
// A*寻路 void FindingPath(Vector2 s, Vector2 e) { Grid.NodeItem startNode = grid.getItem(s); Grid.NodeItem endNode = grid.getItem(e); List <Grid.NodeItem> openSet = new List <Grid.NodeItem> (); HashSet <Grid.NodeItem> closeSet = new HashSet <Grid.NodeItem> (); openSet.Add(startNode); while (openSet.Count > 0) { //从 openSet 找出消耗最小的 Grid.NodeItem curNode = openSet [0]; for (int i = 0, max = openSet.Count; i < max; i++) { if (openSet [i].fCost <= curNode.fCost && openSet [i].hCost < curNode.hCost) { curNode = openSet [i]; } } //消耗最小的Node从OpenSet移走,加入CloseSet openSet.Remove(curNode); closeSet.Add(curNode); // 找到的目标节点 if (curNode == endNode) { generatePath(startNode, endNode); return; } // 判断周围节点,选择一个最优的节点 foreach (var item in grid.getNeibourhood(curNode)) { // 如果是墙或者已经在关闭列表中 if (item.isObstacle || closeSet.Contains(item)) { continue; } // 计算当前相领节点现开始节点距离 int newCost = curNode.gCost + getDistanceNodes(curNode, item); // 如果距离更小,或者原来不在开始列表中 if (newCost < item.gCost || !openSet.Contains(item)) { // 更新与开始节点的距离 item.gCost = newCost; // 更新与终点的距离 item.hCost = getDistanceNodes(item, endNode); // 更新父节点为当前选定的节点 item.parent = curNode; // 如果节点是新加入的,将它加入打开列表中 if (!openSet.Contains(item)) { openSet.Add(item); } } } } generatePath(startNode, null); }
// A*寻路 private void FindingPath(Vector3 s, Vector3 e) { Grid.NodeItem startNode = grid.getItem(s); Grid.NodeItem endNode = grid.getItem(e); List <Grid.NodeItem> openSet = new List <Grid.NodeItem>(); HashSet <Grid.NodeItem> closeSet = new HashSet <Grid.NodeItem>(); openSet.Add(startNode); while (openSet.Count > 0) { // 找到最小代价的节点 Grid.NodeItem curNode = openSet[0]; for (int i = 0, max = openSet.Count; i < max; i++) { if (openSet[i].fCost <= curNode.fCost && openSet[i].hCost < curNode.hCost) { curNode = openSet[i]; } } // 将当前最小代价的节点加入close列表,从开放列表移除 openSet.Remove(curNode); closeSet.Add(curNode); // 找到的目标节点 if (curNode == endNode) { generatePath(startNode, endNode); StartCoroutine(ShowCloseList(closeSet)); return; } // 判断周围节点,选择一个最优的节点 List <Grid.NodeItem> list = grid.getNeibourhood(curNode); foreach (var item in list) { // 如果是墙或者已经在关闭列表中 if (item.isWall || closeSet.Contains(item)) { continue; } // 计算当前相领节点现开始节点距离 //int newCost = curNode.gCost + getDistanceNodes(curNode, item); int gCost = curNode.gCost + getNodesG(curNode, item); // 如果距离更小,或者原来不在开始列表中 if (gCost < item.gCost || !openSet.Contains(item)) { // 更新与开始节点的距离 item.gCost = gCost; // 更新与终点的距离 //item.hCost = getDistanceNodes(item, endNode); item.hCost = getNodesH(item, endNode); // 更新父节点为当前选定的节点 item.parent = curNode; // 如果节点是新加入的,将它加入打开列表中 if (!openSet.Contains(item)) { openSet.Add(item); } } } } generatePath(startNode, null); }