What you’re describing is a textbook use of polymorphism.
Say you have a projectile class, Projectile
. This class describes the behaviors of any projectile.
Let’s take look at this simple class:
public class Projectile extends Entity
{
// Set default values for the base projectile.
protected var _speed:Number = 100;
protected var _size:int = 10;
protected var _velocity:Point;
public function Projectile() { }
/**
* Initializes the projectile with a position and an angle of fire.
* @param xLocation The x-location of the projectile.
* @param yLocation The y-location of the projectile.
* @param angle The angle, in degrees, of fire.
*/
public function init(xLocation:int, yLocation:int, angle:Number):void
{
// Children can set their graphics, size and speed before final setup is done.
x = xLocation;
y = yLocation;
// Save our projectile velocity based on angle and speed.
// Doing this once prevents the need to recalculate sines and cosines constantly.
_velocity = new Point(_speed * Math.cos(FP.RAD * angle), _speed * Math.sin(FP.RAD * angle));
// Create our projectile's hitbox based on size.
setHitbox(_size, _size);
}
override public function update():void
{
// During update, move the projectile.
x += FP.elapsed * _velocity.x;
y += FP.elapsed * _velocity.y;
}
}
Notice how it does the rough setup for any projectile. Now, we want a small, fast projectile, Bullet
, and a large, slow projectile, Missle
. If we inherrit from Projectile
, we need to make minimal changes.
public class Bullet extends Projectile
{
public function Bullet() { }
override public function init(xLocation:int, yLocation:int, angle:Number):void
{
_speed = 500;
_size = 2;
graphic = new Image(BULLET_IMAGE);
super.init(xLocation, yLocation, angle);
}
}
public class Missle extends Projectile
{
public function Bullet() { }
override public function init(xLocation:int, yLocation:int, angle:Number):void
{
_speed = 50;
_size = 25;
graphic = new Image(MISSLE_IMAGE);
super.init(xLocation, yLocation, angle);
}
}
Now, we can use the fact that both Bullet
and Missle
are children of Projectile
when creating Weapon
. Here’s the important bits:
public class Weapon
{
/** The type of Projectile to fire. */
public var equippedProjectile:Class;
...
public function fire():void
{
// Error check to make sure the equippedProjectile is a Projectile.
if (Projectile(equippedProjectile))
{
// Determine angle and location...
var xLocation:int = ...
var yLocation:int = ...
var angle:Number = ...
// ...and FIRE!
Projectile(FP.world.create(equippedProjectile)).init(xLocation, yLocation, angle);
}
}
}
Now, your weapon will fire anything that extends Projectile
. If you want to change what you fire, you just set your equippedProjectile
property on Weapon
.
// Equip missles!
myWeapon.equippedProjectile = Missles;
// Too close for rockets, switching to guns!
myWeapon.equippedProjectile = Bullet;
This is all well and good, but if you want Weapon
to fire something that isn’t a projectile (like a shield gun…), you’ll want to look at creating an interface…