public SteeringBehavior(MovingEntity entity) { for (int i = 0; i < m_Feelers.Length; i++) m_Feelers[i] = new Vector2(); Walls = new List<Wall2D>(); m_Entity = entity; }
internal void CheckBounds(MovingEntity movingEntity) { if (movingEntity.Position.X > Width) movingEntity.Position = new Vector2(Width, movingEntity.Position.Y); if (movingEntity.Position.Y > Height) movingEntity.Position = new Vector2(movingEntity.Position.X, Height); if (movingEntity.Position.X < 0) movingEntity.Position = new Vector2(0, movingEntity.Position.Y); if (movingEntity.Position.Y < 0) movingEntity.Position = new Vector2(movingEntity.Position.X,0); }
public Vector2 Calculate(MovingEntity entity) { m_SteeringForce = Vector2.Zero; m_SteeringForce += CalculateWeightedSum(entity); return m_SteeringForce; }
private Vector2 Wander(MovingEntity entity) { m_WanderTarget = Vector2.Zero; //this behavior is dependent on the update rate, so this line must //be included when using time independent framerate. double JitterThisTimeSlice = m_WanderJitter * entity.TimeElapsed.TotalSeconds; //first, add a small random vector to the target's position m_WanderTarget += new Vector2((float)(RandomClamped() * JitterThisTimeSlice), (float)(RandomClamped() * JitterThisTimeSlice)); //reproject this new vector back on to a unit circle m_WanderTarget.Normalize(); //increase the length of the vector to the same as the radius //of the wander circle m_WanderTarget *= m_WanderRadius; //move the target into a position WanderDist in front of the agent Vector2 target = m_WanderTarget + new Vector2(m_WanderDistance, 0); //project the target into world space target = PointToWorldSpace(target, entity.Heading, entity.Side, entity.Position); //and steer towards it return target - entity.Position; }
Vector2 Pursuit(MovingEntity evader) { //if the evader is ahead and facing the agent then we can just seek //for the evader's current position. Vector2 toEvader = evader.Position - m_Entity.Position; double relativeHeading = Vector2.Dot(m_Entity.Heading, evader.Heading); double direction = Vector2.Dot(toEvader, m_Entity.Heading); if ( direction > 0 && relativeHeading < -0.95) //acos(0.95)=18 degs { return Seek(evader.Position); } //Not considered ahead so we predict where the evader will be. //the lookahead time is propotional to the distance between the evader //and the pursuer; and is inversely proportional to the sum of the //agent's velocities float LookAheadTime = (float)(toEvader.Length() / (m_Entity.MaxSpeed + evader.Speed)); //now seek to the predicted future position of the evader return Seek(evader.Position + Vector2.Multiply(evader.Velocity, LookAheadTime)); }
Vector2 Evade(MovingEntity pursuer) { /* Not necessary to include the check for facing direction this time */ Vector2 ToPursuer = pursuer.Position - m_Entity.Position; //uncomment the following two lines to have Evade only consider pursuers //within a 'threat range' const double ThreatRange = 100.0; if (ToPursuer.LengthSquared() > ThreatRange * ThreatRange) return new Vector2(); //the lookahead time is propotional to the distance between the pursuer //and the pursuer; and is inversely proportional to the sum of the //agents' velocities double LookAheadTime = ToPursuer.Length() / (m_Entity.MaxSpeed + pursuer.Speed); //now flee away from predicted future position of the pursuer return Flee(pursuer.Position + pursuer.Velocity * (float)LookAheadTime); }
public Vector2 CalculateWeightedSum(MovingEntity entity) { Vector2 force = Vector2.Zero; if(entity.Behavior.HasFlag(BehaviorType.Pursuit)) force += Pursuit(Target); if (entity.Behavior.HasFlag(BehaviorType.Seek)) force += Seek(Target != null ? Target.Position : entity.TargetPosition); if (entity.Behavior.HasFlag(BehaviorType.Evade)) force += Evade(Pursuer); if (entity.Behavior.HasFlag(BehaviorType.Arrive)) force += Arrive(Target != null ? Target.Position : entity.TargetPosition, Deceleration.normal); if (entity.Behavior.HasFlag(BehaviorType.Wander)) force += Wander(Target); //broken random numbers are not random if (entity.Behavior.HasFlag(BehaviorType.Wall_avoidance)) force += WallAvoidance(Walls); return force; }
public void SetTarget(MovingEntity target) { m_Steering.Target = target; }
public void SetPursuer(MovingEntity pursuer) { m_Steering.Pursuer = pursuer; }