private ShipPath GetPathFromTreeNode(TreeNode leaf) { ShipPath path = new ShipPath(); while (leaf.parent != null) { path.AddNodeFromBeginning(leaf.node); leaf = leaf.parent; } return(path); }
public List <ShipPath> FindPath(Node from, Node to) { int maxNumPaths = 2; int numPaths = 0; List <ShipPath> allPaths = new List <ShipPath>(); List <TreeNode> nodesToExpand = new List <TreeNode>(); if (from == to) { ShipPath path = new ShipPath(); path.AppendNode(to); allPaths.Add(path); return(allPaths); } nodesToExpand.Add(new TreeNode(null, from)); while (nodesToExpand.Count > 0) { TreeNode treeNodeToExpand = nodesToExpand[0]; nodesToExpand.RemoveAt(0); List <Node> connectedNodes = GetAllConnectedNode(treeNodeToExpand.node); foreach (Node connectedNode in connectedNodes) { // This is per-path way to avoid repeatance. Consider change it to global way. if (isNodeAlreadyOnPath(connectedNode, treeNodeToExpand)) { continue; } TreeNode child = new TreeNode(treeNodeToExpand, connectedNode); if (connectedNode == to) { allPaths.Add(GetPathFromTreeNode(child)); numPaths++; if (numPaths > maxNumPaths) { return(allPaths); } } else { nodesToExpand.Add(child); } } } return(allPaths); }
public ShipPath ConcatenatePath(ShipPath path) { ShipPath newPath = new ShipPath(); foreach (Node node in this.path) { newPath.AppendNode(node); } foreach (Node node in path.path) { newPath.AppendNode(node); } return(newPath); }
/// <summary> /// Follow the Path /// </summary> /// <param name="gameTime"></param> private void FollowPath(GameTime gameTime) { // Make shure we have a valid position. if (float.IsNaN(Position.X)) { return; } // Move to the next Waypoint var distanceToNextPoint = Vector2.Distance(Position, ShipPath.Next.Cell.Center); if (distanceToNextPoint > mNextWaypointThreshold + mNextWaypointThresholdOffset) { if (Game1.mAdvancedMovements) { if (ShipPath.Next.Predecessor != null) { var nextDirection = ShipPath.Next.Cell.Center - Position; nextDirection.Normalize(); var nextNextDirection = ShipPath.Next.Predecessor.Cell.Center - ShipPath.Next.Cell.Center; nextNextDirection.Normalize(); var ammount = Math.Max(0, 0.8f - distanceToNextPoint / 16); Direction = Vector2.Lerp(nextDirection, nextNextDirection, ammount); mShipAngle = MathHelper.ToDegrees((float)Math.Atan2(Direction.Y, Direction.X)) + 180; } else { Direction = ShipPath.Next.Cell.Center - Position; mShipAngle = MathHelper.ToDegrees((float)Math.Atan2(Direction.Y, Direction.X)) + 180; } } else { Direction = ShipPath.Next.Cell.Center - Position; mShipAngle = MathHelper.ToDegrees((float)Math.Atan2(Direction.Y, Direction.X)) + 180; } // Collision avoidance Direction = CollisionAvoidance(Direction, gameTime); mShipAngle = MathHelper.ToDegrees((float)Math.Atan2(Direction.Y, Direction.X)) + 180; var addToPosition = Direction * 150 * (float)gameTime.ElapsedGameTime.TotalSeconds * ActualMovingSpeed; Position += addToPosition; } else { ShipPath.GetNextWaypoint(); mNextWaypointThresholdOffset = 0; } // Update the occupied cells. var cellAtPosition = Game1.mMapScreen.mGridMap.GetCell(Game1.mMapScreen.mGridMap.PosToGrid(Position).ToPoint()); if (mCurrentCell != cellAtPosition) { if (mCurrentCell != null) { mCurrentCell.Occupied = false; } Game1.mMapScreen.mGridMap.OccupyCell(Position, Direction); mCurrentCell = cellAtPosition; } }
private ShipSchedule PathToSchedule(ShipPath path) { double defaultShipSpeed = GameObject.Find("SceneSetting").GetComponent <SceneSetting>().ShipSpeed; double shipSpeed = defaultShipSpeed; ShipSchedule schedule = new ShipSchedule(); MapUtil mapUtil = GameObject.Find("MapUtil").GetComponent <MapUtil>(); DateTime currentTime = GameObject.Find("Timer").GetComponent <Timer>().VirtualTime; Vector2 currentPosition = new Vector2((float)ship.Ship.X, (float)ship.Ship.Y); bool unloadingScheduled = false; Node previousNode = null; foreach (Node node in path.path) { ShipMoveTask moveTask = new ShipMoveTask(); moveTask.Position = new Vector2((float)node.X, (float)node.Y); if (previousNode != null) { moveTask.connection = mapUtil.GetConnection(previousNode, node); shipSpeed = moveTask.connection.Speed; } else { shipSpeed = defaultShipSpeed; } double distance = Math.Pow(Math.Pow(node.X - currentPosition.x, 2) + Math.Pow(node.Y - currentPosition.y, 2), 0.5); TimeSpan duration = new TimeSpan(0, 0, (int)Math.Round(distance / shipSpeed)); moveTask.StartTime = currentTime; moveTask.EndTime = currentTime.Add(duration); previousNode = node; currentTime = currentTime.Add(duration); currentPosition = new Vector2((float)node.X, (float)node.Y); schedule.AppendTask(moveTask); // Unloading task double unloadingSpeed = GameObject.Find("SceneSetting").GetComponent <SceneSetting>().UnloadingSpeed; Dock dock = mapUtil.GetDockByNode(node); if (!unloadingScheduled && dock != null) { TimeSpan unloadingDuration = new TimeSpan(0, 0, (int)Math.Round(ship.Ship.cargo / unloadingSpeed)); UnloadingTask unloadingTask = new UnloadingTask(); unloadingTask.Position = currentPosition; unloadingTask.StartTime = currentTime; unloadingTask.EndTime = currentTime.Add(unloadingDuration); unloadingTask.dock = dock; currentTime = currentTime.Add(unloadingDuration); schedule.AppendTask(unloadingTask); unloadingScheduled = true; } // Task List <Node> exits = mapUtil.ExitNodes(); if (exits.Contains(node)) { VanishTask vanishTask = new VanishTask(); vanishTask.StartTime = currentTime; vanishTask.EndTime = currentTime; schedule.AppendTask(vanishTask); } } return(schedule); }