Create a Space Shooter Game in Flash Using AS3 Download Source Files 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 320×480 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. 01package 02{ 03
import flash.display.Sprite;
04 05
public class Main extends Sprite
06
{
07
public function Main():void
08
{ // constructor code
09
}
10 11
}
12}
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. 03import flash.display.Sprite; 04import flash.ui.Mouse; 05import com.greensock.TweenNano; 06import com.greensock.easing.Expo; 07import flash.events.MouseEvent; 08import flash.events.Event; 09import flash.utils.Timer; 10import 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 14private var starsCopy:Sprite; //Another version of the stars background 15private var ship:Ship; 16private var bullets:Vector. = new Vector.(); //Will hold the 17bullets in stage 18private var enemies:Array = new Array(); //Will hold the enemies in stage 19private var timer:Timer = new Timer(500); //The time in which a new enemy will 20appear 21private var alertView:AlertView; 22private var lives:Vector.; //Will store the lives graphics 23private var boss:Boss; 24private var bossHealth:int = 20; 25private var laserSound:Laser = new Laser(); 26private 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. 30public final function Main():void
{ 31
buildStars(200); //This function starts the game creation
32}
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 .
37private final function buildStars(n:int):void 38{ 39
stars = new Sprite();
40 41
for(var i:int = 0; i < n; i++)
42
{ var star:Star = new Star();
43 44 45
star.alpha = Math.random() * 1;
46
star.scaleX = Math.random() * 1;
47
star.scaleY = star.scaleX;
48
star.x = Math.floor(Math.random() * stage.stageWidth);
49
star.y = Math.floor(Math.random() * stage.stageHeight-20);
50
stars.addChild(star);
51 52
}
53 54
/* Create another stars sprite to make animation */
55 56
starsCopy = new Sprite();
57 58
for(var j:int = 0; j < n; j++)
59
{ var star2:Star = new Star();
60 61 62
star2.alpha = Math.random() * 1 + 0.2;
63
star2.scaleX = Math.random() * 1;
64
star2.scaleY = star.scaleX;
65
star2.x = Math.floor(Math.random() * stage.stageWidth);
66
star2.y = Math.floor(Math.random() * stage.stageHeight-20);
67
starsCopy.addChild(star2);
68 69
}
70 71
starsCopy.y = -stage.stageHeight;
72 73
addChild(starsCopy);
74
addChild(stars);
75
addShip(); //Add ship (player) to stage
76}
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 78
{
79
ship = new Ship();
80
ship.x = stage.stageWidth * 0.5;
81
ship.y = stage.stageHeight + ship.height;
82 83
addChild(ship);
84 85 86
TweenNano.to(ship, 2, {y: (stage.stageHeight - ship.height) - 10, ease:Expo.easeOut, onComplete:listeners()});
87 88 89
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 091
{
092
lives = new Vector.();
093 094 095
for(var i:int = 0; i < 3; i++) {
096
var live:Ship = new Ship();
097 098
live.stop();
099
live.width = 16;
100
live.height = 16;
101
live.x = (stage.stageWidth - live.width * 0.7) - (5 * i+1) -
102
live.width * i;
103
live.y = stage.stageHeight - live.height * 0.7;
104 105
addChild(live);
106 107 108 109
}
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. 111private final function listeners(action:String = 'add'):void 112{ 113
if(action == 'add')
114
{
115
stage.addEventListener(MouseEvent.MOUSE_MOVE, moveShip);
116
stage.addEventListener(MouseEvent.MOUSE_DOWN, shoot);
117
timer.addEventListener(TimerEvent.TIMER, addEnemy);
118
stage.addEventListener(Event.ENTER_FRAME, update);
119
timer.start();
120 121
}
122
else
123
{
124
stage.removeEventListener(MouseEvent.MOUSE_MOVE, moveShip);
125
stage.removeEventListener(MouseEvent.MOUSE_DOWN, shoot);
126
timer.removeEventListener(TimerEvent.TIMER, addEnemy);
127 128
stage.removeEventListener(Event.ENTER_FRAME, update);
129
timer.stop();
130
}
131}
Step 21: Move Ship The player’s ship will be mouse controlled, the next function handles that: 133private final function moveShip(e:MouseEvent):void 134{ 135 136}
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. 138private final function shoot(e:MouseEvent):void 139{ 140
var bullet:Bullet = new Bullet();
141 142
bullet.x = ship.x;
143
bullet.y = ship.y - (ship.height * 0.5);
144 145
laserSound.play(); //Play sound
146 147
bullets.push(bullet);
148 149
addChild(bullet);
150}
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. 152private final function addEnemy(e:TimerEvent):void 153{ 154
var enemy:Enemy = new Enemy();
155 156
enemy.x = Math.floor(Math.random() * (stage.stageWidth - enemy.width));
157
enemy.y = -enemy.height;
158 159
enemies.push(enemy);
160 161 162}
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 164private final function alert(t:String, m:String):void 165{ 166
listeners('remove');
167 168
/* Create and show alert */
169 170
alertView = new AlertView();
171 172
alertView.x = stage.stageWidth * 0.5;
173
alertView.y = stage.stageHeight * 0.5;
174 175
alertView.titleTF.text = t;
176
alertView.msgTF.text = m;
177 178
alertView.addEventListener(MouseEvent.MOUSE_UP, restart);
179 180
addChild(alertView);
181}
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. 183private final function update(e:Event):void 184{ 185 186}
//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. 187stars.y += 5; 188starsCopy.y += 5; 189 190if(stars.y >= stage.stageHeight - 20) 191{ 192
stars.y = -stars.height;
193} 194else if(starsCopy.y >= stage.stageHeight - 20) 195{ 196
starsCopy.y = -stars.height;
197}
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. 201if(bullets.length != 0) 202{ 203
for(var i:int = 0; i < bullets.length; i++)
204
{ bullets[i].y -= 10;
205 206
/* Destroy offstage bullets */
207 208 209
if(bullets[i].y < 0)
210
{
211
removeChild(bullets[i]);
212
bullets[i] = null;
213
bullets.splice(i, 1); }
214 215 216}
}
Step 28: Boss We’ll add a big and bad boss to the game. When the user reaches certain score, the boss will appear: 220if(int(scoreTF.text) == 500 && boss == null) 221{ 222
boss = new Boss();
223 224
bossSound.play();
225 226
boss.x = stage.stageWidth * 0.5;
227
boss.y = -boss.height;
228 229
TweenNano.to(boss, 3, {y: 80});
230 231
addChild(boss);
232}
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. 236if(enemies.length != 0) 237{ 238
for(var j:int = 0; j < enemies.length; j++)
239
{
240
/* Move enemies */
241 242
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: 244/* if enemy hits player */ 245 246if(enemies[j].hitTestObject(ship)) 247{ 248
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. 250/* Remove enemy */ 251 252removeChild(enemies[j]); 253enemies[j] = null; 254enemies.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. 256/* Remove Live */ 257 258removeChild(lives[lives.length-1]); 259lives[lives.length-1] = null; 260lives.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 */ 262 263
if(lives.length == 0)
264
{
265
alert('Game Over', 'Click to continue');
266
}
267
else
268
{
269
/* Tween Ship */
270 271 272 273
ship.y = stage.stageHeight + ship.height; TweenNano.to(ship, 2, {y: (stage.stageHeight - ship.height),
ease:Expo.easeOut});
274
}
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. 276for(var k:int = 0; k < bullets.length; k++) 277{ 278
/* Hit Boss */
279 280
if(boss != null && bullets[k].hitTestObject(boss))
281
{ exSound.play();
282 283 284
removeChild(bullets[k]);
285
bullets[k] = null;
286
bullets.splice(k, 1);
287
bossHealth--;
288
scoreTF.text = String(int(scoreTF.text) + 50);
289 290
}
291 292
if(bossHealth <= 0 && boss != null)
293
{
294
removeChild(boss);
295
boss = null;
296
alert('You Won', 'Click to continue');
297
}
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 */ 299 300if(bullets.length != 0 && enemies[j] != null && 301bullets[k].hitTestObject(enemies[j])) 302{ 303
exSound.play(); //Play sound
304 305
removeChild(enemies[j]);
306
enemies[j] = null;
307
enemies.splice(j, 1);
308 309
removeChild(bullets[k]);
310
bullets[k] = null;
311
bullets.splice(k, 1);
312 313
scoreTF.text = String(int(scoreTF.text) + 50); //Add score to the
314textfield 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. 320private final function restart(e:MouseEvent):void 321{ 322
//code
323}
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. 1322/* Remove Graphics */ 1323 1324removeChild(ship); 1325ship = null; 1326 1327for(var i:int = 0; i < bullets.length; i++) 1328{ 1329
removeChild(bullets[i]);
1330
bullets[i] = null;
1331} 1332 1333bullets.length = 0; 1334 1335for(var j:int = 0; j < enemies.length; j++) 1336{ 1337
removeChild(enemies[j]);
1338
enemies[j] = null;
1339} 1340 1341enemies.length = 0; 1342 1343for(var k:int = 0; k < lives.length; k++) 1344{ 1345
removeChild(lives[k]);
1346
lives[k] = null;
1347} 1348 1349lives.length = 0; 1350 1351removeChild(stars); 1352stars = null; 1353removeChild(starsCopy); 1354starsCopy = null; 1355 1356if(boss != null) 1357{ 1358
removeChild(boss);
1359
boss = null;
1360}
Step 38: Remove Alert The next part of restart() removes the Alert View from the stage: 362/* Remove Alert */ 363 364removeChild(alertView); 365alertView = null;
Step 39: Reset Score/Boss Health In the next part of restart(), the score and boss health variables are reset: 367/* Reset Score */ 368 369scoreTF.text = '0'; 370 371/* Reset Boss Health */ 372 373bossHealth = 50;
Step 40: Call Restart Method Finally, at the end of restart(), we call the method that starts everything: 375/* Restart */ 376 377buildStars(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!