// DECLARING METHODS: PATH FINDING ALGORITHM /// <summary> /// PathFinder Algorithm, searches the shortest way from the EnemyPosition to the PlayerPosition respecting Tiles with Collision /// </summary> /// <param name="vPosition">StartPosition, Pathfinder starts here</param> /// <param name="vTargetPosition">Position where the Pathfinder looks for a path to get</param> public void PathFinder(Vector2f vPosition, Vector2f vTargetPosition) { List <Node> Open; // List of Nodes to be evaluated Open = new List <Node>(); Tilez[,] tManager = MainMap.GetTileManager().GetTileArray(); int startX = (int)((vPosition.X + 25) / 50); int startY = (int)((vPosition.Y + 25) / 50); int goalX = (int)vTargetPosition.X / 50; int goalY = (int)vTargetPosition.Y / 50; Node startNode = new Node(tManager[startX, startY], new Vector2f(startX, startY), new Vector2f(goalX, goalY)); Node targetNode = new Node(tManager[goalX, goalY], new Vector2f(goalX, goalY), startNode); Open.Add(startNode); bool loop = true; // Bool used to loop until the shortest path is found Node nCurrent; // Node being currently inspected nCurrent = Open[0]; int currentindex = 0; int ilooking = 0; while (loop && ilooking < 30) { for (int x = 0; x < Open.Count; x++) { if (x == 0) { nCurrent = Open[Open.Count - 1]; } if (Open[x].iFCost <= nCurrent.iFCost) { nCurrent = Open[x]; currentindex = x; } } Open.RemoveAt(currentindex); Closed.Add(nCurrent); if (nCurrent.vPosition == targetNode.vPosition) { break; } int X = (int)nCurrent.vPosition.X; int Y = (int)nCurrent.vPosition.Y; Node[] neighbour = new Node[] { }; CreateNeighbours(X, Y, ref neighbour, tManager, nCurrent, targetNode); foreach (Node element in neighbour) { if (element.bCollision || Closed.Exists(x => x.vPosition == element.vPosition)) { continue; } if (Open.Find(x => x.vPosition == element.vPosition) == null) { element.nParent = nCurrent; Open.Add(element); } else if (element.iFCost < Open.Find(x => x.vPosition == element.vPosition).iFCost) { element.nParent = nCurrent; Open[Open.IndexOf((Open.Find(x => x.vPosition == element.vPosition)))] = element; } } ilooking++; } Node NodeWay; NodeWay = nCurrent; while (NodeWay != startNode) { NodeWay.vPosition *= 50; Path.Add(NodeWay); NodeWay = NodeWay.nParent; } }
/// <summary> /// Updates PathFinder Logic of the Archer. /// Moves the Enemy to the Player once the Pathfinding Algorithm was initiated. /// The Archer follows the created nodes, but still respects Collisions with Tiles. /// </summary> protected void PathfinderLogic() { bool MovingUp = false; bool MovingDown = false; bool MovingRight = false; bool MovingLeft = false; if (MainMap.GetTileManager().GetCollisionAt(((int)(vEntityPosition.X - 1) / 50), (int)(vEntityPosition.Y / 50)) || MainMap.GetTileManager().GetCollisionAt(((int)(vEntityPosition.X - 1) / 50), (int)((vEntityPosition.Y + 25) / 50)) || MainMap.GetTileManager().GetCollisionAt(((int)(vEntityPosition.X - 1) / 50), (int)((vEntityPosition.Y + 49) / 50))) { MovingLeft = true; } if (MainMap.GetTileManager().GetCollisionAt(((int)(vEntityPosition.X + 50) / 50), (int)(vEntityPosition.Y / 50)) || MainMap.GetTileManager().GetCollisionAt(((int)(vEntityPosition.X + 50) / 50), (int)((vEntityPosition.Y + 25) / 50)) || MainMap.GetTileManager().GetCollisionAt(((int)(vEntityPosition.X + 50) / 50), (int)((vEntityPosition.Y + 49) / 50))) { MovingRight = true; } if (MainMap.GetTileManager().GetCollisionAt(((int)(vEntityPosition.X) / 50), (int)((vEntityPosition.Y - 1) / 50)) || MainMap.GetTileManager().GetCollisionAt(((int)(vEntityPosition.X + 25) / 50), (int)((vEntityPosition.Y - 1) / 50)) || MainMap.GetTileManager().GetCollisionAt(((int)(vEntityPosition.X + 49) / 50), (int)((vEntityPosition.Y - 1) / 50))) { MovingUp = true; } if (MainMap.GetTileManager().GetCollisionAt(((int)(vEntityPosition.X) / 50), (int)((vEntityPosition.Y + 50) / 50)) || MainMap.GetTileManager().GetCollisionAt(((int)(vEntityPosition.X + 25) / 50), (int)((vEntityPosition.Y + 50) / 50)) || MainMap.GetTileManager().GetCollisionAt(((int)(vEntityPosition.X + 49) / 50), (int)((vEntityPosition.Y + 50) / 50))) { MovingDown = true; } if (Path.Count - 1 >= 0) { CurrentGoal = (Vector2i)Path[Path.Count - 1].vPosition + (Vector2i)MainMap.GetTileMapPosition() + new Vector2i(25, 25); CurrentGoalOrigin = CurrentGoal - (Vector2i)sEntity.Position; float MovementX = (CurrentGoalOrigin.X / Utilities.MakePositive(Utilities.DistanceToVectorFromOrigin(new Vector2f(CurrentGoalOrigin.X, 0)))); float MovementY = (CurrentGoalOrigin.Y / Utilities.MakePositive(Utilities.DistanceToVectorFromOrigin(new Vector2f(0, CurrentGoalOrigin.Y)))); int PositionX1 = (int)((vEntityPosition.X + MovementX) / 50); int PositionY1 = (int)((vEntityPosition.Y + MovementY) / 50); int PositionX = (int)((vEntityPosition.X) / 50); int PositionY = (int)((vEntityPosition.Y) / 50); if (!MovementX.Equals(0 / Zero)) { if (CurrentGoalOrigin.X > 0 && !MovingRight) { vEntityPosition.X += fSpeed; } if (CurrentGoalOrigin.X < 0 && !MovingLeft) { vEntityPosition.X -= fSpeed; } } if (!MovementY.Equals(0 / Zero)) { if (CurrentGoalOrigin.Y > 0 && !MovingDown) { vEntityPosition.Y += fSpeed; } if (CurrentGoalOrigin.Y < 0 && !MovingUp) { vEntityPosition.Y -= fSpeed; } } if (sEntity.Position.X - 15 <= CurrentGoal.X && sEntity.Position.X + 15 >= CurrentGoal.X && sEntity.Position.Y - 15 <= CurrentGoal.Y && sEntity.Position.Y + 15 >= CurrentGoal.Y) { Path.RemoveAt(Path.Count - 1); } RotateEnemy(ref fAngle, vRegisteredPlayerPosition + MainMap.GetTileMapPosition() + (vEnemyDirection - sEntity.Position)); } }