private int Heuristic(Node n) { Vector2 distance = destination - n.nodePosition; var x = (int) distance.X; var y = (int) distance.Y; x = x < 0 ? x*-1 : x; y = y < 0 ? y*-1 : y; return (x + y)*10; }
private Node GetLowestFNode() { var bestNode = new Node(); foreach (Node n in openList) { if (bestNode.Equals(new Node())) bestNode = n; else { if (n.F < bestNode.F) bestNode = n; } } return bestNode; }
private void AddEnemyNodesToClosedList() { ClearTemporaryClosedTiles(); if (GameObjects != null) { foreach (GameObject obj in GameObjects) { if ((obj is Enemy)) { var n = new Node(MapHelper.GetTileFromPixels(obj.Position)) {Temporary = true}; if (!IsInClosedList(n.nodePosition)) closedList.Add(n); } } } }
private void CheckAdjascentNodes(Node parentNode) { var node = parentNode.nodePosition; var nodes = new List<Node>(); #region GetNearbyNodes // esquerda if (node.X > 0) { var vct = new Vector2(node.X - 1, node.Y); int factor = map[(int) vct.Y, (int) vct.X] == (int) CollisionValues.Slower80pc ? (int) MovementType.Adjascent*5 : (int) MovementType.Adjascent; nodes.Add(new Node {nodePosition = vct, G = parentNode.G + factor, ParentNode = node}); //cellLeft = new Vector2(node.X - 1, node.Y); } // esquerda cima if ((node.X > 0) && (node.Y > 0)) { var vct = new Vector2(node.X - 1, node.Y - 1); int factor = 14; factor = map[(int) vct.Y, (int) vct.X] == (int) CollisionValues.Slower80pc ? factor*5 : factor; nodes.Add(new Node {nodePosition = vct, G = parentNode.G + factor, ParentNode = node}); //cellUpLeft = new Vector2(node.X - 1, node.Y - 1); } // esquerda baixo if ((node.X > 0) && (node.Y < height - 1)) { var vct = new Vector2(node.X - 1, node.Y + 1); int factor = 14; factor = map[(int) vct.Y, (int) vct.X] == (int) CollisionValues.Slower80pc ? factor*5 : factor; nodes.Add(new Node {nodePosition = vct, G = parentNode.G + factor, ParentNode = node}); //cellDownLeft = new Vector2(node.X - 1, node.Y + 1); } // cima if (node.Y > 0) { var vct = new Vector2(node.X, node.Y - 1); int factor = 10; factor = map[(int) vct.Y, (int) vct.X] == (int) CollisionValues.Slower80pc ? factor*5 : factor; nodes.Add(new Node {nodePosition = vct, G = parentNode.G + factor, ParentNode = node}); //cellUp = new Vector2(node.X, node.Y - 1); } // direita cima if ((node.Y > 0) && (node.X < width - 1)) { var vct = new Vector2(node.X + 1, node.Y - 1); int factor = 14; factor = map[(int) vct.Y, (int) vct.X] == (int) CollisionValues.Slower80pc ? factor*5 : factor; nodes.Add(new Node {nodePosition = vct, G = parentNode.G + factor, ParentNode = node}); //cellUpRight = new Vector2(node.X + 1, node.Y - 1); } // baixo if (node.Y < height - 1) { var vct = new Vector2(node.X, node.Y + 1); int factor = 10; factor = map[(int) vct.Y, (int) vct.X] == (int) CollisionValues.Slower80pc ? factor*5 : factor; nodes.Add(new Node {nodePosition = vct, G = parentNode.G + factor, ParentNode = node}); //cellDown = new Vector2(node.X, node.Y + 1); } // direita baixo if ((node.Y < height - 1) && (node.X < width - 1)) { var vct = new Vector2(node.X + 1, node.Y + 1); int factor = 10; factor = map[(int) vct.Y, (int) vct.X] == (int) CollisionValues.Slower80pc ? factor*5 : factor; nodes.Add(new Node {nodePosition = vct, G = parentNode.G + factor, ParentNode = node}); //cellDownRight = new Vector2(node.X + 1, node.Y + 1); } //direita if (node.X < width - 1) { var vct = new Vector2(node.X + 1, node.Y); int factor = 10; factor = map[(int) vct.Y, (int) vct.X] == (int) CollisionValues.Slower80pc ? factor*5 : factor; nodes.Add(new Node {nodePosition = vct, G = parentNode.G + factor, ParentNode = node}); //cellRight = new Vector2(node.X + 1, node.Y); } #endregion // Verifico todos os nós adjascentes foreach (Node n in nodes) { // Se o nó existe e não está intransponivel if (IsPassable(n.nodePosition)) //map[(int)n.nodePosition.Y, (int)n.nodePosition.X] != (int)CollisionValues.Impassable) { if (cutCorners || !IsCuttingCorner(node, n.nodePosition)) { // Se o nó não está na closed list if (!IsInClosedList(n.nodePosition)) { Node nOpen = GetFromOpenList(n.nodePosition); // Se o nó já está na open list if (!nOpen.Equals(new Node())) { int g = n.G; if (g < nOpen.G) { Node newN = nOpen; newN.ParentNode = n.ParentNode; newN.G = g; newN.H = Heuristic(n); newN.F = n.H + n.G; openList.Remove(nOpen); openList.Add(newN); } } else { Node newN = n; newN.H = Heuristic(n); newN.F = newN.H + n.G; openList.Add(newN); } } } } } currentNode = GetLowestFNode(); }
public void ProcessSearch() { if (destination == player || destination.X < 0 || destination.Y < 0 || width <= destination.X || height <= destination.Y || map[(int) Destination.Y, (int) Destination.X] == (int) CollisionValues.Impassable) { SearchStatus = SearchStatus.NoPath; } var steps = 0; do { if (openList.Count == 0) { var playerNode = new Node(player) {ParentNode = new Vector2(-1, -1)}; openList.Add(playerNode); CheckAdjascentNodes(playerNode); openList.Remove(playerNode); closedList.Add(playerNode); } else { AddEnemyNodesToClosedList(); openList.Remove(currentNode); CheckAdjascentNodes(currentNode); closedList.Add(currentNode); if (currentNode.nodePosition == destination) searchStatus = SearchStatus.PathFound; } steps++; } while (searchStatus == SearchStatus.Searching && steps < stepsPerUpdate); if (searchStatus == SearchStatus.PathFound) { Node n = GetFromClosedList(destination); path.Add(n.nodePosition); do { n = GetFromClosedList(n.ParentNode); path.Add(n.nodePosition); } while (n.ParentNode != player && !n.Equals(new Node()) && n.ParentNode != new Vector2(-1, -1)); } }