Inheritance: MovingEntity, IDisposable
コード例 #1
0
        public FieldPlayer(SoccerTeam homeTeam,
                      int homeRegionIndex,
                      State<FieldPlayer> startState,
                      Vector2D heading,
                      Vector2D velocity,
                      double mass,
                      double maxForce,
                      double maxSpeed,
                      double maxTurnRate,
                      double scale,
                      PlayerBase.PlayerRoles role)
            : base(homeTeam, homeRegionIndex, heading, velocity, mass, maxForce, maxSpeed, maxTurnRate, scale, role)
        {
            _stateMachine = new StateMachine<FieldPlayer>(this);

            if (startState != null)
            {
                _stateMachine.CurrentState = _stateMachine.PreviousState = startState;
                _stateMachine.GlobalState = GlobalPlayerState.Instance;
                _stateMachine.CurrentState.Enter(this);
            }

            _steeringBehaviors.Seperation = true;

            //set up the kick regulator
            _kickRegulator = new Regulator(ParameterManager.Instance.PlayerKickFrequency);
        }
コード例 #2
0
        public SoccerTeam(SoccerGoal homeGoal, SoccerGoal opponentsGoal, SoccerPitch pitch, SoccerTeamColor color)
        {
            _homeGoal = homeGoal;
            _opponentsGoal = opponentsGoal;
            _pitch = pitch;
            _color = color;

            _opposingTeam = null;
            _distSqToBallOfClosestPlayer = 0.0;
            _supportingPlayer = null;
            _controllingPlayer = null;
            _playerClosestToBall = null;

            _stateMachine = new StateMachine<SoccerTeam>(this);

            _stateMachine.CurrentState = DefendingState.Instance;
            _stateMachine.PreviousState = DefendingState.Instance;
            _stateMachine.GlobalState = null;

            //create the players and goalkeeper
            CreatePlayers();

            //set default steering behaviors
            foreach (PlayerBase player in _players)
            {
                player.SteeringBehaviors.Seperation = true;
            }

            _supportSpotCalculator = new SupportSpotCalculator(ParameterManager.Instance.NumSupportSpotsX, ParameterManager.Instance.NumSupportSpotsY, this);
        }
コード例 #3
0
        public SteeringBehaviors(PlayerBase player, SoccerBall ball)
        {
            _player = player;
            _ball = ball;

            _separationMultiple = ParameterManager.Instance.SeparationCoefficient;
            _viewDistance = ParameterManager.Instance.ViewDistance;
            _tagged = false;
            _interposeDist = 0.0;
            _behaviorFlags = (int)BehaviorFlags.None;

            _dribbleFeelers = new List<Vector2D>(5);

            for (int i = 0; i < _dribbleFeelers.Count; i++)
            {
                _dribbleFeelers[i] = new Vector2D();
            }
        }
コード例 #4
0
 public bool SortByReversedDistanceToOpponentsGoal(PlayerBase p1,
                                             PlayerBase p2)
 {
     return (p1.DistanceToOpposingGoal > p2.DistanceToOpposingGoal);
 }
コード例 #5
0
        /// <summary>
        ///  Tests a pass from position 'from' to position 'target' against each member
        ///  of the opposing team. Returns true if the pass can be made without
        ///  getting intercepted
        /// 
        /// </summary>
        /// <param name="from"></param>
        /// <param name="target"></param>
        /// <param name="receiver"></param>
        /// <param name="PassingForce"></param>
        /// <returns></returns>
        public bool IsPassSafeFromAllOpponents(Vector2D from,
                                                    Vector2D target,
                                                    PlayerBase receiver,
                                                    double PassingForce)
        {
            foreach (PlayerBase opponent in OpposingTeam.Players)
            {
                if (!IsPassSafeFromOpponent(from, target, receiver, opponent, PassingForce))
                {
                    return false;
                }
            }

            return true;
        }
