package { import flash.display.*; import flash.events.*; import flash.text.*; import flash.utils.getTimer; import flash.utils.Timer; import flash.geom.Point; public class SpaceRocks extends MovieClip { static const shipRotationSpeed:Number = .1; static const rockSpeedStart:Number = .03; static const rockSpeedIncrease:Number = .02; static const missileSpeed:Number = .2; static const thrustPower:Number = .15; static const shipRadius:Number = 20; static const startingShips:uint = 3; // game objects private var ship:Ship; private var rocks:Array; private var missiles:Array; // animation timer private var lastTime:uint; // arrow keys private var rightArrow:Boolean = false; private var leftArrow:Boolean = false; private var upArrow:Boolean = false; // ship velocity private var shipMoveX:Number; private var shipMoveY:Number; // timers private var delayTimer:Timer; private var shieldTimer:Timer; // game mode private var gameMode:String; private var shieldOn:Boolean; // ships and shields private var shipsLeft:uint; private var shieldsLeft:uint; private var shipIcons:Array; private var shieldIcons:Array; private var scoreDisplay:TextField; // score and level private var gameScore:Number; private var gameLevel:uint; // sprites private var gameObjects:Sprite; private var scoreObjects:Sprite; // start the game public function startSpaceRocks() { // set up sprites gameObjects = new Sprite(); addChild(gameObjects); scoreObjects = new Sprite(); addChild(scoreObjects); // reset score objects gameLevel = 1; shipsLeft = startingShips; gameScore = 0; createShipIcons(); createScoreDisplay(); // set up listeners addEventListener(Event.ENTER_FRAME,moveGameObjects); stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDownFunction); stage.addEventListener(KeyboardEvent.KEY_UP,keyUpFunction); // start gameMode = "delay"; shieldOn = false; missiles = new Array(); nextRockWave(null); newShip(null); } // SCORE OBJECTS // draw number of ships left public function createShipIcons() { shipIcons = new Array(); for(var i:uint=0;i 0) { removeShipIcon(); } } // remove the rest of the shield icons public function removeAllShieldIcons() { while (shieldIcons.length > 0) { removeShieldIcon(); } } // SHIP CREATION AND MOVEMENT // create a new ship public function newShip(event:TimerEvent) { // if ship exists, remove it if (ship != null) { gameObjects.removeChild(ship); ship = null; } // no more ships if (shipsLeft < 1) { endGame(); return; } // create, position, and add new ship ship = new Ship(); ship.gotoAndStop(1); ship.x = 275; ship.y = 200; ship.rotation = -90; ship.shield.visible = false; gameObjects.addChild(ship); // set up ship properties shipMoveX = 0.0; shipMoveY = 0.0; gameMode = "play"; // set up shields shieldsLeft = 3; createShieldIcons(); // all lives but the first start with a free shield if (shipsLeft != startingShips) { startShield(true); } } // register key presses public function keyDownFunction(event:KeyboardEvent) { if (event.keyCode == 37) { leftArrow = true; } else if (event.keyCode == 39) { rightArrow = true; } else if (event.keyCode == 38) { upArrow = true; // show thruster if (gameMode == "play") ship.gotoAndStop(2); } else if (event.keyCode == 32) { // space newMissile(); } else if (event.keyCode == 90) { // z startShield(false); } } // register key ups public function keyUpFunction(event:KeyboardEvent) { if (event.keyCode == 37) { leftArrow = false; } else if (event.keyCode == 39) { rightArrow = false; } else if (event.keyCode == 38) { upArrow = false; // remove thruster if (gameMode == "play") ship.gotoAndStop(1); } } // animate ship public function moveShip(timeDiff:uint) { // rotate and thrust if (leftArrow) { ship.rotation -= shipRotationSpeed*timeDiff; } else if (rightArrow) { ship.rotation += shipRotationSpeed*timeDiff; } else if (upArrow) { shipMoveX += Math.cos(Math.PI*ship.rotation/180)*thrustPower; shipMoveY += Math.sin(Math.PI*ship.rotation/180)*thrustPower; } // move ship.x += shipMoveX; ship.y += shipMoveY; // wrap around screen if ((shipMoveX > 0) && (ship.x > 570)) { ship.x -= 590; } if ((shipMoveX < 0) && (ship.x < -20)) { ship.x += 590; } if ((shipMoveY > 0) && (ship.y > 420)) { ship.y -= 440; } if ((shipMoveY < 0) && (ship.y < -20)) { ship.y += 440; } } // remove ship public function shipHit() { gameMode = "delay"; ship.gotoAndPlay("explode"); removeAllShieldIcons(); delayTimer = new Timer(2000,1); delayTimer.addEventListener(TimerEvent.TIMER_COMPLETE,newShip); delayTimer.start(); removeShipIcon(); shipsLeft--; } // turn on shield for 3 seconds public function startShield(freeShield:Boolean) { if (shieldsLeft < 1) return; // no shields left if (shieldOn) return; // shield already on // turn on shield and set timer to turn off ship.shield.visible = true; shieldTimer = new Timer(3000,1); shieldTimer.addEventListener(TimerEvent.TIMER_COMPLETE,endShield); shieldTimer.start(); // update shields remaining if (!freeShield) { removeShieldIcon(); shieldsLeft--; } shieldOn = true; } // turn off shield public function endShield(event:TimerEvent) { ship.shield.visible = false; shieldOn = false; } // ROCKS // create a single rock of a specific size public function newRock(x,y:int, rockType:String) { // create appropriate new class var newRock:MovieClip; var rockRadius:Number; if (rockType == "Big") { newRock = new Rock_Big(); rockRadius = 35; } else if (rockType == "Medium") { newRock = new Rock_Medium(); rockRadius = 20; } else if (rockType == "Small") { newRock = new Rock_Small(); rockRadius = 10; } // Here is an alternate way to do the above, without a case statement // Need to import flash.utils.getDefinitionByName to use /* var rockClass:Object = getDefinitionByName("Rock_"+rockType); var newRock:MovieClip = new rockClass(); */ // choose a random look newRock.gotoAndStop(Math.ceil(Math.random()*3)); // set start position newRock.x = x; newRock.y = y; // set random movement and rotation var dx:Number = Math.random()*2.0-1.0; var dy:Number = Math.random()*2.0-1.0; var dr:Number = Math.random(); // add to stage and to rocks list gameObjects.addChild(newRock); rocks.push({rock:newRock, dx:dx, dy:dy, dr:dr, rockType:rockType, rockRadius: rockRadius}); } // create four rocks public function nextRockWave(event:TimerEvent) { rocks = new Array(); newRock(100,100,"Big"); newRock(100,300,"Big"); newRock(450,100,"Big"); newRock(450,300,"Big"); gameMode = "play"; } // animate all rocks public function moveRocks(timeDiff:uint) { for(var i:int=rocks.length-1;i>=0;i--) { // move the rocks var rockSpeed:Number = rockSpeedStart + rockSpeedIncrease*gameLevel; rocks[i].rock.x += rocks[i].dx*timeDiff*rockSpeed; rocks[i].rock.y += rocks[i].dy*timeDiff*rockSpeed; // rotate rocks rocks[i].rock.rotation += rocks[i].dr*timeDiff*rockSpeed; // wrap rocks if ((rocks[i].dx > 0) && (rocks[i].rock.x > 570)) { rocks[i].rock.x -= 590; } if ((rocks[i].dx < 0) && (rocks[i].rock.x < -20)) { rocks[i].rock.x += 590; } if ((rocks[i].dy > 0) && (rocks[i].rock.y > 420)) { rocks[i].rock.y -= 440; } if ((rocks[i].dy < 0) && (rocks[i].rock.y < -20)) { rocks[i].rock.y += 440; } } } public function rockHit(rockNum:uint) { // create two smaller rocks if (rocks[rockNum].rockType == "Big") { newRock(rocks[rockNum].rock.x,rocks[rockNum].rock.y,"Medium"); newRock(rocks[rockNum].rock.x,rocks[rockNum].rock.y,"Medium"); } else if (rocks[rockNum].rockType == "Medium") { newRock(rocks[rockNum].rock.x,rocks[rockNum].rock.y,"Small"); newRock(rocks[rockNum].rock.x,rocks[rockNum].rock.y,"Small"); } // remove original rock gameObjects.removeChild(rocks[rockNum].rock); rocks.splice(rockNum,1); } // MISSILES // create a new Missile public function newMissile() { // create var newMissile:Missile = new Missile(); // set direction newMissile.dx = Math.cos(Math.PI*ship.rotation/180); newMissile.dy = Math.sin(Math.PI*ship.rotation/180); // placement newMissile.x = ship.x + newMissile.dx*shipRadius; newMissile.y = ship.y + newMissile.dy*shipRadius; // add to stage and array gameObjects.addChild(newMissile); missiles.push(newMissile); } // animate missiles public function moveMissiles(timeDiff:uint) { for(var i:int=missiles.length-1;i>=0;i--) { // move missiles[i].x += missiles[i].dx*missileSpeed*timeDiff; missiles[i].y += missiles[i].dy*missileSpeed*timeDiff; // moved off screen if ((missiles[i].x < 0) || (missiles[i].x > 550) || (missiles[i].y < 0) || (missiles[i].y > 400)) { gameObjects.removeChild(missiles[i]); delete missiles[i]; missiles.splice(i,1); } } } // remove a missile public function missileHit(missileNum:uint) { gameObjects.removeChild(missiles[missileNum]); missiles.splice(missileNum,1); } // GAME INTERACTION AND CONTROL public function moveGameObjects(event:Event) { // get timer difference and animate var timePassed:uint = getTimer() - lastTime; lastTime += timePassed; moveRocks(timePassed); if (gameMode != "delay") { moveShip(timePassed); } moveMissiles(timePassed); checkCollisions(); } // look for missiles colliding with rocks public function checkCollisions() { // loop through rocks rockloop: for(var j:int=rocks.length-1;j>=0;j--) { // loop through missiles missileloop: for(var i:int=missiles.length-1;i>=0;i--) { // collision detection if (Point.distance(new Point(rocks[j].rock.x,rocks[j].rock.y), new Point(missiles[i].x,missiles[i].y)) < rocks[j].rockRadius) { // remove rock and missile rockHit(j); missileHit(i); // add score gameScore += 10; updateScore(); // break out of this loop and continue next one continue rockloop; } } // check for rock hitting ship if (gameMode == "play") { if (shieldOn == false) { // only if shield is off if (Point.distance(new Point(rocks[j].rock.x,rocks[j].rock.y), new Point(ship.x,ship.y)) < rocks[j].rockRadius+shipRadius) { // remove ship and rock shipHit(); rockHit(j); } } } } // all out of rocks, change game mode and trigger more if ((rocks.length == 0) && (gameMode == "play")) { gameMode = "betweenlevels"; gameLevel++; // advance a level delayTimer = new Timer(2000,1); delayTimer.addEventListener(TimerEvent.TIMER_COMPLETE,nextRockWave); delayTimer.start(); } } public function endGame() { // remove all objects and listeners removeChild(gameObjects); removeChild(scoreObjects); gameObjects = null; scoreObjects = null; removeEventListener(Event.ENTER_FRAME,moveGameObjects); stage.removeEventListener(KeyboardEvent.KEY_DOWN,keyDownFunction); stage.removeEventListener(KeyboardEvent.KEY_UP,keyUpFunction); gotoAndStop("gameover"); } } }