#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
}
}