protected override Vector2 OnUpdateSteeringForce(float elapsedTime, Steerable movingEntity) { //if the evader is ahead and facing the agent then we can just seek //for the evader's current position. Vector2 toEvader = Evader.Position - movingEntity.Position; float relativeHeading = Vector2.Dot(movingEntity.Forward, Evader.Forward); if ((Vector2.Dot(toEvader, movingEntity.Forward) > 0) && (relativeHeading < -0.95f)) //acos(0.95)=18 degs { movingEntity.Target = Evader.Position + Offset; return(SteeringHelper.Seek(elapsedTime, movingEntity)); } //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 = toEvader.Length() / (movingEntity.MaxSpeed + Evader.Speed); //now seek to the predicted future position of the evader movingEntity.Target = Evader.Position + Evader.Velocity * lookAheadTime + Offset; return(SteeringHelper.Seek(elapsedTime, movingEntity)); }
/// <summary> /// Calculates the steering force to arrive at the target. /// </summary> public static Vector2 Arrive(float elapsedTime, Steerable movingEntity) { if (!movingEntity.Target.HasValue) { return(Vector2.Zero); } Vector2 toTarget = movingEntity.Target.Value - movingEntity.Position; // Stop when the moving entity has passed target. if (toTarget.Length() <= movingEntity.BoundingRadius + movingEntity.Skin + movingEntity.DecelerationRange) { if (movingEntity.Velocity != Vector2.Zero && Vector2.Dot(toTarget, movingEntity.Velocity) <= 0) { movingEntity.Target = null; return(Vector2.Zero); } } // Stop when the moving entity is close enough. float distance = toTarget.Length(); if (distance <= movingEntity.DecelerationRange) { movingEntity.Target = null; return(Vector2.Zero); } return(SteeringHelper.Seek(elapsedTime, movingEntity)); }
protected override Vector2 OnUpdateSteeringForce(float elapsedTime, Steerable movingEntity) { int count = 0; Vector2 center = Vector2.Zero; var boundingSphere = new BoundingSphere(new Vector3(movingEntity.Position, 0), Range); Neighbors.FindAll(ref boundingSphere, Partners); foreach (var partner in Partners) { if (partner != null && partner != movingEntity) { center += partner.Position; if (++count >= SteeringHelper.MaxAffectingEntities) { break; } } } Partners.Clear(); if (count > 0) { center /= count; movingEntity.Target = center; return(SteeringHelper.Seek(elapsedTime, movingEntity)); } return(Vector2.Zero); }
protected override Vector2 OnUpdateSteeringForce(float elapsedTime, Steerable movingEntity) { return(SteeringHelper.Seek(elapsedTime, movingEntity)); }