Video icon 64
Build your coding skills with practical video courses from Tuts+. Start your free trial today.
Advertisement

Create a Space Shooter Game in Flash Using AS3

by
Student iconAre you a student? Get a yearly Tuts+ subscription for $45 →

Follow the straight-forward steps of this Premium Tutorial to create an entertaining shoot-'em-up with Flash and AS3.


Step 1: Brief Overview

Using pre-made sprites and the Flash Tools, we'll create a good looking graphic interface that will be powered by several ActionScript 3 classes.

The user will be able to control a spaceship and shoot multiple enemies while traveling in space.


Step 2: Flash Document Settings

Open Flash and create a 320 pixels wide, 480 pixels tall document. Set the Frame rate to 24fps.



Step 3: Interface


Our interface will be composed of several sprites, text fields and movie clips.

Continue on to the next steps and we'll look at how to create it.


Step 4: Background

The background will be very simple, as the stars are generated using ActionScript.

Create a 320x480 px rectangle and fill it with black. You could add a slight radial gradient.


Use the Align Panel (Cmd + K) to center it in the stage.


Step 5: Sprites

I've used a great sprite library in the demo of this tutorial, these are part of the SpriteLib by Flying Yogi.



Step 6: Sprite MovieClips

Import the sprites to the stage (Cmd+ R), convert them to MovieClips, and adjust the frames to display a nice animation.



Step 7: Score TextField

A Dynamic TextField will be needed to display the game score. Use the Text Tool (T) to create one; name it scoreTF and place it in the bottom-left corner of the stage.



Step 8: Embed Font

In order to use a custom font in a dynamic textfield, you must embed it in your application. Select the textfield and use the Properties panel's Embed... button to add the necessary characters.



Step 9: Alert View

The Alert View will be shown when the user reaches a game state, (win, lose). Use your desired font to create a simple screen with two dynamic textfields; name them titleTF and msgTF, convert the box to a MovieClip and set its class name to AlertView.



Step 10: Sounds


We'll use Sound Effects to enhance the feeling of the game, you can find the sounds used in this example in Soungle.com using the keywords space, explosion and laser.


Step 11: Tween Nano


We'll use a different tween engine from the default included in Flash, this will increase performace and be easier to use.

You can download Tween Nano from its official website.


Step 12: New ActionScript Class

Create a new (Cmd + N) ActionScript 3.0 Class and save it as Main.as in your class folder.



Step 13: Class Structure

Create your basic class structure to begin writing your code.

 
package  
{ 
	import flash.display.Sprite; 
	 
	public class Main extends Sprite 
	{ 
		public function Main():void 
		{ 
			// constructor code 
		} 
	} 
}

Step 14: Required Classes

These are the classes we'll need to import for our class to work; the import directive makes externally defined classes and packages available to your code.

 
import flash.display.Sprite; 
import flash.ui.Mouse; 
import com.greensock.TweenNano; 
import com.greensock.easing.Expo; 
import flash.events.MouseEvent; 
import flash.events.Event; 
import flash.utils.Timer; 
import flash.events.TimerEvent;

Step 15: Variables

These are the variables we'll use, read the comments in the code to know more about them.

 
private var stars:Sprite; // Will store the stars background 
private var starsCopy:Sprite; //Another version of the stars background 
private var ship:Ship; 
private var bullets:Vector.<Sprite> = new Vector.<Sprite>(); //Will hold the bullets in stage 
private var enemies:Array = new Array(); //Will hold the enemies in stage 
private var timer:Timer = new Timer(500); //The time in which a new enemy will appear 
private var alertView:AlertView; 
private var lives:Vector.<Sprite>; //Will store the lives graphics 
private var boss:Boss; 
private var bossHealth:int = 20; 
private var laserSound:Laser = new Laser(); 
private var bossSound:UFO = new UFO(); 
private var exSound:Explosion = new Explosion();

Step 16: Constructor Code

The constructor is a function that runs when an object is created from a class, this code is the first to execute when you make an instance of an object or runs using the Document Class.

It calls the necessary functions to start the game. Check those functions in the next steps.

 
public final function Main():void<br />{ 
	buildStars(200); //This function starts the game creation 
}

