private void TranslateNodeToVector2(aStarNode node, List <Vector2> path) { if (node.parent != null) { path.Add(node.position * Tile.size); TranslateNodeToVector2(node.parent, path); } }
private int CompareAStarNode(aStarNode x, aStarNode y) { if (x.nodeValue == y.nodeValue) { return(0); } else if (x.nodeValue < y.nodeValue) { return(-1); } else { return(1); } }
public aStarCalculator(Map map, bool debugHeuristic = false, bool debugMovmentCost = false, bool debugParent = false) { this.map = map; this.debugHeuristic = debugHeuristic; this.debugParent = debugParent; this.debugMovmentCost = debugMovmentCost; nodesList = new List <aStarNode>(); for (int x = 0; x < map.width; x++) { for (int y = 0; y < map.height; y++) { aStarNode node = new aStarNode(); node.position.X = x; node.position.Y = y; node.passable = map.CheckTilePassability(x, y); nodesList.Add(node); } } openList = new List <aStarNode>(); closedList = new List <aStarNode>(); }
private bool checkDiagonals(aStarNode diagonal1, aStarNode diagonal2) { if (diagonal1 == null) { if (diagonal2 == null) { return(true); } else { if (diagonal2.passable) { return(true); } } } else { if (diagonal1.passable) { if (diagonal2 == null) { return(true); } else { if (diagonal2.passable) { return(true); } } } } return(false); }
public List <Vector2> FindWayTo(Vector2 startingPosition, Vector2 destination, bool diagonal, Rectangle searchRect) { startingPosition = new Vector2((int)(startingPosition / Tile.size).X, (int)(startingPosition / Tile.size).Y); destination = new Vector2((int)(destination / Tile.size).X, (int)(destination / Tile.size).Y); if (startingPosition == destination) { return(null); } if (debugHeuristic) { heuristicTextList.Clear(); } if (debugMovmentCost) { movementCostTextList.Clear(); } if (debugParent) { parentImageList.Clear(); } Rectangle freshRect = new Rectangle(); for (int i = 0; i < nodesList.Count; i++) { nodesList[i].position.X = i % map.width; nodesList[i].position.Y = i / map.width; //nodesList[i].passable = map.CheckTilePassability(i % map.width, i / map.width); nodesList[i].heuristic = FindHeuristicValue(nodesList[i].position, destination); nodesList[i].movementCost = 0; nodesList[i].parent = null; if (searchRect != freshRect) { nodesList[i].inRect = new Rectangle((int)nodesList[i].position.X * Tile.size, (int)nodesList[i].position.Y * Tile.size, Tile.size, Tile.size).Intersects(searchRect); } if (debugHeuristic) { Text text = new Text(Game.content.Load <SpriteFont>("Fonts\\Debug1 small"), nodesList[i].position * Tile.size + new Vector2(20, 20), Color.White, nodesList[i].heuristic.ToString()); heuristicTextList.Add(text); } } aStarNode startingNode = nodesList[(int)(startingPosition.Y * map.width + startingPosition.X)]; startingNode.parent = null; closedList.Add(startingNode); foreach (aStarNode node in GetStarNodes(startingNode, diagonal)) { openList.Add(node); } aStarNode result = null; for (int i = 0; i < openList.Count;) { openList.Sort(CompareAStarNode); aStarNode node = openList[i]; if (node.heuristic == 10) { result = node; break; } closedList.Add(node); openList.Remove(node); foreach (aStarNode node2 in GetStarNodes(node, diagonal)) { if (!closedList.Contains(node2) && !openList.Contains(node2)) { openList.Add(node2); } } } if (debugMovmentCost || debugParent) { foreach (aStarNode node in nodesList) { if (node.movementCost != 0 && debugMovmentCost) { Text text = new Text(Game.content.Load <SpriteFont>("Fonts\\Debug1 small"), node.position * Tile.size, Color.Gold, node.movementCost.ToString()); movementCostTextList.Add(text); } if (node.parent != null && debugParent) { Picture pic = new Picture(Game.content.Load <Texture2D>("Textures\\Spritesheets\\system arrow"), node.position * Tile.size, null); int setDrawingRectY = 0; int setDrawingRectX = 0; if (node.parent.position.X < node.position.X) { setDrawingRectY = 1; setDrawingRectX = 1; } if (node.parent.position.X > node.position.X) { setDrawingRectY = 2; setDrawingRectX = 2; } if (node.parent.position.Y > node.position.Y) { setDrawingRectY = 0; } if (node.parent.position.Y < node.position.Y) { setDrawingRectY = 3; } pic.fileDrawingRect = new Rectangle(Tile.size * setDrawingRectX, Tile.size * setDrawingRectY, Tile.size, Tile.size); parentImageList.Add(pic); } } } if (result == null) { if (searchRect != freshRect) { int smallestHeuristic = closedList[0].heuristic; aStarNode smallestHeuristicNode = null; for (int i = 1; i < closedList.Count; i++) { if (closedList[i].heuristic < smallestHeuristic) { smallestHeuristic = closedList[i].heuristic; smallestHeuristicNode = closedList[i]; } } result = smallestHeuristicNode; } else { return(null); } } List <Vector2> path = new List <Vector2>(); path.Add(destination * Tile.size); TranslateNodeToVector2(result, path); openList.Clear(); closedList.Clear(); path.Reverse(); return(path); }
private List <aStarNode> GetStarNodes(aStarNode starCenter, bool diagonal) { List <aStarNode> result = new List <aStarNode>(); int starCenterIndex = nodesList.IndexOf(starCenter); int nodesListCount = nodesList.Count; int index = starCenterIndex - 1; aStarNode leftNode = null; if (index > -1 && index < nodesListCount) { leftNode = nodesList[index]; if (leftNode.passable && leftNode.inRect) { if (!openList.Contains(leftNode) && !closedList.Contains(leftNode) && leftNode.parent == null) { leftNode.parent = starCenter; leftNode.movementCost = 10 + leftNode.parent.movementCost; } result.Add(leftNode); } } index = starCenterIndex + 1; aStarNode rightNode = null; if (index > -1 && index < nodesListCount) { rightNode = nodesList[index]; if (rightNode.passable && rightNode.inRect) { if (!openList.Contains(rightNode) && !closedList.Contains(rightNode) && rightNode.parent == null) { rightNode.parent = starCenter; rightNode.movementCost = 10 + rightNode.parent.movementCost; } result.Add(rightNode); } } index = starCenterIndex - map.width; aStarNode upNode = null; if (index > -1 && index < nodesListCount) { upNode = nodesList[index]; if (upNode.passable && upNode.inRect) { if (!openList.Contains(upNode) && !closedList.Contains(upNode) && upNode.parent == null) { upNode.parent = starCenter; upNode.movementCost = 10 + upNode.parent.movementCost; } result.Add(upNode); } } index = starCenterIndex + map.width; aStarNode downNode = null; if (index > -1 && index < nodesListCount) { downNode = nodesList[index]; if (downNode.passable && downNode.inRect) { if (!openList.Contains(downNode) && !closedList.Contains(downNode) && downNode.parent == null) { downNode.parent = starCenter; downNode.movementCost = 10 + downNode.parent.movementCost; } result.Add(downNode); } } if (!diagonal) { return(result); } index = starCenterIndex - 1 - map.width; aStarNode leftUpNode; if (index > -1 && index < nodesListCount) { leftUpNode = nodesList[index]; if (leftUpNode.passable && leftUpNode.inRect && checkDiagonals(leftNode, upNode)) { if (!openList.Contains(leftUpNode) && !closedList.Contains(leftUpNode) && leftUpNode.parent == null) { leftUpNode.parent = starCenter; leftUpNode.movementCost = 14 + leftUpNode.parent.movementCost; } result.Add(leftUpNode); } } index = starCenterIndex + 1 - map.width; aStarNode rightUpNode; if (index > -1 && index < nodesListCount) { rightUpNode = nodesList[index]; if (rightUpNode.passable && rightUpNode.inRect && checkDiagonals(rightNode, upNode)) { if (!openList.Contains(rightUpNode) && !closedList.Contains(rightUpNode) && rightUpNode.parent == null) { rightUpNode.parent = starCenter; rightUpNode.movementCost = 14 + rightUpNode.parent.movementCost; } result.Add(rightUpNode); } } index = starCenterIndex - 1 + map.width; aStarNode leftDownNode; if (index > -1 && index < nodesListCount) { leftDownNode = nodesList[index]; if (leftDownNode.passable && leftDownNode.inRect && checkDiagonals(leftNode, downNode)) { if (!openList.Contains(leftDownNode) && !closedList.Contains(leftDownNode) && leftDownNode.parent == null) { leftDownNode.parent = starCenter; leftDownNode.movementCost = 14 + leftDownNode.parent.movementCost; } result.Add(leftDownNode); } } index = starCenterIndex + 1 + map.width; aStarNode rightDownNode; if (index > -1 && index < nodesListCount) { rightDownNode = nodesList[index]; if (rightDownNode.passable && rightDownNode.inRect && checkDiagonals(rightNode, downNode)) { if (!openList.Contains(rightDownNode) && !closedList.Contains(rightDownNode) && rightDownNode.parent == null) { rightDownNode.parent = starCenter; rightDownNode.movementCost = 14 + rightDownNode.parent.movementCost; } result.Add(rightDownNode); } } return(result); }