Upload
juan-manuel
View
194
Download
5
Embed Size (px)
Citation preview
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.
01
02
03
04
05
06
07
08
09
10
11
12
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.
03
04
05
06
07
08
09
10
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.
14
15
16
17
18
19
20
21
22
23
24
25
26
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.
30
31
32
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�.
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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.
78
79
80
81
82
83
84
85
86
87
88
89
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.
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
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.
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
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:
133
134
135
136
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.
138
139
140
141
142
143
144
145
146
147
148
149
150
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.
152
153
154
155
156
157
158
159
160
161
162
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
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.
183
184
185
186
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.
187
188
189
190
191
192
193
194
195
196
197
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.
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
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:
220
221
222
223
224
225
226
227
228
229
230
231
232
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.
236
237
238
239
240
241
242
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:
244
245
246
247
248
/* 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.
250
251
252
253
254
/* 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.
256
257
258
259
260
/* 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.
262
263
264
265
266
267
268
269
270
271
272
273
274
/* 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.
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
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.
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
/* 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.
320
321
322
323
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.
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
/* 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:
362
363
364
365
/* 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:
367
368
369
370
371
372
373
/* 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:
375
376
377
/* 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!