|
Spaceship Shooter game with AS3
Overview:
This game is simple and is a good example of using the Timer class for a multiple timeline effect.
To compile this game you will need to create your own images and sound, and
change the name of the embed folder (../testimages) to the folder where your images are.
package
{
import flash.display.Sprite;
import flash.display.Graphics;
import flash.display.DisplayObject;
import flash.display.GradientType;
import flash.geom.Rectangle;
import flash.geom.Matrix;
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.ui.Mouse;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.text.TextFieldAutoSize;
import flash.media.Sound;
[SWF( backgroundColor = '0xA9A9A9', frameRate = '20', width = '500', height = '500')]
/*a (t)a.d as3 tutorial
copyright 2008 */
public class ShipShooterGame extends Sprite
{
private var shotDistance:Number = 20;
private var shotGo:Timer;
private var pellet:Sprite;
private var pelletTwo:Sprite;
private var pelletThree:Sprite;
private var theShip:Sprite;
private var pelletTwoGo:String = "no";
private var pelletThreeGo:String = "no";
private var enemyOne:Sprite;
private var enemyOneLife:Number = 0;
/* the smaller the tougher */
private var enemyOneToughness:Number = .03;
private var enemyOneBaby:Sprite;
private var enemyTwo:Sprite;
private var enemyTwoLife:Number = 0;
private var enemyTwoToughness:Number = .01;
private var enemyThree:Sprite;
private var enemyThreeLife:Number = 0;
private var enemyThreeToughness:Number = .01;
private var enemyDeploy:Timer;
private var lifeMeter:Sprite;
private var playerLife:Number = 115;
private var lifeBox:Sprite;
private var theScore:Number = 0;
private var shipStatus:TextField;
private var currentSituation:String = "All systems go - click then press enter";
private var statTXTFormat:TextFormat;
private var gameStarted:String = "no";
private var powerUp:Sprite;
private var pelletPower:Number = 0;
private var backgroundAnimation:Timer;
private var gameBack:Sprite;
private var pelletShotMatrix:Matrix;
private var shotColors:Array = [0xFFFF60, 0xFFFFFF];
private var circleRadius:Number = 5;
private var mouseActive:String = "yes";
[Embed(source="../testimages/pup.png")]
private var PowerUpImage:Class;
[Embed(source="../testimages/backstars.gif")]
private var StarBackOne:Class;
[Embed(source="../testimages/backstarsb.gif")]
private var StarBackTwo:Class;
[Embed(source="../testimages/backstarsc.gif")]
private var StarBackThree:Class;
[Embed(source="../testimages/aship.png")]
private var ShipImage:Class;
[Embed(source="../testimages/enys.png")]
private var enemyImage:Class;
[Embed(source="../testimages/enysother.png")]
private var YellowEnemyImage:Class;
[Embed(source="../testimages/shot.mp3")]
private var ShotSound:Class;
private var shotNoise:Sound = new ShotSound();
public function ShipShooterGame()
{
backgroundAnimation = new Timer(300, 0);
gameBack = new Sprite();
gameBack.addChild(new StarBackOne());
gameBack.addChild(new StarBackTwo());
gameBack.addChild(new StarBackThree());
addChild(gameBack);
backgroundAnimation.addEventListener(TimerEvent.TIMER, backAnimation);
backgroundAnimation.start();
powerUp = new Sprite();
var puper:DisplayObject = new PowerUpImage();
puper.x = 0 - puper.width/2;
puper.y = 0 - puper.height/2;
powerUp.addChild(puper);
powerUp.x = 75;
powerUp.y = -50;
addChild(powerUp);
statTXTFormat = new TextFormat();
statTXTFormat.font = "Arial";
statTXTFormat.color = 0xE0FFFF;
statTXTFormat.size = 10;
statTXTFormat.align = TextFormatAlign.LEFT;
shipStatus = new TextField();
shipStatus.defaultTextFormat = statTXTFormat;
shipStatus.autoSize = TextFieldAutoSize.LEFT;
shipStatus.height = 20;
shipStatus.selectable = false;
shipStatus.text = "Score: " + theScore + "\n" + "Status: " + currentSituation;
enemyDeploy = new Timer(300, 50);
enemyOne = makeAnEnemy(enemyOne);
enemyOne.y = -55;
enemyOne.x = 500/2;
enemyOneBaby=makeBaby(enemyOneBaby);
enemyOneBaby.x = enemyOne.x;
enemyOneBaby.y = enemyOne.y;
enemyTwo = makeAnEnemy(enemyTwo);
enemyTwo.y = -55;enemyTwo.x = 500/2 + enemyOne.width + 95;
enemyThree = makeAnEnemy(enemyThree);
enemyThree.y = -55;enemyThree.x = 500/2 - enemyOne.width - 95;
addChild(enemyThree);
addChild(enemyTwo);
addChild(enemyOneBaby);
addChild(enemyOne);
lifeBox = new Sprite();
lifeBox.graphics.lineStyle(2, 0x6A5ACD);
lifeBox.graphics.drawRect(0, 0, 120, 20);
lifeMeter = lifeMeterCreate(lifeMeter, playerLife);
lifeBox.addChild(lifeMeter);
lifeBox.y = 500 - 40;
lifeBox.x = 30;
addChild(lifeBox);
shipStatus.x = lifeBox.x;
shipStatus.y = lifeBox.y - lifeBox.height - 7;
addChild(shipStatus);
shotGo = new Timer(50, 7);
theShip = new Sprite();
var ship:DisplayObject = new ShipImage();
ship.x = 0 - ship.width/2;
ship.y = 0 - ship.height/2;
theShip.addChild(ship);
pelletShotMatrix = new Matrix();
pelletShotMatrix.createGradientBox(2, 2, Math.PI/2, 0, 0);
pellet = new Sprite();
pellet.graphics.lineStyle(0);
pellet.graphics.beginGradientFill(GradientType.LINEAR, shotColors, [1.0, 0.4], [0, 127], pelletShotMatrix);
pellet.graphics.drawCircle(0, 0, circleRadius);
pelletTwo = new Sprite();
pelletTwo.graphics.lineStyle(0);
pelletTwo.graphics.beginGradientFill(GradientType.LINEAR, shotColors, [1.0, 0.4],
[0, 127],pelletShotMatrix);
pelletTwo.graphics.drawCircle(0, 0, circleRadius);
pelletThree = new Sprite();
pelletThree.graphics.lineStyle(0);
pelletThree.graphics.beginGradientFill(GradientType.LINEAR, shotColors, [1.0, 0.4], [0, 127], pelletShotMatrix);
pelletThree.graphics.drawCircle(0, 0, circleRadius);
theShip.x = 500/2 - theShip.width/2;
theShip.y = 500/2 - theShip.height/2;
theShip.buttonMode = true;
theShip.addEventListener(MouseEvent.CLICK, firePelletHandler);
pellet.x = theShip.x;
pellet.y = theShip.y;
pelletTwo.x = theShip.x;
pelletTwo.y = theShip.y;
pelletThree.x = theShip.x;
pelletThree.y = theShip.y;
addChild(pelletThree);
addChild(pelletTwo);
addChild(pellet);
addChild(theShip);
stage.addEventListener(Event.ENTER_FRAME, theGame);
stage.addEventListener(MouseEvent.CLICK, goBackToMouse);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
}
/* start funcs */
private function goBackToMouse(event:MouseEvent):void
{
mouseActive = "yes";
}
private function upThePellets():void
{
circleRadius += 1;
pellet.graphics.clear();
pellet.graphics.lineStyle(0);
pellet.graphics.beginGradientFill(GradientType.LINEAR, shotColors, [1.0, 0.4], [0, 127], pelletShotMatrix);
pellet.graphics.drawCircle(0, 0, circleRadius);
pelletTwo.graphics.clear();
pelletTwo.graphics.lineStyle(0);
pelletTwo.graphics.beginGradientFill(GradientType.LINEAR, shotColors, [1.0, 0.4],
[0, 127],pelletShotMatrix);
pelletTwo.graphics.drawCircle(0, 0, circleRadius);
pelletThree.graphics.clear();
pelletThree.graphics.lineStyle(0);
pelletThree.graphics.beginGradientFill(GradientType.LINEAR, shotColors, [1.0, 0.4], [0, 127], pelletShotMatrix);
pelletThree.graphics.drawCircle(0, 0, circleRadius);
}
private function backAnimation(event:TimerEvent):void
{
/* this is always happening
swapping the three background pics */
gameBack.swapChildrenAt(2, 1);
gameBack.swapChildrenAt(1, 0);
}
private function changeStats(statnow:String):void
{
currentSituation = statnow;
shipStatus.text = "Score: " + theScore + "\n" + "Status: " + currentSituation;
}
private function makeAnEnemy(enemy:Sprite):Sprite
{
enemy = new Sprite();
var enylook:* = new enemyImage();
/* this gives the object the x and y in its middle like a circle */
enylook.x = 0 - enylook.width/2;
enylook.y = 0 - enylook.height/2;
enemy.addChild(enylook);
return(enemy);
}
private function changeEnemy(enemy:Sprite, enyimg:*, uptough:Number):void
{
enemy.removeChildAt(0);
var enylook:* = enyimg;
enylook.x = 0 - enylook.width/2;
enylook.y = 0 - enylook.height/2;
enemy.addChild(enylook);
if (enemy == enemyOne)
{enemyOneToughness -= uptough;}
}
private function makeBaby(benemy:Sprite):Sprite
{
benemy = new Sprite();
benemy.graphics.lineStyle(1, 0xFF0000);
benemy.graphics.beginFill(0xD19275);
benemy.graphics.drawCircle(0, 0, 7);
return(benemy);
}
/* keyboard control
all keyboard events happen off this one function
that waits for any key to be pressed
its also the function that starts the game since enter must be pressed */
private function keyDownHandler(event:KeyboardEvent):void
{
if (event.keyCode == 13 && enemyDeploy.running == false && gameStarted == "no")
{startGame();}
if (event.keyCode == 32 && enemyDeploy.running == true && gameStarted == "yes")
{mouseActive="no";keyboardFirePellet();}
if (event.keyCode == 39)
{mouseActive="no";theShip.x += 7;}
if (event.keyCode == 37)
{mouseActive="no";theShip.x -= 7;}
if (event.keyCode == 38)
{mouseActive="no";theShip.y -= 7;}
if (event.keyCode == 40)
{mouseActive="no";theShip.y += 7;}
}
private function resetEnemysAndTimer():void
{
/* this function happens if all the enemies get destroyed
in ortherwords alpha of zero or less */
Timer(enemyDeploy).reset();Timer(enemyDeploy).stop();
var nextleveldelay:Number = 800;
if (theScore <= 9)
{enemyOneToughness -= .0002;enemyTwoToughness -= .0002;enemyThreeToughness -= .0002;
enemyDeploy.delay -= .5;}
if (theScore >= 10 && theScore <= 12)
{enemyOneToughness -= .001;enemyTwoToughness -= .001;enemyThreeToughness -= .001;enemyDeploy.delay -= 1;}
if (theScore >= 20 && theScore < 24)
{enemyOneToughness -= .003;enemyTwoToughness -= .002;enemyThreeToughness -= .002;enemyDeploy.delay -= 3;
changeStats("next enemys");changeEnemy(enemyOne, new YellowEnemyImage(), .02);}
if (theScore >= 30 && theScore <= 35)
{enemyOneToughness -= .002;enemyTwoToughness -= .003;enemyThreeToughness -= .003;enemyDeploy.delay -= 10;
changeStats("enemy level +3");}
if (theScore >= 50 && theScore <= 52)
{enemyOneToughness -= .004;enemyTwoToughness -= .004;enemyThreeToughness -= .004;enemyDeploy.delay -= 25;
changeStats("enemy level +4");}
enemyOne.alpha = 1;enemyOne.y = -70;enemyOneLife = 0;
enemyTwo.alpha = 1;enemyTwo.y = -50;enemyTwoLife = 0;
enemyThree.alpha = 1;enemyThree.y = -50;enemyThreeLife = 0;powerUp.alpha = 1;powerUp.y = -50;
enemyTwo.x = enemyOne.x + enemyOne.width + 65;
enemyThree.x = enemyOne.x - enemyOne.width - 65;enemyDeploy.delay -= 2;
var killedallreset:Timer = new Timer(nextleveldelay, 2);
killedallreset.addEventListener(TimerEvent.TIMER_COMPLETE, redeploy);
killedallreset.start();
}
private function redeploy(event:TimerEvent):void
{
Timer(enemyDeploy).reset();Timer(enemyDeploy).start();
}
private function resetEnemys(event:TimerEvent):void
{
/* this function happens at the end of enemy deploy,
in otherwords when the enemys pass the bottom
to give time for any next level animation or not.
enemyDeploys delay is what makes the enemys fall down faster */
var levelupdelay:Number = 1000;
Timer(enemyDeploy).reset();Timer(enemyDeploy).stop();
if (theScore >= 10 && theScore <= 12)
{enemyOneToughness -= .001;enemyTwoToughness -= .001;enemyThreeToughness -= .001;enemyDeploy.delay -= 1;}
if (theScore >= 20 && theScore <= 22)
{enemyOneToughness -= .002;enemyTwoToughness -= .002;enemyThreeToughness -= .002;enemyDeploy.delay -= 3;
changeStats("get more enemies");}
if (theScore >= 30 && theScore <= 34)
{enemyOneToughness -= .003;enemyTwoToughness -= .003;enemyThreeToughness -= .003;enemyDeploy.delay -= 9;
changeStats("enemy level +3");changeEnemy(enemyThree, new YellowEnemyImage(), .014);}
if (theScore >= 50 && theScore <= 52)
{enemyOneToughness -= .003;enemyTwoToughness -= .004;enemyThreeToughness -= .004;enemyDeploy.delay -= 24;
changeStats("enemy level +4");}
enemyOne.y = - 70;enemyOne.alpha =1;enemyOneLife = 0;
enemyTwo.y = - 50;enemyTwo.alpha =1;enemyTwoLife = 0;
enemyThree.y = - 50;enemyThree.alpha =1;enemyThreeLife = 0;powerUp.alpha = 1;powerUp.y = -50;
enemyTwo.x = enemyOne.x + enemyOne.width + 65;
enemyThree.x = enemyOne.x - enemyOne.width - 65;enemyDeploy.delay -= 2;
var somepassed:Timer = new Timer(levelupdelay, 2);
somepassed.addEventListener(TimerEvent.TIMER_COMPLETE, redeploy);
somepassed.start();
}
private function lifeMeterChange(thebar:Sprite, lifeleft:Number):void
{
/* max 115 */
thebar.graphics.clear();
thebar.graphics.lineStyle(0, 0xFF0000);
thebar.graphics.beginFill(0xFF0000);
thebar.graphics.drawRect(2, 1, lifeleft, 17);
thebar.graphics.endFill();
}
private function lifeMeterCreate(thebar:Sprite, lifeleft:Number):Sprite
{
/* max is 115 */
thebar = new Sprite();
thebar.graphics.clear();
thebar.graphics.lineStyle(0, 0xFF0000);
thebar.graphics.beginFill(0xFF0000);
thebar.graphics.drawRect(2, 1, lifeleft, 17);
thebar.graphics.endFill();
return(thebar);
}
/* govern the enemys travel and anything that falls down
give points and powerUping
this function is tied closely to theGame function
this is the function of the falldown or enemy timeline enemyDeploy
in this way the swf has more than one timeline */
private function enemyGo(event:TimerEvent):void
{
enemyOne.y += 20;
if (enemyOne.y >= 110 && enemyOne.alpha > 0.2)
{enemyOneBaby.y += 60;}
else {enemyOneBaby.y = enemyOne.y;enemyOneBaby.alpha = 0;}
enemyOne.alpha -= enemyOneLife;enemyOneBaby.alpha = enemyOne.alpha;
if (enemyOne.y < 500)
{ if (enemyOne.alpha <= 0.2 && enemyOne.alpha > 0.01) {theScore += .5;changeStats("Enemy destroyed");} }
enemyTwo.y += 20;
enemyTwo.alpha -= enemyTwoLife;
if (enemyTwo.y < 500)
{ if (enemyTwo.alpha <= 0.2 && enemyTwo.alpha > 0.01) {theScore += .5;changeStats("Enemy destroyed");} }
enemyThree.y += 20;
enemyThree.alpha -= enemyThreeLife;
if (enemyThree.y < 500)
{ if (enemyThree.alpha <= 0.2 && enemyThree.alpha > 0.01) {theScore += .5;changeStats("Enemy destroyed");} }
if (theScore >= 20 && theScore <= 24)
{
if (powerUp.y < 500+powerUp.height)
{powerUp.y += 30;}
else
{powerUp.y = -50;}
}
if (theScore >= 45 && theScore <= 49)
{
if (powerUp.y < 500+powerUp.height)
{powerUp.y += 38;}
else
{powerUp.y = -50;}
}
if (powerUp.x >= theShip.x - 20 && powerUp.x <= theShip.x + 20 && powerUp.y >= theShip.y - 20 && powerUp.y < 500+powerUp.height && powerUp.y <= theShip.y + 20)
{pelletPower += .008;changeStats("shot power up");upThePellets();}
}
/* stop game */
private function stopGame():void
{
gameStarted = "no";
Mouse.show();
shotGo.removeEventListener(TimerEvent.TIMER, seeShot);
shotGo.removeEventListener(TimerEvent.TIMER_COMPLETE, resetShot);
enemyDeploy.removeEventListener(TimerEvent.TIMER, enemyGo);
enemyDeploy.removeEventListener(TimerEvent.TIMER_COMPLETE, resetEnemys);
if (enemyDeploy.running == true)
{Timer(enemyDeploy).stop();}
}
/* start game */
private function startGame():void
{
gameStarted = "yes";
Mouse.hide();
shotGo.addEventListener(TimerEvent.TIMER, seeShot);
shotGo.addEventListener(TimerEvent.TIMER_COMPLETE, resetShot);
enemyDeploy.addEventListener(TimerEvent.TIMER, enemyGo);
enemyDeploy.addEventListener(TimerEvent.TIMER_COMPLETE, resetEnemys);
if (enemyDeploy.running == false)
{Timer(enemyDeploy).start();}
}
/* animation
and main game if thens
always happening */
private function theGame(event:Event):void
{
if (mouseActive =="yes")
{theShip.x = mouseX;theShip.y = mouseY;}
pellet.x = theShip.x;pelletTwo.x = theShip.x;pelletThree.x = theShip.x;
pellet.y = theShip.y - shotDistance;
if (pelletTwoGo == "yes")
{pelletTwo.y = theShip.y - shotDistance + pellet.width*3;}
else
{pelletTwo.y = theShip.y;}
if (pelletThreeGo == "yes")
{pelletThree.y = theShip.y - shotDistance + pellet.width*3 + pelletTwo.width*3;}
else
{pelletThree.y = theShip.y;}
if (gameStarted == "yes")
{
if (enemyOne.hitTestObject(pellet) || enemyOne.hitTestObject(pelletTwo) || enemyOne.hitTestObject(pelletThree))
{enemyOneLife += enemyOneToughness+pelletPower;enemyOne.y -= 5;}
if (enemyTwo.hitTestObject(pellet) || enemyTwo.hitTestObject(pelletTwo) || enemyTwo.hitTestObject(pelletThree))
{enemyTwoLife += enemyTwoToughness+pelletPower;enemyTwo.y -= 5;}
if (enemyThree.hitTestObject(pellet) || enemyThree.hitTestObject(pelletTwo) || enemyThree.hitTestObject(pelletThree))
{enemyThreeLife += enemyThreeToughness+pelletPower;enemyThree.y -= 5;}
if (theShip.hitTestObject(enemyOne))
{enemyOne.y -= 10;}
if (theShip.hitTestObject(enemyTwo))
{enemyTwo.y -= 10;}
if (theShip.hitTestObject(enemyThree))
{enemyThree.y -= 10;}
if (theShip.hitTestObject(enemyOne) && enemyOne.alpha > 0.3)
{
if (playerLife > 0)
{playerLife -=5;lifeMeterChange(lifeMeter, playerLife);changeStats("Ship damage!");}
}
if (theShip.hitTestObject(enemyTwo) && enemyTwo.alpha > 0.3)
{
if (playerLife > 0)
{playerLife -=5;lifeMeterChange(lifeMeter, playerLife);changeStats("Ship damage!");}
}
if (theShip.hitTestObject(enemyThree) && enemyThree.alpha > 0.3)
{
if (playerLife > 0)
{playerLife -=5;lifeMeterChange(lifeMeter, playerLife);changeStats("Ship damage!");}
}
if (theShip.hitTestObject(powerUp))
{powerUp.alpha -= .08;}
if (theShip.hitTestObject(enemyOneBaby) && enemyOneBaby.alpha > 0.2)
{
if (playerLife > 0)
{playerLife -=5;lifeMeterChange(lifeMeter, playerLife);changeStats("Ship damage!");}
}
var alphaMargin:Number = playerLife -15;
theShip.alpha = alphaMargin/100 + .17;
if (playerLife < 35 && playerLife > 0)
{playerLife -= .05;lifeMeterChange(lifeMeter, playerLife);changeStats("Critical ship damage!");}
else
{playerLife = playerLife;}
if (playerLife < 1)
{stopGame();changeStats("Your ship has been evaporated!");}
if (enemyOne.alpha <= 0 && enemyTwo.alpha <= 0 && enemyThree.alpha <= 0)
{resetEnemysAndTimer();}
}
if (pellet.y == theShip.y - 20)
{pellet.alpha = 0;}
else
{pellet.alpha += .05;}
if (pelletTwo.y == theShip.y)
{pelletTwo.alpha = 0;}
else
{pelletTwo.alpha += .05;}
if (pelletThree.y == theShip.y)
{pelletThree.alpha = 0;}
else
{pelletThree.alpha += .05;}
}
private function firePelletHandler(event:MouseEvent):void
{
mouseActive = "yes";
if (shotDistance > 20 && pelletTwoGo == "no")
{pelletTwoGo = "yes";Timer(shotGo).reset();changeStats("2/3 powered shot");shotNoise.play();}
if (pelletTwoGo == "yes" && pelletTwo.y < theShip.y)
{pelletThreeGo = "yes";Timer(shotGo).reset();changeStats("3/3 powered shot");shotNoise.play();}
if (shotGo.running == false)
{Timer(shotGo).reset();Timer(shotGo).start();}
}
private function keyboardFirePellet():void
{
/* this is for the keyboard event space bar 32 */
if (shotDistance > 20 && pelletTwoGo == "no")
{pelletTwoGo = "yes";Timer(shotGo).reset();changeStats("2/3 powered shot");shotNoise.play();}
if (pelletTwoGo == "yes" && pelletTwo.y < theShip.y)
{pelletThreeGo = "yes";Timer(shotGo).reset();changeStats("3/3 powered shot");shotNoise.play();}
if (shotGo.running == false)
{Timer(shotGo).reset();Timer(shotGo).start();}
}
private function seeShot(event:TimerEvent):void
{
shotDistance += 20;
}
private function resetShot(event:TimerEvent):void
{
shotDistance = 20;
pelletTwoGo = "no";pelletThreeGo = "no";
}
}
}
|