public static Vec2DRotateAroundOrigin ( |
||
v | ||
ang | double | |
리턴 | void |
/// <summary> /// this can be used to vary the accuracy of a player's kick. Just call it /// prior to kicking the ball using the ball's position and the ball target as /// parameters. /// /// </summary> /// <param name="BallPos"></param> /// <param name="BallTarget"></param> /// <returns></returns> public static Vector2D AddNoiseToKick(Vector2D BallPos, Vector2D BallTarget) { Random random = new Random(); double displacement = (Pi - Pi * ParameterManager.Instance.PlayerKickingAccuracy) * Utils.Math.RandomClamped(random); Vector2D toTarget = BallTarget - BallPos; Transformations.Vec2DRotateAroundOrigin(toTarget, displacement); return(toTarget + BallPos); }
public override void Execute(FieldPlayer player) { double dot = player.Team.HomeGoal.FacingDirection.GetDotProduct(player.Heading); //if the ball is between the player and the home goal, it needs to swivel // the ball around by doing multiple small kicks and turns until the player //is facing in the correct direction if (dot < 0) { //the player's heading is going to be rotated by a small amount (Pi/4) //and then the ball will be kicked in that direction Vector2D direction = player.Heading; //calculate the sign (+/-) of the angle between the player heading and the //facing direction of the goal so that the player rotates around in the //correct direction double angle = Utils.Math.Constants.QuarterPi * -1 * player.Team.HomeGoal.FacingDirection.Sign(player.Heading); Transformations.Vec2DRotateAroundOrigin(direction, angle); //this value works well whjen the player is attempting to control the //ball and turn at the same time const double KickingForce = 0.8; player.Ball.Kick(direction, KickingForce); } //kick the ball down the field else { player.Ball.Kick(player.Team.HomeGoal.FacingDirection, ParameterManager.Instance.MaxDribbleForce); } //the player has kicked the ball so he must now change state to follow it player.StateMachine.ChangeState(ChaseBallState.Instance); return; }
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()); } }