/// <summary> /// Stop movement /// </summary> /// <param name="physics">The physics component of the thinking character</param> public void Stop(ref PhysicsComponent2D physics) { physics.SetTargetValues(true, null, null, null); }
/// <summary> /// Evade movement /// Code is based on the code in the AI book /// </summary> /// <param name="physics">The physics component of the thinking character</param> public void Evade(ref PhysicsComponent2D physics) { if (targetVelocity.Length() == 0) { Flee(ref physics); return; } float maxPrediction = 0.1f; float prediction; Vector2 direction = targetPosition - physics.Position; float distance = direction.Length(); float speed = physics.Velocity.Length(); if (speed <= distance / maxPrediction) { prediction = maxPrediction; } else { prediction = distance / speed; } Vector2 targetPos = targetPosition; targetPos += targetVelocity * prediction; // Pursue normally targetPos = (targetPos - physics.Position); physics.SetTargetValues(false, targetPos, null, null); }
/// <summary> /// Wander movement /// </summary> /// <param name="physics">The physics component of the thinking character</param> public void Wander(ref PhysicsComponent2D physics) { Vector2 direction; float angle; if (physics.Direction.Length() == 0) { float x, y; do { x = Game1.random.Next(-10, 11); } while (x == 0); do { y = Game1.random.Next(-10, 11); } while (y == 0); direction = new Vector2(x, y); if (direction.LengthSquared() > 0) direction.Normalize(); } else { do { angle = MathHelper.ToRadians(5 * (float)normallyDistributedRandomNumber()); Vector2 previousDirection = physics.Direction; direction.X = (float)Math.Cos(angle) * previousDirection.X - (float)Math.Sin(angle) * previousDirection.Y; direction.Y = (float)Math.Sin(angle) * previousDirection.X + (float)Math.Cos(angle) * previousDirection.Y; if (direction.LengthSquared() > 0) direction.Normalize(); } while (direction.Length() == 0); } // Seek normally physics.SetTargetValues(false, direction, null, null); }
/// <summary> /// Flee movement /// </summary> /// <param name="physics">The physics component of the thinking character</param> public void Flee(ref PhysicsComponent2D physics) { // Flee normally Vector2 toFlee = (physics.Position - targetPosition); physics.SetTargetValues(false, toFlee, null, null); }
/// <summary> /// Seek movement /// </summary> /// <param name="physics">The physics component of the thinking character</param> public void Seek(ref PhysicsComponent2D physics) { // Seek normally physics.SetTargetValues(false, targetPosition - physics.Position, null, null); }
/// <summary> /// Align to the desired orientation /// Code is based on the code in the AI book /// </summary> /// <param name="physics">Physics component of the target</param> private void align(ref PhysicsComponent2D physics) { float rotation = MathHelper.WrapAngle(targetOrientation - physics.Orientation); float rotationSize = Math.Abs(rotation); if (rotationSize < arrivalRadiusRotation) { physics.SetTargetValues(targetOrientation, -Math.Sign(physics.Rotation) * physics.MaxAngularAcceleration); return; } if (rotationSize > slowDownRadiusRotation) { targetRotation = physics.MaxRotation; } else { targetRotation = physics.MaxRotation * rotationSize / slowDownRadiusRotation; } targetRotation *= rotation / rotationSize; float angular = (targetRotation - physics.Rotation) / timeToTarget; float angularAcceleration = Math.Abs(angular); if (angularAcceleration > physics.MaxAngularAcceleration) { angular /= angularAcceleration; angular *= physics.MaxAngularAcceleration; } physics.SetTargetValues(targetOrientation, angular); }
/// <summary> /// Steering arrive to the target /// Code is based on the code in the AI book /// </summary> /// <param name="physics">Physics component of the target</param> private void steeringArrive(ref PhysicsComponent2D physics) { Vector2 direction = targetPosition - physics.Position; float distance = direction.Length(); float speed; if (distance < arrivalRadius) { return; } if (distance > slowDownRadius) { speed = physics.MaxVelocity; } else { speed = physics.MaxVelocity * distance / slowDownRadius; } Vector2 velocity = direction; if(velocity.LengthSquared() > 0) velocity.Normalize(); velocity *= speed; Vector2 targetAcceleration = velocity - physics.Velocity; targetAcceleration /= timeToTarget; if (targetAcceleration.Length() > physics.MaxAcceleration) { if (targetAcceleration.LengthSquared() > 0) targetAcceleration.Normalize(); targetAcceleration *= physics.MaxAcceleration; } physics.SetTargetValues(false, velocity, null, targetAcceleration); }
/// <summary> /// Kinematic arrive to the target /// Code is based on the code in the AI book /// </summary> /// <param name="physics">Physics component of the target</param> private void kinematicArrive(ref PhysicsComponent2D physics) { Vector2 velocity = targetPosition - physics.Position; if (velocity.Length() < arrivalRadius) { return; } velocity /= timeToTarget; if (velocity.Length() > physics.MaxVelocity) { if(velocity.LengthSquared() > 0) velocity.Normalize(); velocity *= physics.MaxVelocity; } physics.SetTargetValues(false, velocity, velocity, null); }