コード例 #6
0
        /// <summary>
        ///  Three potential passes are calculated. One directly toward the receiver's
        ///  current position and two that are the tangents from the ball position
        ///  to the circle of radius 'range' from the receiver.
        ///  These passes are then tested to see if they can be intercepted by an
        ///  opponent and to make sure they terminate within the playing area. If
        ///  all the passes are invalidated the function returns false. Otherwise
        ///  the function returns the pass that takes the ball closest to the 
        ///  opponent's goal area.
        /// 
        /// </summary>
        /// <param name="passer"></param>
        /// <param name="receiver"></param>
        /// <param name="PassTarget"></param>
        /// <param name="power"></param>
        /// <returns></returns>
        public bool GetBestPassToReceiver(PlayerBase passer,
                                               PlayerBase receiver,
                                               ref Vector2D PassTarget,
                                               double power)
        {
            //first, calculate how much time it will take for the ball to reach 
            //this receiver, if the receiver was to remain motionless 
            double time = Pitch.Ball.CalucateTimeToCoverDistance(Pitch.Ball.Position,
                                                              receiver.Position,
                                                              power);

            //return false if ball cannot reach the receiver after having been
            //kicked with the given power
            if (time < 0) return false;

            //the maximum distance the receiver can cover in this time
            double InterceptRange = time * receiver.MaxSpeed;

            //Scale the intercept range
            const double ScalingFactor = 0.3;
            InterceptRange *= ScalingFactor;

            //now calculate the pass targets which are positioned at the intercepts
            //of the tangents from the ball to the receiver's range circle.
            Vector2D ip1 = new Vector2D(), ip2 = new Vector2D();

            Geometry.GetTangentPoints(receiver.Position,
                             InterceptRange,
                             Pitch.Ball.Position,
                             ip1,
                             ip2);

            const int NumPassesToTry = 3;
            Vector2D[] Passes = new Vector2D[NumPassesToTry] { ip1, receiver.Position, ip2 };


            // this pass is the best found so far if it is:
            //
            //  1. Further upfield than the closest valid pass for this receiver
            //     found so far
            //  2. Within the playing area
            //  3. Cannot be intercepted by any opponents

            double ClosestSoFar = double.MaxValue;
            bool bResult = false;

            for (int pass = 0; pass < NumPassesToTry; ++pass)
            {
                double dist = Math.Abs(Passes[pass].X - OpponentsGoal.GoalLineCenter.X);

                if ((dist < ClosestSoFar) &&
                    Pitch.PlayingArea.IsPositionInside(Passes[pass]) &&
                    IsPassSafeFromAllOpponents(Pitch.Ball.Position,
                                               Passes[pass],
                                               receiver,
                                               power))
                {
                    ClosestSoFar = dist;
                    PassTarget = Passes[pass];
                    bResult = true;
                }
            }

            return bResult;
        }
コード例 #7
0
        /// <summary>
        ///  test if a pass from 'from' to 'to' can be intercepted by an opposing player
        /// 
        /// </summary>
        /// <param name="from"></param>
        /// <param name="target"></param>
        /// <param name="receiver"></param>
        /// <param name="opp"></param>
        /// <param name="PassingForce"></param>
        /// <returns></returns>
        public bool IsPassSafeFromOpponent(Vector2D from,
                                                Vector2D target,
                                                PlayerBase receiver,
                                                PlayerBase opp,
                                                double PassingForce)
        {
            //move the opponent into local space.
            Vector2D ToTarget = target - from;
            Vector2D ToTargetNormalized = Vector2D.Vec2DNormalize(ToTarget);

            Vector2D LocalPosOpp = Transformations.PointToLocalSpace(opp.Position,
                                                   ToTargetNormalized,
                                                   ToTargetNormalized.Perp,
                                                   from);

            //if opponent is behind the kicker then pass is considered okay(this is 
            //based on the assumption that the ball is going to be kicked with a 
            //velocity greater than the opponent's max velocity)
            if (LocalPosOpp.X < 0)
            {
                return true;
            }

            //if the opponent is further away than the target we need to consider if
            //the opponent can reach the position before the receiver.
            if (Vector2D.Vec2DDistanceSq(from, target) < Vector2D.Vec2DDistanceSq(opp.Position, from))
            {
                if (receiver != null)
                {
                    if (Vector2D.Vec2DDistanceSq(target, opp.Position) >
                         Vector2D.Vec2DDistanceSq(target, receiver.Position))
                    {
                        return true;
                    }

                    else
                    {
                        return false;
                    }

                }

                else
                {
                    return true;
                }
            }

            //calculate how long it takes the ball to cover the distance to the 
            //position orthogonal to the opponents position
            double TimeForBall =
                Pitch.Ball.CalucateTimeToCoverDistance(new Vector2D(0, 0),
                                                 new Vector2D(LocalPosOpp.X, 0),
                                                 PassingForce);

            //now calculate how far the opponent can run in this time
            double reach = opp.MaxSpeed * TimeForBall +
                          Pitch.Ball.BoundingRadius +
                          opp.BoundingRadius;

            //if the distance to the opponent's y position is less than his running
            //range plus the radius of the ball and the opponents radius then the
            //ball can be intercepted
            if (Math.Abs(LocalPosOpp.Y) < reach)
            {
                return false;
            }

            return true;
        }
