// for move command. returns true if command ended bool checkForPush(MoveCommand command) { lock (PotentialCollisionsLock) { foreach (Unit unit in PotentialCollisions) { if (Intersects(unit)) { float angle = (float)Math.Atan2(unit.centerPoint.Y - centerPoint.Y, unit.centerPoint.X - centerPoint.X); float distance = Radius + unit.Radius; float force = distance - Vector2.Distance(unit.centerPoint, centerPoint); if (unit.IsIdle && (unit.lastMoveDestination == command.Destination || unit.Contains(command.Destination))) { PushSimple(angle + (float)Math.PI, force); lastWayPoint = command.WayPoints[0]; command.NextWayPoint(this, PathFinder); if (command.WayPoints.Count == 0) { nextCommand(); return true; } } else if (Contains(command.Destination)) { PushSimple(angle + (float)Math.PI, force); lastWayPoint = command.WayPoints[0]; command.NextWayPoint(this, PathFinder); if (command.WayPoints.Count == 0) { nextCommand(); return true; } } /*if (unit.isFollowing && unit.followTarget == this) { unit.Push(this, angle, force); } else if (isFollowing && unit == followTarget) { PushSimple(angle + (float)Math.PI, force); } else*/ { //pushCount++; unit.Push(this, angle, force * .1f); PushSimple(angle + (float)Math.PI, force * .9f); } } } } return false; }
public void QueueCommand(MoveCommand command) { if (Commands.Count == 0) GiveCommand(command); else { MoveCommand previousMoveCommand = Commands[Commands.Count - 1] as MoveCommand; if (previousMoveCommand != null) command.WayPoints.Insert(0, previousMoveCommand.Destination); Commands.Add(command); } }
public void GiveCommand(MoveCommand command) { Commands.Clear(); Commands.Add(command); lastWayPoint = centerPoint; lastMoveDestination = command.Destination; //command.WayPoints = PathFinder.FindPath(CurrentPathNode, command.Destination, false); }
//public Object WayPointsLock = new Object(); public PathFindRequest(Unit unit, MoveCommand command, PathNode startNode, bool avoidUnits) { Unit = unit; Command = command; StartNode = startNode; AvoidUnits = avoidUnits; }
/*void Move(Vector2 target, GameTime gameTime) { clearPushStatus(); float moveX = Util.ScaleWithGameTime(speed.X, gameTime); float moveY = Util.ScaleWithGameTime(speed.Y, gameTime); Vector2 difference = target - centerPoint; if (Math.Abs(difference.X) < moveX && Math.Abs(difference.Y) < moveY) { this.CenterPoint = target; nextWayPoint(); return; } float angle = (float)Math.Atan2((double)(target.Y - CenterPoint.Y), (double)(target.X - CenterPoint.X)); moveX *= (float)Math.Cos(angle); moveY *= (float)Math.Sin(angle); lastMove.X = moveX; lastMove.Y = moveY; PrecisePosition += lastMove; checkForWallHit(); //foreach (Unit unit in Units) foreach (Unit unit in PotentialCollisions) { if (unit != this && Intersects(unit)) { if (isMoving) { if (unit.isIdle && unit.lastWayPoint == target) { nextWayPoint(); //Stop(); } else if (Contains(MoveTarget))// || unit.Contains(moveTarget)) { nextWayPoint(); //Stop(); } } angle = (float)Math.Atan2(unit.centerPoint.Y - centerPoint.Y, unit.centerPoint.X - centerPoint.X); float distance = Radius + unit.Radius; float force = distance - Vector2.Distance(unit.centerPoint, centerPoint); if (unit.isFollowing && unit.followTarget == this) { unit.Push(this, angle, force); } else if (isFollowing && unit == followTarget) { //Push(angle + (float)Math.PI, force); PushSimple(angle + (float)Math.PI, force); } else { isPushing = true; unit.Push(this, angle, force * .1f); PushSimple(angle + (float)Math.PI, force * .9f); //Push(angle + (float)Math.PI, force * .5f); //unit.Push(angle, force); } } } //if (instanceFrameCount % 6 == 0) // checkIfCurrentPathNodeChanged(); checkIfCloserToNextWayPointThanCurrentWayPoint(); //if (instanceFrameCount % 120 == 0) // checkIfCloserToGoalThanCurrentWayPoint(); turnTowards(target, 100 / radius, gameTime); }*/ void Move(MoveCommand command, GameTime gameTime) { clearPushStatus(); clearHitWallStatus(); Vector2 wayPoint = command.WayPoints[0]; float moveX = Util.ScaleWithGameTime(speed.X, gameTime); float moveY = Util.ScaleWithGameTime(speed.Y, gameTime); Vector2 difference = wayPoint - centerPoint; if (Math.Abs(difference.X) < moveX && Math.Abs(difference.Y) < moveY) { this.CenterPoint = wayPoint; lastWayPoint = wayPoint; command.NextWayPoint(this, PathFinder); if (command.WayPoints.Count == 0) nextCommand(); return; } float angle = (float)Math.Atan2((double)(wayPoint.Y - CenterPoint.Y), (double)(wayPoint.X - CenterPoint.X)); moveX *= (float)Math.Cos(angle); moveY *= (float)Math.Sin(angle); lastMove.X = moveX; lastMove.Y = moveY; PrecisePosition += lastMove; checkForWallHit(); if (checkForPush(command)) return; turnTowards(wayPoint, 120 / Radius, gameTime); }
void giveMoveCommand(Vector2 mousePosition) { // create move command shrinker thing Shrinker moveCommandThing; if (Unit.PathFinder.IsPointWalkable(mousePosition)) moveCommandThing = new Shrinker(mousePosition - new Vector2(moveCommandShrinkerSize / 2f, moveCommandShrinkerSize / 2f), moveCommandShrinkerSize, 10); else moveCommandThing = new Shrinker(map.FindNearestWalkableTile(mousePosition) - new Vector2(moveCommandShrinkerSize / 2f, moveCommandShrinkerSize / 2f), moveCommandShrinkerSize, 10); moveCommandThing.Texture = moveCommandTexture; // create magic box Rectangle magicBox = SelectedUnits[0]; foreach (Unit unit in SelectedUnits) magicBox = Rectangle.Union(magicBox, unit.Rectangle); // box is too big or clicked inside magic box if (magicBox.Width > magicBoxMaxSize || magicBox.Height > magicBoxMaxSize || magicBox.Contains((int)mousePosition.X, (int)mousePosition.Y)) { bool isPointWalkable = Unit.PathFinder.IsPointWalkable(mousePosition); // assign move targets to mouse position foreach (Unit unit in SelectedUnits) { // if mouse position is not in a walkable tile, find nearest walkable tile Vector2 destinationPoint; if (isPointWalkable) destinationPoint = mousePosition; else destinationPoint = map.FindNearestWalkableTile(mousePosition); // not holding shift if (keyboardState.IsKeyUp(Keys.LeftShift)) { //float distanceToDestination = Vector2.Distance(unit.CurrentPathNode.Tile.CenterPoint, destinationPoint); //if (distanceToDestination <= unit.Diameter) //unit.GiveCommand(new MoveCommand(destinationPoint, 1)); //else MoveCommand command = new MoveCommand(destinationPoint, 1); unit.GiveCommand(command); Unit.PathFinder.AddPathFindRequest(unit, command, unit.CurrentPathNode, false); } // holding shift else { //float distanceBetweenCurrentAndNewMoveTarget = Vector2.Distance(unit.FinalMoveDestination, destinationPoint); //if (distanceBetweenCurrentAndNewMoveTarget <= unit.Diameter) // unit.QueueCommand(new MoveCommand(destinationPoint, 1)); //else MoveCommand command = new MoveCommand(destinationPoint, 1); unit.QueueCommand(command); //Unit.PathFinder.AddPathFindRequest(unit, command, unit.CurrentPathNode); } } } // clicked outside magic box else { // make destination box and keep in screen Rectangle destBox = magicBox; destBox.X = (int)mousePosition.X - destBox.Width / 2; destBox.Y = (int)mousePosition.Y - destBox.Height / 2; // calculate angle from magic box to destination box float angle = (float)Math.Atan2(destBox.Center.Y - magicBox.Center.Y, destBox.Center.X - magicBox.Center.X); float angleX = (float)Math.Cos(angle); float angleY = (float)Math.Sin(angle); float distance = Vector2.Distance(new Vector2(magicBox.Center.X, magicBox.Center.Y), new Vector2(destBox.Center.X, destBox.Center.Y)); // assign move targets based on angle foreach (Unit unit in SelectedUnits) { // if mouse position is not in a walkable tile, find nearest walkable tile Vector2 destinationPoint = unit.CenterPoint + new Vector2(distance * angleX, distance * angleY); if (!Unit.PathFinder.IsPointWalkable(destinationPoint)) destinationPoint = map.FindNearestWalkableTile(destinationPoint); // not holding shift if (keyboardState.IsKeyUp(Keys.LeftShift)) { //float distanceToDestination = Vector2.Distance(unit.CurrentPathNode.Tile.CenterPoint, destinationPoint); //if (distanceToDestination <= unit.Diameter) // unit.GiveCommand(new MoveCommand(destinationPoint, 1)); //else MoveCommand command = new MoveCommand(destinationPoint, 1); unit.GiveCommand(command); Unit.PathFinder.AddPathFindRequest(unit, command, unit.CurrentPathNode, false); } // holding shift else { //float distanceBetweenCurrentAndNewMoveTarget = Vector2.Distance(unit.FinalMoveDestination, destinationPoint); //if (distanceBetweenCurrentAndNewMoveTarget <= unit.Diameter) // unit.QueueCommand(new MoveCommand(destinationPoint, 1)); //else unit.QueueCommand(new MoveCommand(destinationPoint, 1)); } } } }