Step 17: Build Stars

The buildStars() method uses the Star MC in the library to create a background with randomly placed stars. Two sprites are created in order to tween both of them and simulate movement, using the same trick as in this parallax scrolling tutorial.

 
private final function buildStars(n:int):void 
{ 
	stars = new Sprite(); 
	 
	for(var i:int = 0; i < n; i++) 
	{ 
		var star:Star = new Star(); 
		 
		star.alpha = Math.random() * 1; 
		star.scaleX = Math.random() * 1; 
		star.scaleY = star.scaleX; 
		star.x = Math.floor(Math.random() * stage.stageWidth); 
		star.y = Math.floor(Math.random() * stage.stageHeight-20); 
		 
		stars.addChild(star); 
	} 
	 
	/* Create another stars sprite to make animation */ 
	 
	starsCopy = new Sprite(); 
	 
	for(var j:int = 0; j < n; j++) 
	{ 
		var star2:Star = new Star(); 
		 
		star2.alpha = Math.random() * 1 + 0.2; 
		star2.scaleX = Math.random() * 1; 
		star2.scaleY = star.scaleX; 
		star2.x = Math.floor(Math.random() * stage.stageWidth); 
		star2.y = Math.floor(Math.random() * stage.stageHeight-20); 
		 
		starsCopy.addChild(star2); 
	} 
	 
	starsCopy.y = -stage.stageHeight; 
	 
	addChild(starsCopy); 
	addChild(stars); 
	addShip(); //Add ship (player) to stage 
}

Step 18: Add Ship

This function creates an instance of the Ship MC in the library and places it on the stage with a neat animation.

 
private final function addShip():void 
{ 
	ship = new Ship(); 
	ship.x = stage.stageWidth * 0.5; 
	ship.y = stage.stageHeight + ship.height; 
	 
	addChild(ship); 
	 
	TweenNano.to(ship, 2, {y: (stage.stageHeight - ship.height) - 10, ease:Expo.easeOut, onComplete:listeners()}); 
	 
	addLives(); 
}

Step 19: Add Lives

Reusing the Ship MC, three ship sprites are added to the stage as a lives indicator. The ships are added to a Vector to check for game over later in the game.

 
private final function addLives():void 
{ 
	lives = new Vector.<Sprite>(); 
	  
	for(var i:int = 0; i < 3; i++) 
	{ 
		var live:Ship = new Ship(); 
		 
		live.stop(); 
		live.width = 16; 
		live.height = 16; 
		live.x = (stage.stageWidth - live.width * 0.7) - (5 * i+1) - live.width * i; 
		live.y = stage.stageHeight - live.height * 0.7; 
		 
		addChild(live); 
		 
		lives.push(live); 
	} 
}

Step 20: Add Listeners

These lines will add the necessary listeners to the stage and timer; this includes Mouse events, Timer events and and EnterFrame events that will update the game every frame.

 
private final function listeners(action:String = 'add'):void 
{ 
	if(action == 'add') 
	{ 
		stage.addEventListener(MouseEvent.MOUSE_MOVE, moveShip); 
		stage.addEventListener(MouseEvent.MOUSE_DOWN, shoot); 
		timer.addEventListener(TimerEvent.TIMER, addEnemy); 
	 
		stage.addEventListener(Event.ENTER_FRAME, update); 
		timer.start(); 
	} 
	else 
	{ 
		stage.removeEventListener(MouseEvent.MOUSE_MOVE, moveShip); 
		stage.removeEventListener(MouseEvent.MOUSE_DOWN, shoot); 
		timer.removeEventListener(TimerEvent.TIMER, addEnemy); 
	 
		stage.removeEventListener(Event.ENTER_FRAME, update); 
		timer.stop(); 
	} 
}


Step 21: Move Ship

The player's ship will be mouse controlled, the next function handles that:

 
private final function moveShip(e:MouseEvent):void 
{ 
	ship.x = mouseX; 
}

Step 22: Shoot

