/// <summary> /// This calculates a force repelling from the other neighbors /// </summary> /// <returns></returns> protected Vector2D calculateSeparationVector() { //iterate through all the neighbors and calculate the vector from the Vector2D steeringForce = new Vector2D(); List <PlayerBase> allPlayers = AutoList <PlayerBase> .GetAllMembers(); for (int playerIndex = 0; playerIndex < allPlayers.Count; playerIndex++) { //make sure this agent isn't included in the calculations and that //the agent is close enough if (allPlayers[playerIndex] != _player && allPlayers[playerIndex].SteeringBehaviors.Tagged) { Vector2D toAgent = _player.Position - allPlayers[playerIndex].Position; //scale the force inversely proportional to the agents distance //from its neighbor. if (Math.Abs(toAgent.Length) > double.Epsilon) { steeringForce += Vector2D.Vec2DNormalize(toAgent) / toAgent.Length; } } } return(steeringForce); }
/// <summary> /// Tags any vehicles within a predefined radius /// </summary> protected void findNeighbours() { List <PlayerBase> allPlayers = AutoList <PlayerBase> .GetAllMembers(); for (int playerIndex = 0; playerIndex < allPlayers.Count; playerIndex++) { //first clear any current tag allPlayers[playerIndex].SteeringBehaviors.Tagged = false; //work in distance squared to avoid sqrts Vector2D to = allPlayers[playerIndex].Position - _player.Position; if (to.LengthSquared < (_viewDistance * _viewDistance)) { allPlayers[playerIndex].SteeringBehaviors.Tagged = true; } }//next }
public PlayerBase(SoccerTeam homeTeam, int homeRegionIndex, Vector2D heading, Vector2D velocity, double mass, double maxForce, double maxSpeed, double maxTurnRate, double scale, PlayerRoles role) : base(homeTeam.Pitch.GetRegion(homeRegionIndex).VectorCenter, scale * 10.0, velocity, maxSpeed, heading, mass, new Vector2D(scale, scale), maxTurnRate, maxForce) { _playerRole = role; _team = homeTeam; _distanceToBallSquared = double.MaxValue; _homeRegionIndex = homeRegionIndex; _kickoffRegionIndex = homeRegionIndex; Vector2D[] player = new Vector2D[4] { new Vector2D(-3, 8), new Vector2D(3, 10), new Vector2D(3, -10), new Vector2D(-3, -8) }; for (int vertexIndex = 0; vertexIndex < 4; vertexIndex++) { _vecPlayerVB.Add(player[vertexIndex]); //set the bounding radius to the length of the //greatest extent if (Math.Abs(player[vertexIndex].X) > BoundingRadius) { BoundingRadius = Math.Abs(player[vertexIndex].X); } if (Math.Abs(player[vertexIndex].Y) > BoundingRadius) { BoundingRadius = Math.Abs(player[vertexIndex].Y); } } //set up the steering behavior class _steeringBehaviors = new SteeringBehaviors(this, Ball); //a player's start target is its start position (because it's just waiting) _steeringBehaviors.Target = _team.Pitch.GetRegion(_homeRegionIndex).VectorCenter; AutoList <PlayerBase> .GetAllMembers().Add(this); _defaultHomeRegionIndex = _homeRegionIndex; }
public override void Update() { //run the logic for the current state _stateMachine.Update(); //calculate the combined force from each steering behavior Vector2D SteeringForce = _steeringBehaviors.CalculateSteeringForce(); //Acceleration = Force/Mass Vector2D Acceleration = SteeringForce / Mass; //update velocity Velocity += Acceleration; //make sure player does not exceed maximum velocity Velocity.Truncate(MaxSpeed); //update the position Position += Velocity; //enforce a non-penetration constraint if desired if (ParameterManager.Instance.NonPenetrationConstraint) { EntityManager.EnforceNonPenetrationContraint <PlayerBase>(this, AutoList <PlayerBase> .GetAllMembers()); } //update the heading if the player has a non zero velocity if (!Velocity.IsZero) { Heading = Vector2D.Vec2DNormalize(Velocity); Side = Heading.Perp; } //look-at vector always points toward the ball if (!Team.Pitch.GoalKeeperHasBall) { _lookAt = Vector2D.Vec2DNormalize(Ball.Position - Position); } }
public override void Update() { //run the logic for the current state _stateMachine.Update(); //calculate the combined steering force _steeringBehaviors.CalculateSteeringForce(); //if no steering force is produced decelerate the player by applying a //braking force if (_steeringBehaviors.SteeringForce.IsZero) { double brakingRate = 0.8; Velocity = Velocity * brakingRate; } //the steering force's side component is a force that rotates the //player about its axis. We must limit the rotation so that a player //can only turn by PlayerMaxTurnRate rads per update. double TurningForce = _steeringBehaviors.SideComponent; if (TurningForce < -ParameterManager.Instance.PlayerMaxTurnRate) { TurningForce = -ParameterManager.Instance.PlayerMaxTurnRate; } if (TurningForce > ParameterManager.Instance.PlayerMaxTurnRate) { TurningForce = ParameterManager.Instance.PlayerMaxTurnRate; } //rotate the heading vector Transformations.Vec2DRotateAroundOrigin(Heading, TurningForce); //make sure the velocity vector points in the same direction as //the heading vector Velocity = Heading * Velocity.Length; //and recreate m_vSide Side = Heading.Perp; //now to calculate the acceleration due to the force exerted by //the forward component of the steering force in the direction //of the player's heading Vector2D accel = Heading * _steeringBehaviors.ForwardComponent / Mass; Velocity += accel; //make sure player does not exceed maximum velocity Velocity.Truncate(MaxSpeed); //update the position Position += Velocity; //enforce a non-penetration constraint if desired if (ParameterManager.Instance.NonPenetrationConstraint) { EntityManager.EnforceNonPenetrationContraint(this, AutoList <PlayerBase> .GetAllMembers()); } }
public void Dispose() { AutoList <PlayerBase> .GetAllMembers().Remove(this); }