package game.projectiles
{
import com.cheezeworld.math.Vector2D;
import events.ImpactEvent;
import events.ModelEvent;
import flash.events.Event;
import game.enemies.Enemy;
import game.models.Model;
import game.models.MovingModel;
import game.towers.Tower;
import utils.ModelUtilities;
/**
* ...
* @author
*/
public class Projectile extends MovingModel {
static public const ON_HIT:String = "onHit";
protected var _target:Enemy;
public function get target():Enemy { return _target; }
protected var _damage:int;
public function get damage():int { return _damage; }
protected var _shooter:Tower;
public function get shooter():Tower { return _shooter; }
protected var _positionToMove:Vector2D;
protected var removeOnTargetDeath:Boolean;
protected var maxtravelFrames:int;
private var currentTravelFrame:int;
public function Projectile(shooter:Tower, target:Enemy) {
super();
_target = target;
_shooter = shooter;
_damage = shooter.damage;
maxtravelFrames = 12;
currentTravelFrame = 0;
_position.x = shooter.position.x;
_position.y = shooter.position.y;
removeOnTargetDeath = true;
_target.addEventListener(Model.DISPOSE, onTargetDispose);
upgradeStats();
}
override public function update():void {
currentTravelFrame++;
applyVelocity();
if (_target != null && _target.position) {
velocity.x = ((_target.position.x - _position.x) / maxtravelFrames) * currentTravelFrame;
velocity.y = ((_target.position.y - _position.y) / maxtravelFrames) * currentTravelFrame;
if ( checkTargetCollision(_target) ) {
onHitTarget();
}
} else if ( !removeOnTargetDeath && _positionToMove != null) {
velocity.x = ((_positionToMove.x - _position.x) / maxtravelFrames) * currentTravelFrame;
velocity.y = ((_positionToMove.y - _position.y) / maxtravelFrames) * currentTravelFrame;
if (currentTravelFrame == maxtravelFrames) {
onHitDestination();
}
} else {
dispatchEvent( new ModelEvent(ON_HIT, this) );
}
}
protected function upgradeStats():void {
//abstract
}
private function onTargetDispose(e:Event):void {
_positionToMove = _target.position.copy();
}
//Gets called instead of OnHitTarget if the target is killed before this projectile gets to its destination
protected function onHitDestination():void {
dispatchEvent( new ModelEvent(ON_HIT, this) );
}
protected function onHitTarget():void {
_target.onImpact(_damage);
dispatchEvent( new ModelEvent(ON_HIT, this) );
}
protected function checkTargetCollision(target:Enemy):Boolean {
var distance:Number = ModelUtilities.getRadiusDistance(this, target);
if (distance < target.radius) return true;
else return false;
}
override public function dispose():void {
super.dispose();
_target.removeEventListener(Model.DISPOSE, onTargetDispose);
}
}
}