Our ship will be able to shoot bullets to destroy and protect itself from enemies. This function will run every time the user clicks the stage and will place a bullet in front of the ship that will be later moved by the update() function. It also plays a shooting sound.

 
private final function shoot(e:MouseEvent):void 
{ 
	var bullet:Bullet = new Bullet(); 
	 
	bullet.x = ship.x; 
	bullet.y = ship.y - (ship.height * 0.5); 
	 
	laserSound.play(); //Play sound 
	 
	bullets.push(bullet); 
	 
	addChild(bullet); 
}

Step 23: Add Enemy

It wouldn't be a shooter without something to shoot. The enemies are created by the next function, a Timer is used to create an enemy every 500 milliseconds (you can change that value in the variables step) which is later moved by the update() function.

 
private final function addEnemy(e:TimerEvent):void 
{ 
	var enemy:Enemy = new Enemy(); 
	 
	enemy.x = Math.floor(Math.random() * (stage.stageWidth - enemy.width)); 
	enemy.y = -enemy.height; 
	 
	enemies.push(enemy); 
	 
	addChild(enemy); 
}

Step 24: Alert View

The Alert View shows the player information about the status of the game, it is shown when a game event is reached.

Two parameters are used in this function:

  • t: The alert title
  • m: A short message
 
private final function alert(t:String, m:String):void 
{ 
	listeners('remove'); 
	 
	/* Create and show alert */ 
	 
	alertView = new AlertView(); 
	 
	alertView.x = stage.stageWidth * 0.5; 
	alertView.y = stage.stageHeight * 0.5; 
	 
	alertView.titleTF.text = t; 
	alertView.msgTF.text = m; 
	 
	alertView.addEventListener(MouseEvent.MOUSE_UP, restart); 
	 
	addChild(alertView); 
}

Step 25: Update

The update() function is executed every frame, it handles all the game movement and collisions. It is the game loop function for this game. Take a look at the next steps to see its behavior.

 
private final function update(e:Event):void 
{ 
    //code 
}

Step 26: Move Background

The background is moved every frame to simulate space travel; when the bottom stars sprite reaches the stage limit it is moved back to the top, creating a loop.

 
stars.y += 5; 
starsCopy.y += 5; 
 
if(stars.y >= stage.stageHeight - 20) 
{ 
	stars.y = -stars.height; 
} 
else if(starsCopy.y >= stage.stageHeight - 20) 
{ 
	starsCopy.y = -stars.height; 
}

Step 27: Move Bullets

The next lines of code check if there are bullets in stage; if true, the bullets are moved upwards; when a bullet is no longer visible, it's destroyed.

 
if(bullets.length != 0) 
{ 
	for(var i:int = 0; i < bullets.length; i++) 
	{ 
		bullets[i].y -= 10; 
		 
		/* Destroy offstage bullets */ 
		 
		if(bullets[i].y < 0) 
		{ 
			removeChild(bullets[i]); 
			bullets[i] = null; 
			bullets.splice(i, 1); 
		} 
	} 
}

Step 28: Boss

We'll add a big and bad boss to the game. When the user reaches certain score, the boss will appear:

 
if(int(scoreTF.text) == 500 && boss == null) 
{ 
	boss = new Boss(); 
	 
	bossSound.play(); 
	 
	boss.x = stage.stageWidth * 0.5; 
	boss.y = -boss.height; 
	 
	TweenNano.to(boss, 3, {y: 80}); 
	 
	addChild(boss); 
}

Step 29: Move Enemies

