public RoboCop(PhysicsComponent2D phys, MovementAIComponent2D move, DrawComponent draw) { detectRadius = 400; movement = move; physics = phys; this.draw = draw; state = RoboCopState.STATIC; this.BoundingRectangle = new COMP476Proj.BoundingRectangle(phys.Position, 16, 6); draw.Play(); }
public DumbCop(PhysicsComponent2D phys, MovementAIComponent2D move, DrawComponent draw, DumbCopState pState, float radius) { movement = move; physics = phys; this.draw = draw; state = defaultState = pState; detectRadius = radius; this.BoundingRectangle = new COMP476Proj.BoundingRectangle(phys.Position, 16, 6); draw.Play(); }
public Pedestrian(PhysicsComponent2D phys, MovementAIComponent2D move, DrawComponent draw, PedestrianState pState) { movement = move; physics = phys; this.draw = draw; state = pState; behavior = PedestrianBehavior.DEFAULT; studentType = draw.animation.animationId.Substring(0, 8); this.BoundingRectangle = new COMP476Proj.BoundingRectangle(phys.Position, 16, 6); draw.Play(); }
public SmartCop(PhysicsComponent2D phys, MovementAIComponent2D move, DrawComponent draw, SmartCopState pState) { detectRadius = 400; movement = move; physics = phys; this.draw = draw; behavior = SmartCopBehavior.DEFAULT; state = defaultState = pState; this.BoundingRectangle = new COMP476Proj.BoundingRectangle(phys.Position, 16, 6); draw.Play(); }
/// <summary> /// Resolve collision between two moveable objects /// </summary> /// <param name="other">Other object colliding</param> /// <param name="overlap">Rectangle of intersection between bounding rectangles</param> public void ResolveCollision(PhysicsComponent2D other, Rectanglef overlap) { // Normal Vector2 contactNormal = position - overlap.Center; if(contactNormal.LengthSquared() > 0) contactNormal.Normalize(); // Steps outlined in the class slides float Vs = -(1 + coefficientOfRestitution) * -(Math.Abs(Vector2.Dot(velocity, contactNormal)) + Math.Abs(Vector2.Dot(other.velocity, contactNormal))); float deltaPD = (1 / mass) + (1 / other.mass); float g = Vs / deltaPD; contactNormal *= g; velocity += contactNormal / mass; movementDirection = velocity; if (movementDirection.LengthSquared() > 0) movementDirection.Normalize(); }
/// <summary> /// Look away from a point, delegated to allign /// Code is based on the code in the AI book /// </summary> public void FaceAway(ref PhysicsComponent2D physics) { Vector2 direction = physics.Position - targetPosition; if (direction.Length() == 0) { return; } targetOrientation = (float)Math.Atan2(direction.X, direction.Y); align(ref physics); }
/// <summary> /// Look where you're going, delegated to allign /// Code is based on the code in the AI book /// </summary> /// <param name="physics">The physics component of the thinking character</param> public void Look(ref PhysicsComponent2D physics) { if (physics.Velocity.Length() == 0) { return; } targetOrientation = (float)Math.Atan2(physics.Velocity.X, physics.Velocity.Y); align(ref physics); }
/// <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> /// 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> /// 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> /// 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> /// Arrive movement /// </summary> /// <param name="physics">The physics component of the thinking character</param> public void Arrive(ref PhysicsComponent2D physics) { // Call appropriate behaviour if (physics.IsSteering) { steeringArrive(ref physics); } else { kinematicArrive(ref physics); } }
/// <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> /// Checks to see whether or not the target is in a cone of perception /// Perception is based on angle and velocity (as velocity increases, /// cone size decreases) /// </summary> /// <param name="physics">Physics component of the target</param> /// <returns>Whether or not the target can be seen</returns> private bool isInPerceptionZone(ref PhysicsComponent2D physics) { Vector2 direction = targetPosition - physics.Position; if (direction.Length() == 0) { return true; } float angle = (float)Math.Atan2(direction.X, direction.Y); return (Math.Abs(angle - physics.Orientation) < (perceptionAngle / (perceptionConstant * physics.Velocity.Length() + 1))); }
/// <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); }
public Streaker(PhysicsComponent2D phys, DrawComponent draw) { physics = phys; this.draw = draw; //Initialize Components using Entitybuilder! this.BoundingRectangle = new COMP476Proj.BoundingRectangle(phys.Position, 16, 6); inputTimer = 0; recoverTimer = 0; inputDelay = 100; superFlashTimer = 0; superFlashDelay = 20000; superFlashParticles = new ParticleSpewer( phys.Position.X + draw.animation.FrameWidth / 2, phys.Position.Y + draw.animation.FrameHeight / 2, 10000, 100, 0, MathHelper.TwoPi, 500, 1000, 2, 600, 30, 60, 0.1f, 0.1f, 1, 1, true, 0.75f); danceParticles = new ParticleSpewer( phys.Position.X + draw.animation.FrameWidth / 2, phys.Position.Y + draw.animation.FrameHeight / 2, 10000, 100, 0, MathHelper.TwoPi, 50, 300, 2, 350, 180, 200, 0.25f, 0.5f, 1, 1, true, 0f); powerParticles = new ParticleSpewer( phys.Position.X + draw.animation.FrameWidth / 2, phys.Position.Y + draw.animation.FrameHeight / 2, 10000, 10, 0, MathHelper.TwoPi, 50, 300, 3, 350, 180, 200, 0.5f, 1f, 0.5f, 1, true, 0f); powerParticles.Start(); }
/// <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> /// 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); }