private void DoFindPath() { OpenStartNode(); while (!_openedList.isEmpty) { AStarEightDirectionsHeapNode currentNode = _openedList.GetMinimumCostNode(); if (IsDestination(currentNode)) { break; } OpenNode(currentNode, Vector2.up); OpenNode(currentNode, new Vector2(1, 1)); OpenNode(currentNode, Vector2.right); OpenNode(currentNode, new Vector2(1, -1)); OpenNode(currentNode, Vector2.down); OpenNode(currentNode, new Vector2(-1, -1)); OpenNode(currentNode, Vector2.left); OpenNode(currentNode, new Vector2(-1, 1)); CloseNode(currentNode); } }
void OpenNode(AStarEightDirectionsHeapNode currentNode, Vector2 direction) { AStarEightDirectionsHeapNode newNode = GetNode(currentNode, direction); if (newNode == null || !newNode.canThrough) { return; //如果没获取到新节点或新节点不能通行则直接return } switch (newNode.state) { case AStarEightDirectionsNodeState.unopened: DoOpenNode(currentNode, newNode); break; case AStarEightDirectionsNodeState.opened: if (currentNode.startToCost < newNode.nextNode.startToCost) //如果新节点已经开了但从起点到指向的节点的成本比当前节点高 { ReopenNode(currentNode, newNode); } break; case AStarEightDirectionsNodeState.closed: break; } }
public void Reset() //寻路开始时清空成本和指向 { _state = AStarEightDirectionsNodeState.unopened; _nextNode = null; _startToCost = 0; _toEndCost = 0; _totalCost = 0; }
void OpenStartNode() { AStarEightDirectionsHeapNode startNode = GetNode(_startPosition); startNode.Open(_endPosition); _openedList.Set(startNode); }
public void Remove(AStarEightDirectionsHeapNode node) { var targetSubHeap = _heap.FindFirstThroughValue(node.totalCost); targetSubHeap.RemoveFirstThroughObj(node); if (targetSubHeap.Count == 0) { _heap.RemoveFirstThroughObj(targetSubHeap); } }
Color GetNodeColor(AStarEightDirectionsHeapNode node, float maxStartToCost, float maxToEndCost) { if (!node.canThrough) { return(Color.black); } Color nodeRed = Color.red * node.startToCost / maxStartToCost; Color nodeBlue = Color.blue * node.toEndCost / maxToEndCost; return(nodeRed + nodeBlue + Color.gray * 0.5f); }
public void Set(AStarEightDirectionsHeapNode node) { MinBinaryHeap <AStarEightDirectionsHeapNode> subHeap = _heap.FindFirstThroughValue(node.totalCost); if (subHeap != null) { subHeap.SetNode(node, node.toEndCost); } else { subHeap = new MinBinaryHeap <AStarEightDirectionsHeapNode>(); subHeap.SetNode(node, node.toEndCost); _heap.SetNode(subHeap, node.totalCost); } }
void DisplayPath() { AStarEightDirectionsHeapNode currentNode = _aStar.GetNode(_endPosition); if (currentNode == null || currentNode.nextNode == null) { return; } while (currentNode.nextNode != null) { AddGreen(currentNode); currentNode = currentNode.nextNode; } AddGreen(currentNode); }
string GetDirectionText(AStarEightDirectionsHeapNode node) { if (node == null || node.nextNode == null) { return(""); } Vector2 direction = node.nextNode.position - node.position; if (direction == Vector2.up) { return("↑"); } if (direction == Vector2.right) { return("→"); } if (direction == Vector2.down) { return("↓"); } if (direction == Vector2.left) { return("←"); } if (direction == new Vector2(-1, -1)) { return("↙"); } if (direction == new Vector2(-1, 1)) { return("↖"); } if (direction == new Vector2(1, -1)) { return("↘"); } if (direction == new Vector2(1, 1)) { return("↗"); } return(""); }
public void Pathfind_CanFind_NoObstacle() { AStarEightDirections aStar = new AStarEightDirections(7, 7); Vector2 startPosition = new Vector2(0, 0); Vector2 endPosition = new Vector2(6, 6); aStar.FindPath(startPosition, endPosition); /* * 0 0 0 0 ↘ ↓ E * * 0 0 0 ↘ ↓ ↙ ← * * 0 0 ↘ ↓ ↙ ← ↖ * * 0 ↘ ↓ ↙ ← ↖ 0 * * ↘ ↓ ↙ ← ↖ 0 0 * * ↓ ↙ ← ↖ 0 0 0 * * S ← ↖ 0 0 0 0 */ AStarEightDirectionsHeapNode[,] matrix = aStar.matrix; AStarEightDirectionsHeapNode[,] nextNodes = new AStarEightDirectionsHeapNode[7, 7] { { null, matrix[0, 0], matrix[1, 1], null, null, null, null }, { matrix[0, 0], matrix[0, 0], matrix[1, 1], matrix[2, 2], null, null, null }, { matrix[1, 1], matrix[1, 1], matrix[1, 1], matrix[2, 2], matrix[3, 3], null, null }, { null, matrix[2, 2], matrix[2, 2], matrix[2, 2], matrix[3, 3], matrix[4, 4], null }, { null, null, matrix[3, 3], matrix[3, 3], matrix[3, 3], matrix[4, 4], matrix[5, 5] }, { null, null, null, matrix[4, 4], matrix[4, 4], matrix[4, 4], matrix[5, 5] }, { null, null, null, null, matrix[5, 5], matrix[5, 5], matrix[5, 5] } }; for (int x = 0; x < 7; x++) { for (int y = 0; y < 7; y++) { Assert.AreEqual(nextNodes[y, x], aStar.matrix[x, y].nextNode); //二维数组赋值是按照横竖x的方式进行的,也就是说上面的矩阵写错了,要转置,这就是一个用 [y, x] 一个用 [x, y] 的原因 } } }
public AStarEightDirections(int width, int height) { if (width < 0) { width = 0; //防止传入负数 } if (height < 0) { height = 0; //防止传入负数 } _matrix = new AStarEightDirectionsHeapNode[width, height]; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { _matrix[x, y] = new AStarEightDirectionsHeapNode(x, y); } } }
void MouseMiddleDown() { Vector2 position = GetMousePosition(); AStarEightDirectionsHeapNode node = _aStar.GetNode(position); if (node == null) { return; } if (node.canThrough) { _aStar.SetObstacle(position); } else { _aStar.RemoveObstacle(position); } DoFindPath(); }
void ReopenNode(AStarEightDirectionsHeapNode currentNode, AStarEightDirectionsHeapNode openNode) { _openedList.Remove(openNode); DoOpenNode(currentNode, openNode); }
bool IsDestination(AStarEightDirectionsHeapNode currentNode) { return(currentNode == GetNode(_endPosition)); }
void AddGreen(AStarEightDirectionsHeapNode currentNode) { Vector2 position = currentNode.position; _displayMatrix[(int)position.x, (int)position.y].GetComponentInChildren <Image>().color += Color.green; }
void DoOpenNode(AStarEightDirectionsHeapNode currentNode, AStarEightDirectionsHeapNode openNode) { openNode.Open(currentNode, _endPosition); _openedList.Set(openNode); }
void CloseNode(AStarEightDirectionsHeapNode node) { _openedList.Remove(node); node.Close(); }
void DisplayANode(AStarEightDirectionsHeapNode node, GameObject displayer, float maxStartToCost, float maxToEndCost) { displayer.GetComponentInChildren <Image>().color = GetNodeColor(node, maxStartToCost, maxToEndCost); displayer.GetComponentInChildren <Text>().text = GetDirectionText(node); }
public void Open(AStarEightDirectionsHeapNode nextNode, Vector2 destination) { _state = AStarEightDirectionsNodeState.opened; _nextNode = nextNode; ComputeCost(destination); }
public AStarEightDirectionsHeapNode GetNode(AStarEightDirectionsHeapNode node, Vector2 direction) { return(GetNode(node.position + direction)); }