/// <summary> /// Finds path along a 2D grid /// </summary> /// <param name="solidityMap">2D array of solids</param> /// <param name="start">Vector of starting position</param> /// <param name="end">Vector of ending position</param> /// <returns>List of points to follow</returns> public static List <Vector2> FindPath(bool[,] solidityMap, Vector2 start, Vector2 end) { var finalPath = new List <Vector2>(); if (!(start.X < solidityMap.GetLength(0) - 1 && start.X > 0 && start.Y < solidityMap.GetLength(1) - 1 && start.Y > 0 && end.X < solidityMap.GetLength(0) - 1 && end.X > 0 && end.Y < solidityMap.GetLength(1) - 1 && end.Y > 0)) { return(finalPath); } var closed = new List <Node>(); var open = new List <Node> { new Node(start) }; bool done = false; Node currentNode = open[0]; int trials = 0; while (!done && trials < 1000) { trials++; var lowestF = int.MaxValue; for (int i = 0; i < open.Count; i++) { if (Math.Abs(open[i].Pos.X - end.X) + Math.Abs(open[i].Pos.Y - end.Y) < lowestF) { lowestF = (int)(Math.Abs(open[i].Pos.X - end.X) + Math.Abs(open[i].Pos.Y - end.Y)); currentNode = open[i]; } } if (currentNode.Pos.X == end.X && currentNode.Pos.Y == end.Y) { done = true; } else { closed.Add(currentNode); open.Remove(currentNode); for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { if ((i != 0 || j != 0) && !DirectionHelper.IsDiagonal(DirectionHelper.VectorToDirection(new Vector2(i, j))) && currentNode.Pos.X + i > 0 && currentNode.Pos.Y + j > 0 && currentNode.Pos.X + i < solidityMap.GetLength(0) && currentNode.Pos.Y + j < solidityMap.GetLength(1) && !solidityMap[(int)currentNode.Pos.X + i, (int)currentNode.Pos.Y + j]) { bool isInClosed = false; Node closedNode = null; for (int k = 0; k < closed.Count; k++) { if (closed[k].Pos.X == currentNode.Pos.X + i && closed[k].Pos.Y == currentNode.Pos.Y + j) { isInClosed = true; closedNode = closed[k]; break; } } if (isInClosed && closedNode.G > currentNode.G + 1) { closedNode.G = currentNode.G + 1; closedNode.Parent = currentNode; } else if (!isInClosed) { bool isInOpen = false; Node openNode = null; for (int k = 0; k < open.Count; k++) { if (open[k].Pos.X == currentNode.Pos.X + i && open[k].Pos.Y == currentNode.Pos.Y + j) { isInOpen = true; openNode = open[k]; break; } } if (isInOpen && openNode.G > currentNode.G + 1) { openNode.G = currentNode.G + 1; openNode.Parent = currentNode; } else if (!isInOpen) { Node n = new Node(new Vector2(currentNode.Pos.X + i, currentNode.Pos.Y + j), currentNode); n.G = currentNode.G + 1; open.Add(n); trials = 0; } } } } } } } while (currentNode.Parent != null) { finalPath.Add(currentNode.Pos); currentNode = currentNode.Parent; } finalPath.Add(currentNode.Pos); finalPath.Reverse(); return(finalPath); }
/// <summary> /// Moves the entity /// </summary> /// <param name="ihn">Ihn entity is contained in</param> /// <param name="entity">Entity to update</param> public void Update(Ihn ihn, Entity entity) { var pos = entity.GetComp <ComponentPosition>(); var move = entity.GetComp <ComponentKeyboardMovement>(); ComponentVelocity velocity = null; if (entity.HasComp <ComponentVelocity>()) { velocity = entity.GetComp <ComponentVelocity>(); } bool n; bool e; bool s; bool w; n = KeyHelper.KeyDown(Keys.W); e = KeyHelper.KeyDown(Keys.D); s = KeyHelper.KeyDown(Keys.S); w = KeyHelper.KeyDown(Keys.A); Vector2 momentum = new Vector2(); if (velocity == null) { pos.X += e ? move.Speed * move.HorizontalModifier : 0; momentum.X += e ? move.Speed * move.HorizontalModifier : 0; if (CollisionHelper.Colliding(ihn, entity)) { pos.X -= e ? move.Speed * move.HorizontalModifier : 0; } pos.X += w ? -move.Speed * move.HorizontalModifier : 0; momentum.X += w ? -move.Speed * move.HorizontalModifier : 0; if (CollisionHelper.Colliding(ihn, entity)) { pos.X -= w ? -move.Speed * move.HorizontalModifier : 0; } pos.Y += s ? move.Speed * move.VerticalModifier : 0; momentum.Y += s ? move.Speed * move.VerticalModifier : 0; if (CollisionHelper.Colliding(ihn, entity)) { pos.Y -= s ? move.Speed * move.VerticalModifier : 0; } pos.Y += n ? -move.Speed * move.VerticalModifier : 0; momentum.Y += n ? -move.Speed * move.VerticalModifier : 0; if (CollisionHelper.Colliding(ihn, entity)) { pos.Y -= n ? -move.Speed * move.VerticalModifier : 0; } } else { velocity.X += e ? move.Speed * move.HorizontalModifier : 0; momentum.X += e ? move.Speed * move.HorizontalModifier : 0; velocity.X += w ? -move.Speed * move.HorizontalModifier : 0; momentum.X += w ? -move.Speed * move.HorizontalModifier : 0; velocity.Y += s ? move.Speed * move.VerticalModifier : 0; momentum.Y += s ? move.Speed * move.VerticalModifier : 0; velocity.Y += n ? -move.Speed * move.VerticalModifier : 0; momentum.Y += n ? -move.Speed * move.VerticalModifier : 0; } if (entity.HasComp <ComponentDirection>() && (momentum.X != 0 || momentum.Y != 0)) { var dir = entity.GetComp <ComponentDirection>(); dir.Dir = DirectionHelper.VectorToDirection(momentum); } }