void OpenNode(AStarEvadeHeapNode currentNode, Vector2 direction) { AStarEvadeHeapNode newNode = GetNode(currentNode, direction); if (newNode == null || !newNode.canThrough || HaveCorver(currentNode, newNode)) { return; //如果没获取到新节点或新节点不能通行则直接return } switch (newNode.state) { case AStarEvadeNodeState.unopened: DoOpenNode(currentNode, newNode); break; case AStarEvadeNodeState.opened: if (currentNode.startToCost < newNode.nextNode.startToCost) //如果新节点已经开了但从起点到指向的节点的成本比当前节点高 { ReopenNode(currentNode, newNode); } break; case AStarEvadeNodeState.closed: break; } }
private void DoFindPath() { OpenStartNode(); while (!_openedList.isEmpty) { AStarEvadeHeapNode 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); } }
public void Reset() //寻路开始时清空成本和指向 { _state = AStarEvadeNodeState.unopened; _nextNode = null; _startToCost = 0; _toEndCost = 0; _totalCost = 0; }
void OpenStartNode() { AStarEvadeHeapNode startNode = GetNode(_startPosition); startNode.Open(_endPosition); _openedList.Set(startNode); }
public void Remove(AStarEvadeHeapNode node) { var targetSubHeap = _heap.FindFirstThroughValue(node.totalCost); targetSubHeap.RemoveFirstThroughObj(node); if (targetSubHeap.Count == 0) { _heap.RemoveFirstThroughObj(targetSubHeap); } }
Color GetNodeColor(AStarEvadeHeapNode 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(AStarEvadeHeapNode node) { MinBinaryHeap <AStarEvadeHeapNode> subHeap = _heap.FindFirstThroughValue(node.totalCost); if (subHeap != null) { subHeap.SetNode(node, node.toEndCost); } else { subHeap = new MinBinaryHeap <AStarEvadeHeapNode>(); subHeap.SetNode(node, node.toEndCost); _heap.SetNode(subHeap, node.totalCost); } }
void DisplayPath() { AStarEvadeHeapNode currentNode = _aStar.GetNode(_endPosition); if (currentNode == null || currentNode.nextNode == null) { return; } while (currentNode.nextNode != null) { AddGreen(currentNode); currentNode = currentNode.nextNode; } AddGreen(currentNode); }
string GetDirectionText(AStarEvadeHeapNode 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 AStarEvade(int width, int height) { if (width < 0) { width = 0; //防止传入负数 } if (height < 0) { height = 0; //防止传入负数 } _matrix = new AStarEvadeHeapNode[width, height]; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { _matrix[x, y] = new AStarEvadeHeapNode(x, y); } } }
void MouseMiddleDown() { Vector2 position = GetMousePosition(); AStarEvadeHeapNode node = _aStar.GetNode(position); if (node == null) { return; } if (node.canThrough) { _aStar.SetObstacle(position); } else { _aStar.RemoveObstacle(position); } DoFindPath(); }
void CloseNode(AStarEvadeHeapNode node) { _openedList.Remove(node); node.Close(); }
void ReopenNode(AStarEvadeHeapNode currentNode, AStarEvadeHeapNode openNode) { _openedList.Remove(openNode); DoOpenNode(currentNode, openNode); }
void DoOpenNode(AStarEvadeHeapNode currentNode, AStarEvadeHeapNode openNode) { openNode.Open(currentNode, _endPosition); _openedList.Set(openNode); }
bool HaveCorver(AStarEvadeHeapNode currentNode, AStarEvadeHeapNode newNode) { return(!GetNode(new Vector2(currentNode.position.x, newNode.position.y)).canThrough || !GetNode(new Vector2(newNode.position.x, currentNode.position.y)).canThrough); }
void AddGreen(AStarEvadeHeapNode currentNode) { Vector2 position = currentNode.position; _displayMatrix[(int)position.x, (int)position.y].GetComponentInChildren <Image>().color += Color.green; }
bool IsDestination(AStarEvadeHeapNode currentNode) { return(currentNode == GetNode(_endPosition)); }
public AStarEvadeHeapNode GetNode(AStarEvadeHeapNode node, Vector2 direction) { return(GetNode(node.position + direction)); }
public void Open(AStarEvadeHeapNode nextNode, Vector2 destination) { _state = AStarEvadeNodeState.opened; _nextNode = nextNode; ComputeCost(destination); }
void DisplayANode(AStarEvadeHeapNode node, GameObject displayer, float maxStartToCost, float maxToEndCost) { displayer.GetComponentInChildren <Image>().color = GetNodeColor(node, maxStartToCost, maxToEndCost); displayer.GetComponentInChildren <Text>().text = GetDirectionText(node); }