#region File Description //----------------------------------------------------------------------------- // Projectile.cs // // Microsoft XNA Community Game Platform // Copyright (C) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- #endregion #region Using Statements using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; #endregion namespace NetRumble { /// /// Base public class for all projectiles that exist in the game. /// abstract public class Projectile : GameplayObject { #region Gameplay Data /// /// The player who fired this projectile. /// protected Ship owner; public Ship Owner { get { return owner; } } /// /// The amount that this projectile hurts it's target and those around it. /// protected float damageAmount = 0f; /// /// The radius at which this projectile hurts others when it explodes. /// protected float damageRadius = 0f; /// /// If true, this object will damage it's owner if it hits it /// protected bool damageOwner = true; /// /// The amount of time before this projectile dies on it's own. /// protected float duration = 0f; #endregion #region Initialization Methods /// /// Constructs a new projectile. /// /// The ship that fired this projectile. /// The initial direction for this projectile. protected Projectile(Ship owner, Vector2 direction) : base() { // safety-check the parameter if (owner == null) { throw new ArgumentNullException("owner"); } // apply the parameters this.owner = owner; this.velocity = direction; // speed will be applied in the subclass // initialize the graphics data this.position = owner.Position; this.rotation = (float)Math.Acos(Vector2.Dot(Vector2.UnitY, direction)); if (direction.X > 0f) { this.rotation *= -1f; } } #endregion #region Updating Methods /// /// Update the projectile. /// /// The amount of elapsed time, in seconds. public override void Update(float elapsedTime) { // projectiles can "time out" if (duration > 0f) { duration -= elapsedTime; if (duration < 0f) { Die(null, false); } } base.Update(elapsedTime); } #endregion #region Drawing Methods /// /// Draw the projectile. /// /// The amount of elapsed time, in seconds. /// The SpriteBatch object used to draw. public abstract void Draw(float elapsedTime, SpriteBatch spriteBatch); #endregion #region Interaction /// /// Defines the interaction between this projectile and a target GameplayObject /// when they touch. /// /// The GameplayObject that is touching this one. /// True if the objects meaningfully interacted. public override bool Touch(GameplayObject target) { // check the target, if we have one if (target != null) { // don't bother hitting any power-ups if (target is PowerUp) { return false; } // don't hit the owner if the damageOwner flag isn't set if ((this.damageOwner == false) && (target == owner)) { return false; } // don't hit other projectiles from the same ship Projectile projectile = target as Projectile; if ((projectile != null) && (projectile.Owner == this.Owner)) { return false; } // damage the target target.Damage(this, this.damageAmount); } // either we hit something or the target is null - in either case, die Die(target, false); return base.Touch(target); } /// /// Kills this projectile, in response to the given GameplayObject. /// /// The GameplayObject responsible for the kill. /// /// If true, the object dies without any further effects. /// public override void Die(GameplayObject source, bool cleanupOnly) { if (active) { if (!cleanupOnly) { CollisionManager.Explode(this, source, damageAmount, Position, damageRadius, damageOwner); } } base.Die(source, cleanupOnly); } #endregion } }