コード例 #1
0
ファイル: Unit.cs プロジェクト: nubington/bill
        // 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;
        }
コード例 #2
0
ファイル: Unit.cs プロジェクト: nubington/bill
 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);
     }
 }
コード例 #3
0
ファイル: Unit.cs プロジェクト: nubington/bill
 public void GiveCommand(MoveCommand command)
 {
     Commands.Clear();
     Commands.Add(command);
     lastWayPoint = centerPoint;
     lastMoveDestination = command.Destination;
     //command.WayPoints = PathFinder.FindPath(CurrentPathNode, command.Destination, false);
 }
コード例 #4
0
ファイル: Unit.cs プロジェクト: nubington/bill
 //public Object WayPointsLock = new Object();
 public PathFindRequest(Unit unit, MoveCommand command, PathNode startNode, bool avoidUnits)
 {
     Unit = unit;
     Command = command;
     StartNode = startNode;
     AvoidUnits = avoidUnits;
 }
コード例 #5
0
ファイル: Unit.cs プロジェクト: nubington/bill
        /*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);
        }
コード例 #6
0
ファイル: Rts.cs プロジェクト: nubington/bill
        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));
                    }
                }
            }
        }