The enemies are also moved every frame. This code finds all the enemies in the stage using the array and moves them 5px downwards.

 
if(enemies.length != 0) 
{ 
	for(var j:int = 0; j < enemies.length; j++) 
	{ 
		/* Move enemies */ 
		 
		enemies[j].y += 5;

Step 30: Enemy-Ship Collision

Here we check whether an enemy collides with the player's ship; if it does, a series of actions are performed starting with the explosion sound:

 
/* if enemy hits player */ 
	 
if(enemies[j].hitTestObject(ship)) 
{ 
	exSound.play();

Step 31: Destroy Enemy

After playing the sound, the enemy is removed from the stage and the array, and is set to null in order to (eventually) clear it from memory.

 
/* Remove enemy */ 
 
removeChild(enemies[j]); 
enemies[j] = null; 
enemies.splice(j, 1);

Step 32: Remove Live

One of the lives counter's icons will also be removed in the same way as the enemy.

 
/* Remove Live */ 
 
removeChild(lives[lives.length-1]); 
lives[lives.length-1] = null; 
lives.splice(lives.length-1, 1);

Step 33: Test for Game Over

Then we check the lives number, if the player is out of lives we use the alert method to display an alert indicating game over, if there are still lives available the ship is animated into the stage.

 
/* If no lives left, game over */ 
 
if(lives.length == 0) 
{ 
	alert('Game Over', 'Click to continue'); 
} 
else 
{ 
	/* Tween Ship */ 
	 
	ship.y = stage.stageHeight + ship.height; 
	TweenNano.to(ship, 2, {y: (stage.stageHeight - ship.height), ease:Expo.easeOut}); 
}

Step 34: Hit Boss

The following code handles the boss collisions, it uses the same method used in the enemy-ship collision. Here we use the bossHealth variable to determine when the boss is defeated.

 
for(var k:int = 0; k < bullets.length; k++) 
{ 
	/* Hit Boss */ 
	 
	if(boss != null && bullets[k].hitTestObject(boss)) 
	{ 
		exSound.play(); 
		 
		removeChild(bullets[k]); 
		bullets[k] = null; 
		bullets.splice(k, 1); 
		 
		bossHealth--; 
		scoreTF.text = String(int(scoreTF.text) + 50); 
	} 
	 
	if(bossHealth <= 0 && boss != null) 
	{ 
		removeChild(boss); 
		boss = null; 
		alert('You Won', 'Click to continue'); 
	}

Step 35: Bullet-Enemy Collision

Another collision detection code. The bullets in the array are tested for collision with the enemies; when this happens, both are removed from the stage and their arrays.

 
/* if bullet hits enemy */ 
 
if(bullets.length != 0 && enemies[j] != null && bullets[k].hitTestObject(enemies[j])) 
{ 
	exSound.play(); //Play sound 
	 
	removeChild(enemies[j]); 
	enemies[j] = null; 
	enemies.splice(j, 1); 
 
	removeChild(bullets[k]); 
	bullets[k] = null; 
	bullets.splice(k, 1); 
	 
	scoreTF.text = String(int(scoreTF.text) + 50); //Add score to the textfield in stage 
}

Step 36: Restart Function

The restart function() is called by the alert() function, it handles the necessary operations to reset the game and restart it.

 
private final function restart(e:MouseEvent):void 
{ 
    //code 
}

Step 37: Remove Sprites

The first part of the restart() function handles the sprites, the next lines of code remove all the images from the stage.

 
/* Remove Graphics */ 
 
removeChild(ship); 
ship = null; 
 
for(var i:int = 0; i < bullets.length; i++) 
{ 
	removeChild(bullets[i]); 
	bullets[i] = null; 
} 
 
bullets.length = 0; 
 
for(var j:int = 0; j < enemies.length; j++) 
{ 
	removeChild(enemies[j]); 
	enemies[j] = null; 
} 
 
enemies.length = 0; 
 
for(var k:int = 0; k < lives.length; k++) 
{ 
	removeChild(lives[k]); 
	lives[k] = null; 
} 
 
lives.length = 0; 
 
removeChild(stars); 
stars = null; 
removeChild(starsCopy); 
starsCopy = null; 
 
if(boss != null) 
{ 
	removeChild(boss); 
	boss = null; 
}

Step 38: Remove Alert

The next part of restart() removes the Alert View from the stage:

 
/* Remove Alert */ 
 
removeChild(alertView); 
alertView = null;

Step 39: Reset Score/Boss Health

In the next part of restart(), the score and boss health variables are reset:

 
/* Reset Score */ 
 
scoreTF.text = '0'; 
 
/* Reset Boss Health */ 
 
bossHealth = 50;

Step 40: Call Restart Method

Finally, at the end of restart(), we call the method that starts everything:

 
/* Restart */ 
 
buildStars(200);

Step 41: Document Class


Add the class name to the Class field in the Publish section of the Properties panel to associate the FLA with the Main document class.


Conclusion

You've learned how to create a Space Shooter game with all its basic features, try to expand it using what you already know!

I hope you liked this tutorial, thank you for reading!

Advertisement