package
{
import com.cheezeworld.utils.Input;
import com.cheezeworld.utils.KeyCode;
import events.GridObjectEvent;
import events.ModelEvent;
import events.StringEvent;
import events.ViewEvent;
import factories.PathGridObjectFactory;
import factories.ProjectileFlamethrowerFactory;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.utils.Dictionary;
import flash.utils.getTimer;
import game.build.BuildManager;
import game.enemies.Enemy;
import game.enemies.EnemyManager;
import game.menu.BuyMenu;
import game.projectiles.Projectile;
import game.projectiles.ProjectileFlamethrower;
import game.projectiles.ProjectileHeavy;
import game.projectiles.ProjectileManager;
import game.projectiles.ProjectileSlow;
import game.towers.Tower;
import game.towers.TowerFlamethrower;
import game.towers.TowerHeavy;
import game.towers.TowerManager;
import game.towers.TowerSlow;
import game.UpgradeManager;
import game.waves.WaveManager;
import grid.Grid;
import grid.path.PathFollowUnit;
import hud.HUD;
import views.EnemyView;
import views.PathGridObjectView;
import views.PathView;
import views.ProjectileFlamethowerView;
import views.ProjectileHeavyView;
import views.ProjectileSlowView;
import views.ProjectileView;
import views.TowerFlamethrowerView;
import views.TowerHeavyView;
import views.TowerSlowView;
import views.TowerView;
import views.View;
import grid.path.PathGrid;
import grid.path.PathGridObject;
import pathfinder.INode;
import pathfinder.Pathfinder;
import flash.system.System;
/**
* ...
* @author
*/
public class Game extends Sprite {
static public const BUILD_PHASE:String = "buildPhase";
static public const PLAY_PHASE:String = "playPhase";
private var pathGrid:PathGrid;
private var pathView:PathView;
private var towerManager:TowerManager;
private var enemyManager:EnemyManager;
private var route:Array;
private var projectileManager:ProjectileManager;
private var waveManager:WaveManager;
private var upgradeManager:UpgradeManager;
private var buildManager:BuildManager;
private var buildPhase:Boolean;
private var placingTower:Boolean;
public var placingTowerName:String;
private var hudD:HUD;
private var buyMenu:BuyMenu;
//still a simple variable, might make a class instead
private var health:int;
public function Game() {
trace("Hello world!");
pathView = new PathView();
addChild(pathView);
pathView.addEventListener(PathView.VIEW_ADD, onViewAdd);
pathGrid = new PathGrid();
pathGrid.addEventListener(Grid.OBJECT_ADD, onObjectAdd);
pathGrid.startGrid(11, 11);
towerManager = new TowerManager();
towerManager.addEventListener(TowerManager.TOWER_ADD, onTowerAdd);
towerManager.addEventListener(TowerManager.TOWER_FIRE, onTowerFire);
//towerManager.addEventListener(TowerManager.TOWER_REMOVE, onTowerRemove);
enemyManager = new EnemyManager();
enemyManager.addEventListener(EnemyManager.ENEMY_ADD, onEnemyAdd);
enemyManager.addEventListener(EnemyManager.ENEMY_REMOVE, onEnemyRemove);
enemyManager.addEventListener(PathFollowUnit.END_PATH, onEnemyEndPath);
projectileManager = new ProjectileManager();
projectileManager.addEventListener(ProjectileManager.PROJECTILE_ADDED, onProjectileAdded);
//projectileManager.addEventListener(ProjectileManager.ON_PROJECTILE_HIT, onProjectileHit);
waveManager = new WaveManager();
waveManager.addEventListener(WaveManager.SPAWN_ENEMY, onSpawnEnemy);
buildManager = new BuildManager();
buyMenu = new BuyMenu();
buyMenu.addEventListener(BuyMenu.TOWER_SELECTED, onTowerSelected);
addChild(buyMenu);
hudD = new HUD();
addChild(hudD);
hudD.addEventListener(HUD.SELL_TOWER, onSellTower);
hudD.addEventListener(HUD.UPGRADE_TOWER, onUpgradeTower);
addEventListener(Event.ENTER_FRAME, update);
addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
findRoute();
health = 15;
}
private function onUpgradeTower(e:ModelEvent):void {
var tower:Tower = e.model as Tower;
if ( tower.upgradeCost <= buildManager.moneyCount() ) {
buildManager.removeMoney(tower.upgradeCost);
tower.upgrade();
}
dispatchEvent( new ModelEvent(Tower.TOWER_UPGRADE, tower) );
//upgradeManager.upgrade(tower);
//System.exit(0);
}
private function onSellTower(e:ModelEvent):void {
var tower:Tower = e.model as Tower;
buildManager.refundTowerByTower(tower);
towerManager.removeTowerbyPathGridObject(tower.location);
}
private function update(e:Event):void {
hudD.update( buildManager.moneyCount(), waveManager.currentWaveID(), health );
waveManager.update();
pathView.update();
highlightRoute(route);
towerManager.updateTowerTargets(enemyManager.enemies);
enemyManager.update();
projectileManager.update();
if (Input.instance.isKeyDown(KeyCode.SPACEBAR) ) waveManager.startNewWave();
}
private function onTowerSelected(e:StringEvent):void {
placingTower = !placingTower;
placingTowerName = e.string;
}
private function onSpawnEnemy(e:ModelEvent):void {
enemyManager.addEnemy(e.model as Enemy);
}
private function onTowerFire(e:ModelEvent):void {
var projectile:Projectile = e.model as Projectile;
projectileManager.addProjectile(projectile);
}
private function onEnemyEndPath(e:ModelEvent):void {
var enemy:Enemy = e.model as Enemy;
enemyManager.removeEnemy(enemy);
health--;
if (health < 1) {
trace("game over!");
health = 0;
}
}
private function onEnemyRemove(e:ModelEvent):void {
//add value to enemy class
var money:int = 5 + waveManager.currentWaveID();
buildManager.addMoney(money);
}
private function onEnemyAdd(e:ModelEvent):void {
var enemy:Enemy = e.model as Enemy;
var endNode:INode = route[route.length - 1];
if (!endNode) {
throw new Error("Path is null!");
}
enemy.setAtNode(endNode, route.length);
pathView.addView( new EnemyView(enemy) );
}
private function onProjectileAdded(e:ModelEvent):void {
//ADDTOWER
if (e.model is ProjectileSlow) pathView.addView( new ProjectileSlowView(e.model as Projectile) );
else if (e.model is ProjectileHeavy) pathView.addView( new ProjectileHeavyView(e.model as Projectile) );
else if (e.model is ProjectileFlamethrower) pathView.addView( new ProjectileFlamethowerView(e.model as Projectile) );
else pathView.addView( new ProjectileView(e.model as Projectile) );
}
private function onTowerAdd(e:ModelEvent):void {
var tower:Tower = e.model as Tower;
//ADDTOWER
if (tower is TowerSlow) {
pathView.addView( new TowerSlowView(tower) );
} else if (tower is TowerHeavy) {
pathView.addView( new TowerHeavyView(tower) );
} else if (tower is TowerFlamethrower) {
pathView.addView( new TowerFlamethrowerView(tower) );
} else {
pathView.addView( new TowerView(tower) );
}
}
private function onMouseDown(e:MouseEvent):void {
//pathGrid.getGridObject(0, 0);
}
public function findRoute():void {
if (!waveManager.isActive) {
var endNode:INode = pathGrid.getGridObject(0, 0) as PathGridObject;
//startNode
var startNode:INode = pathGrid.getGridObject(10, 10) as PathGridObject;
Pathfinder.heuristic = Pathfinder.manhattanHeuristic;
var pre:int = getTimer();
for (var i:int = 0; i < 1; i++) {
route = Pathfinder.findPath(startNode, endNode, pathGrid.findConnectedPathGridObjects);
}
var post:int = getTimer();
var timeInMilliseconds:int = post - pre;
if (!route) return;
}
}
private function onViewAdd(e:ViewEvent):void {
e.view.addEventListener(MouseEvent.CLICK, onViewClick);
e.view.addEventListener(MouseEvent.MOUSE_OVER, onViewMouseOver);
e.view.addEventListener(MouseEvent.MOUSE_OUT, onViewMouseOut);
}
private function onViewClick(e:MouseEvent):void {
var pathGridObject:PathGridObject;
if (e.currentTarget is PathGridObjectView) {
var view:PathGridObjectView = e.currentTarget as PathGridObjectView;
pathGridObject = view.followTarget as PathGridObject;
if ( placingTower && !pathGridObject.traversable) {
if ( buildManager.canBuyTower(placingTowerName) ) {
if ( towerManager.createTower(pathGridObject, placingTowerName) ) {
buildManager.removeMoney( buildManager.getCostForTowerByName(placingTowerName) );
}
}
} else if ( !towerManager.checkLocationForTurret(pathGridObject) ) {
if (pathGridObject.traversable) {
if ( buildManager.canBuyBlock() && !waveManager.isActive) {
buildManager.removeMoney(BuildManager.COST_BLOCK);
toggleTraversable(pathGridObject);
} else return;
} else if (!waveManager.isActive) {
toggleTraversable(pathGridObject);
buildManager.addMoney(BuildManager.COST_BLOCK);
}
}
disablePlacingTower();
} else if (e.currentTarget is TowerView) {
var towerView:TowerView = e.currentTarget as TowerView;
pathGridObject = towerView.tower.location;
//buildManager.refundTowerByTower(towerView.tower);
//towerManager.removeTowerbyPathGridObject(pathGridObject);
showStatsOfTower(towerView);
}
}
private function onViewMouseOver(e:MouseEvent):void {
var view:View = e.currentTarget as View;
if (view is TowerView) {
//show range
var towerView:TowerView = view as TowerView;
towerView.drawTurretRange();
}
}
private function onViewMouseOut(e:MouseEvent):void {
var view:View = e.currentTarget as View;
if (view is TowerView) {
//show range
var towerView:TowerView = view as TowerView;
towerView.hideTurretRange();
}
}
private function showStatsOfTower(towerView:TowerView):void {
var towerInQuestion:Tower = towerView.tower;
hudD.showTowerStats(towerInQuestion);
}
public function disablePlacingTower():void {
buyMenu.toggleHighLight(placingTowerName, true, false);
placingTower = false;
}
private function toggleTraversable(pathGridObject:PathGridObject):void {
pathGridObject.traversable = !pathGridObject.traversable;
findRoute();
}
private function highlightRoute(route:Array):void {
if (!route) {
//trace("WARNING: NO PATH DETECTED");
return;
}
for (var i:int = 0; i < route.length; i++) {
var currentObject:PathGridObject = route[i];
var currentView:PathGridObjectView = pathView.getViewOfPathObject(currentObject);
currentView.drawBox(currentObject, 0x5555ff);
}
}
private function onObjectAdd(e:GridObjectEvent):void {
var pathGridObject:PathGridObject = e.gridObject as PathGridObject;
pathView.addView( new PathGridObjectView(pathGridObject) );
}
public function get currentPhase():String {
if (buildPhase) return BUILD_PHASE;
else return PLAY_PHASE;
}
}
}