package { import flash.display.Graphics; import flash.display.MovieClip; import flash.geom.ColorTransform; import flash.geom.Point; import caurina.transitions.*; import Globals; public class Ship extends MovieClip { private var speed:Number = 0; private var torqueSpeed:Number = 0; private var lastCoords:Point = new Point(Globals.posToCoords(x), Globals.posToCoords(y)); private var maxHealth:Number; private var health:Number; private var sector:Sector; private var speedAcc:Number; private var speedMax:Number; private var breakSpeed:Number; private var torqueAcc:Number; private var torqueMax:Number; private var properties:Object; private var allegienceColors:Array; private var allegience:int; private var dying:Boolean = false;//prevents double destroy() calls private var trailCounter:int = 0; private var smokeCounter:int = 0; private var shipType:int; private var damageSkin:Damage_skin; private var speedX:Number; private var speedY:Number; private var speedXOffset:Number = 0; private var speedYOffset:Number = 0; private var timer:int = 0; public function Ship($coords:Point, $rotation:Number, $sector:Sector, $shipProperties:Object, $allegience:int) { moveTo($coords, $rotation); properties = $shipProperties; health = properties.hp; maxHealth = health; sector = $sector; speedAcc = properties.speedAcc; speedMax = properties.speedMax; breakSpeed = properties.breakSpeed; torqueAcc = properties.torqueAcc; torqueMax = properties.torqueMax; allegience = $allegience; shipType = properties.id; allegienceColors = sector.AllegianceColors; gotoAndStop(shipType); addColors(); addDamageSkin(); } private function addColors():void { var stripes:Color_stripes = new Color_stripes(); stripes.gotoAndStop(shipType); stripes.transform.colorTransform = allegienceColors[allegience]; addChildAt(stripes, 1); stripes = null; } private function addDamageSkin() { damageSkin = new Damage_skin(); damageSkin.gotoAndStop(shipType); damageSkin.alpha = 0; addChild(damageSkin); } public function move():void { //keep speeds within the limits if (Speed < 0) Speed = 0;//no reversing if (Speed > SpeedMax) Speed = SpeedMax;//no speeding if (TorqueSpeed < 0 && TorqueSpeed <= -(TorqueMax * TorqueRate)) TorqueSpeed = -(TorqueMax * TorqueRate);//not to fast to the left if (TorqueSpeed > 0 && TorqueSpeed >= (TorqueMax * TorqueRate)) TorqueSpeed = (TorqueMax * TorqueRate);//not to fast to the right //calculate speeds speedX = Math.sin(Globals.degToRad(rotation)) * speed; speedY = Math.cos(Globals.degToRad(rotation)) * -speed; //slowdown speedXOffset if (speedXOffset > .2) speedXOffset -= .1; else if (speedXOffset < -.2) speedXOffset += .1; else speedXOffset = 0; //slowdown speedYOffset if (speedYOffset > .2) speedYOffset -= .1; else if (speedYOffset < -.2) speedYOffset += .1; else speedYOffset = 0; //checks shipHitCheck(); asteroidHitCheck(); deathCheck(); outsideCheck(); //spawn trail if moving if (Speed > 0) { for (var i:int = 0; i < properties.trails; i++) { var trailRot:Number; if (i % 2) trailRot = -properties.trailRot; else trailRot = properties.trailRot; trailSpawn(properties.trailDist, trailRot, properties.trailScale); } } if (++smokeCounter >= 6) { smokeCounter = 0; if (health / maxHealth <= .3) spawnSmoke(1, 1, 1, false) } damageSkin.alpha = 1 - (health / maxHealth); //apply speeds and rotation x += speedX + speedXOffset; y += speedY + speedYOffset; rotation += torqueSpeed; //timer restarts every 10th second, 0 - 400 if (++timer >= 400) timer = 0; } ///Run every time the ship are at new coordinates public function onNewCoords() { if (atNewPoint()) { lastCoords.x = Coords.x; lastCoords.y = Coords.y; } } public function spawnSmoke($ammount:int, $speed:Number, $scale:Number, $moving:Boolean) { for (var i:int = 0; i < $ammount; i++) { var temp:Engine_smoke; if ($moving) { temp = new Engine_smoke( (Math.random() * $speed) - ($speed / 2) + (SpeedX / 2), (Math.random() * $speed) - ($speed / 2) + (SpeedY / 2) ); } else { temp = new Engine_smoke( (Math.random() * $speed) - ($speed / 2), (Math.random() * $speed) - ($speed / 2) ); } temp.x = x; temp.y = y; temp.scaleX = $scale; temp.scaleY = $scale; sector.addChild(temp); } } private function trailSpawn($distance:Number, $rotOffset:Number, $scale:Number):void { $rotOffset += 180; var temp:Trail = new Trail(); temp.x = x + (Math.sin(Globals.degToRad(rotation + $rotOffset)) * $distance); temp.y = y - (Math.cos(Globals.degToRad(rotation + $rotOffset)) * $distance); temp.rotation = rotation; temp.scaleX = $scale; temp.scaleY = $scale; temp.transform.colorTransform = allegienceColors[allegience]; temp.alpha = Globals.round(Speed / SpeedMax, 2); sector.addChildAt(temp, 0); } ///checks if the ship is outside the map boundaries private function outsideCheck():void { var hpLoss:int = 10; if (Coords.x < 0)//left { health -= hpLoss; Tweener.addTween(this, {time:1, rotation:90} ); } if (Coords.x >= sector.SectorW)//right { health -= hpLoss; Tweener.addTween(this, {time:1, rotation:-90} ); } if (Coords.y < 0)//over { health -= hpLoss; Tweener.addTween(this, {time:1, rotation:180} ); } if (Coords.y >= sector.SectorH)//under { health -= hpLoss; Tweener.addTween(this, {time:1, rotation:0} ); } } ///Is the ship at new coordinates since the last timer tick? private function atNewPoint():Boolean { return lastCoords.x != Coords.x || lastCoords.y != Coords.y; } ///moves the ship instantaneously to a new point public function moveTo(point:Point, $rotation:Number):void { x = (point.x * 32) + 16; y = (point.y * 32) + 16; rotation = $rotation; } public function asteroidHitCheck() { for each (var a:Asteroid in sector.Asteroids) { if (a && Globals.calcDist(a.x, a.y, x, y) < 80) { alpha = .5; Tweener.addTween(this, { alpha:1, time:.5 } );//fade the ship out and in every time it's hit a.hit((Speed / SpeedMax) * properties.mass); HP -= (Speed / SpeedMax) * 10; bump(a, Speed); } } } public function projectileHit($damage:Number):void { //hit effect alpha = .5; Tweener.addTween(this, { alpha:1, time:.5 } );//fade the ship out and in every time it's hit if (!Dying) HP -= $damage; } ///Checks if this ship hits another ship public function shipHitCheck():void { for each(var s:Ship in getSector.getShips()) { if (s && s != this && Globals.calcDist(s.x, s.y, x, y) < 32) bumpShip(s); } } //This ship bumps into another ship public function bumpShip($hitObject:Ship) { if ($hitObject.Allegiance != Allegiance) { HP -= 10; Tweener.addTween(this, { alpha:1, time:.5 } );//fade the ship out and in bump($hitObject, Speed + $hitObject.Speed); } else { bump($hitObject, 0); } } ///Makes this ship slide away from $hitObject public function bump($hitObject:MovieClip, $bumpSpeed:Number) { //calc relative pos to the other ship var deltaX:Number = x - $hitObject.x; var deltaY:Number = y - $hitObject.y; //move this ship away from the other speedXOffset = deltaX / 10; speedYOffset = deltaY / 10; Speed *= .9; //do damage if this ships speed is greater than half if ($bumpSpeed > (SpeedMax / 2)) bumpDamage($bumpSpeed); } public function bumpDamage($damage:Number) { if (timer % 40 == 0) HP -= $damage; } public function deathCheck() { if (HP <= 0 && !Dying) destroy(); } public function destroy() { speed = 0; speedXOffset = 0; speedYOffset = 0; var boom:ShipExplode = new ShipExplode(); boom.x = x; boom.y = y; getSector.addChildAt(boom, 2); spawnSmoke(6, 3, 2, true); parent.removeChild(this); } //--------------------------------------------set/get-------------------------------------------- public function set Speed($speed:Number):void { speed = $speed; } public function get Speed():Number { return speed; } public function set TorqueSpeed($torqueSpeed:Number):void { torqueSpeed = $torqueSpeed; } public function get TorqueSpeed():Number { return torqueSpeed; } public function get Coords():Point { return new Point(Globals.posToCoords(x), Globals.posToCoords(y)); } public function get HP():int { return health; } public function set HP($health:int):void { health = $health; } public function get MaxHP():int { return maxHealth; } public function set MaxHP($value:int):void { maxHealth = $value; } public function get getSector():Sector { return sector; } public function get ID():int//placeholder that is overidden in AIShip and PlayerShip { return 0; } public function get SpeedAcc():Number { return speedAcc; } public function set SpeedAcc($value:Number) { speedAcc = $value; } public function get SpeedMax():Number { return speedMax; } public function set SpeedMax($value:Number) { speedMax = $value; } public function get BreakSpeed():Number { return breakSpeed; } public function set BreakSpeed($value:Number) { breakSpeed = $value; } public function get TorqueAcc():Number { return torqueAcc; } public function set TorqueAcc($value:Number) { torqueAcc = $value; } public function get TorqueMax():Number { return torqueMax; } public function set TorqueMax($value:Number) { torqueMax = $value; } public function get Dying():Boolean { return dying; } public function set Dying($value:Boolean) { dying = $value; } public function get Allegiance():int { return allegience; } public function get TorqueRate():Number { var temp:Number = ((SpeedMax - Speed) / SpeedMax / 2) + .5; return Math.round(temp * 100) / 100; } public function get Mass():int { return properties.mass; } public function get SpeedX():Number { return speedX; } public function get SpeedY():Number { return speedY; } public function get SpeedXOffset():Number { return speedXOffset; } public function get SpeedYOffset():Number { return speedYOffset; } } }