コード例 #8
0
        /// <summary>
        ///  The best pass is considered to be the pass that cannot be intercepted 
        ///  by an opponent and that is as far forward of the receiver as possible
        /// 
        /// </summary>
        /// <param name="passer"></param>
        /// <param name="receiver"></param>
        /// <param name="PassTarget"></param>
        /// <param name="power"></param>
        /// <param name="MinPassingDistance"></param>
        /// <returns></returns>
        public bool FindPass(PlayerBase passer,
                                 out PlayerBase receiver,
                                 out Vector2D PassTarget,
                                 double power,
                                 double MinPassingDistance)
        {

            receiver = null;
            PassTarget = null;

            double ClosestToGoalSoFar = double.MaxValue;
            Vector2D Target = new Vector2D();

            //iterate through all this player's team members and calculate which
            //one is in a position to be passed the ball 
            foreach (PlayerBase currentPlayer in _players)
            {
                //make sure the potential receiver being examined is not this player
                //and that it is further away than the minimum pass distance
                if ((currentPlayer != passer) &&
                    (Vector2D.Vec2DDistanceSq(passer.Position, currentPlayer.Position) >
                     MinPassingDistance * MinPassingDistance))
                {
                    if (GetBestPassToReceiver(passer, currentPlayer, ref Target, power))
                    {
                        //if the pass target is the closest to the opponent's goal line found
                        // so far, keep a record of it
                        double Dist2Goal = Math.Abs(Target.X - OpponentsGoal.GoalLineCenter.X);

                        if (Dist2Goal < ClosestToGoalSoFar)
                        {
                            ClosestToGoalSoFar = Dist2Goal;

                            //keep a record of this player
                            receiver = currentPlayer;

                            //and the target
                            PassTarget = Target;
                        }
                    }
                }
            }//next team member

            if (receiver != null) return true;

            else return false;
        }
コード例 #9
0
        /// <summary>
        /// sets _playerClosestToBall to the player closest to the ball
        /// </summary>
        public void CalculateClosestPlayerToBall()
        {
            double ClosestSoFar = double.MaxValue;

            for (int playerIndex = 0; playerIndex < _players.Count; playerIndex++)
            {
                //calculate the dist. Use the squared value to avoid sqrt
                double dist = Vector2D.Vec2DDistanceSq(_players[playerIndex].Position, Pitch.Ball.Position);

                //keep a record of this value for each player
                _players[playerIndex].DistanceToBallSquared = dist;

                if (dist < ClosestSoFar)
                {
                    ClosestSoFar = dist;

                    _playerClosestToBall = _players[playerIndex];
                }
            }

            _distSqToBallOfClosestPlayer = ClosestSoFar;
        }
コード例 #10
0
        /// <summary>
        /// Calculates the closest opponent to this teams goal
        /// </summary>
        public void CalculateClosestOpponentToGoal()
        {
            double ClosestSoFar = double.MaxValue;


            for (int memberIndex = 0; memberIndex < _opposingTeam.Players.Count; memberIndex++)
            {
                //calculate the dist. to home goal, remember the opponents home goal
                // is our target
                if (_opposingTeam.Players[memberIndex].PlayerRole != PlayerBase.PlayerRoles.GoalKeeper)
                {
                    double dist = _opposingTeam.Players[memberIndex].DistanceToHomeGoal;
                    if (dist < ClosestSoFar)
                    {
                        ClosestSoFar = dist;
                        _opponentClosestToGoal = _opposingTeam.Players[memberIndex];
                    }
                }
            }
        }
コード例 #11
0
 private void LostControl()
 {
     _controllingPlayer = null;
 }
コード例 #12
0
 public bool SortByReversedDistanceToOpponentsGoal(PlayerBase p1,
                                                   PlayerBase p2)
 {
     return(p1.DistanceToOpposingGoal > p2.DistanceToOpposingGoal);
 }