Developing a space shooter game
BASIC MOVEMENT
The first thing you need in a game is some interactivity, some movement. When you make a game you need to know what to use: keyboard or mouse. Personally I prefer to use keys, and as that is more simple, I will explain that first in these tutorials. So, lets look at what we will have by the end of this lesson.
You should be able to see a blue plane flying round the screen when you press the movement keys. So lets get down to business.
First, make the stage 550*300 pixels, set the Frames Per Second (FPS) to 25 and draw your hero. It can be anything but don't make it too big. Convert it to a Movieclip and give it the instance name of "hero".

Now, when you've done that, put the hero movieclip on the stage where you want your squirrel/penguin/whatever to start. Then make a new layer called actions and open the action pane and type:
_root.onEnterFrame = function() {
moveHero(5);
}
So whenever a new frame starts (every 25th of a second) the function moveHero will start with the parameter 5. So, now we need to write the function.
function moveHero(speed) {
//check if key is down
if (Key.isDown(Key.UP)) {
_root.hero._y -= speed;
}
else if (Key.isDown(Key.LEFT)) {
_root.hero._x -= speed;
}
else if (Key.isDown(Key.DOWN)) {
_root.hero._y += speed;
}
else if (Key.isDown(Key.RIGHT)) {
_root.hero._x += speed;
}
}
And you're done! Simple. So, lets go through it. First there is a parameter called "speed". Remember we put 5 there earlier? Well, that means the hero's speed will be 5 pixels per 25th of a second. So a bit of quick maths and the hero will move at 125 pixels/second.
Anyway, lets look at the next bit of code. A simple if statement asking if Up is down. Now that just sounds really stupid, so I'll move on. If the above statement is true, _root.hero's y property is reduced by speed. So basically _root.hero goes up, and it does this for all the other directions.
You may notice I have "else if" instead of just another if statement for every direction. This is so the hero only moves if it's being told to go one way and no other way. You do not have to do this but I think it can make the game a bit better.
SHOOTING
In the first tutorial we looked at movement, possibly the most important thing in most games. Now we will look at shooting, which seems quite complex at first, but is really simple. So lets look at what we will be making (spacebar to fire).
At the moment bullets fly out constantly, but in a later tutorial we will limit this.
Start off by drawing your bullet. Go to Insert/New Symbol and click on "Advanced" if that section is not there already. call it bullet and click the "Export for ActionScript" checkbox.

It can be anything, but I decided to keep it simple and just use a yellow dot. Make sure the bullet if positioned relative to the registration point like this:

When you've done that, go back to the main stage open the ActionScript pane and at the end of the moveHero function put this:
if (Key.isDown(Key.SPACE)) {
fireBullets();
}
We covered this sort of thing last time. When the spacebar is pressed, the function fireBullets is called. Now for the function:
var i;
var i; function fireBullets() { i++; var newname = "bullet"+i; _root.attachMovie("bullet", newname, i*100); _root[newname]._y = _root.hero._y+13; _root[newname]._x = _root.hero._x+55; _root[newname].onEnterFrame = function() { var bullet_speed = 7; this._x += bullet_speed; if (this._x>555) { this.removeMovieClip(); } };
};
}
Before the function even starts the variable "i" is set without a value and each time the function is called this variable increases by 1. A name "bullet"+i is made and then we come to the attachMovie function. This attaches a movieclip from the library and gives it a new name. "bullet" tells flash which Movieclip to attach, the next parameter is the name of the new movieclip and the last parameter is Depth, which you don't need to worry about for this sort of game. Next, the new movieclip is put to the correct x and y relative to the hero (that's what the "+13" etc. is for: adjust those values to fit the size of your hero).
Now to make the bullet move. An OnEnterFrame function for the new bullet is called. "bullet_speed" is the speed of your bullet, which is added to the _x value of the bullet to make it move. And finally, if the bullet goes of the screen to save speed the bullet is removed with removeMovieClip.
ENEMIES
If a game has no enemies, it has no fun. Enemies help give the game something to do. You can create good puzzle games without enemies, but for anything else, they are an absolute must. So let's look at what we'll be making.
The first thing you can see is that there is no collision detection. We'll be looking at that in the next chapter. So, first draw your enemies.

When you've drawn it, go back to the main timeline and give the enemy an instance name of "enemy1". Now go to the actions and add this function at the end:
var numEnemy = 3;
function Enemys()
{
for (j=2; j<=numEnemy; j++)
{
var name = "enemy" + j;
_root.enemy1.duplicateMovieClip(name, j);
}
}
Enemys();
So first the variable numEnemy is set with 3. This is the number of enemies which will be on the screen at any one time. Next a for loop starts, which basically cycles through twice (depending on numEnemy) each time making a new name (enemy+j) and then duplicating enemy1. In duplicateMovieClip("this is the new name",this is the depth). Always remember that two movieclips can't have the same depth. And then the function is called. But how will our enemies move?
onClipEvent (load) {
function reset();
{
this._x = 550;
this._y = math.random() * 300;
enemySpeed = (Math.random() * 6) + 1;
}
reset();
}
onClipEvent (enterFrame) {
this._x -= enemySpeed;
if (this._x < -10) {
reset();
}
}
Put this code on the enemy1 movie clip. When you duplicate a movie clip, it keeps its actions from the original (which is good for us). First lets look at the reset function. It sets the enemy's x property to the far edge of the stage, and gives it a random _y between 0 and 300 using the Math.random function and multiplying it by 300 as the function in itself only makes a number between 0 and 1. It then uses the random function again to make a number between 1 and 7 which we will use as the enemy's speed, as it would be boring if they all went at the same speed. Then the function is called when the movieclip loads. Simple enough.
Now we come to on enterFrame. This is even simpler. It takes the random enemySpeed variable from the _x property making it move. Then it asks: is the enemy off the screen? If yes, the enemy goes back with the reset function.
COLLISION CHECKING WITH hitTest
Invicibility is boring. That's why there is collisions. But how do you detect collisions? Lets look at what we'll be making.
So, as usual, let's start by drawing some new things. Our enemies need to be a bit more exciting, so when they die they need a little animation.

Just so the enemy doesn't keep cylcing through its dying animation, put stop(); on the first frame. And when the animation is over, the enemy has to reset so on the last frame put:
this.reset(); gotoAndStop(1);
Now we need a game over screen.

Make a button and put this code on it for restarting.
on(release) {
gotoAndStop(1);
}
Now thats all the drawing you need to do on this tutorial, so lets move on to the coding. The first and most important thing we need to detect is bullets on the enemies. First a bit of theory on the hitTest.
The "hitTest(movieclip)" method, which we'll be using, has a major disadvantage. If you look in the picture above you can see very clearly the rectangular "bounding box" of each movie clip. Our problem is that hitTest checks for the collisions of bounding boxes not the shapes. In a fast-paced game like this where the movieclips are squarish (is that the word?) anyway, this method is the simplest and easiest to use. So, now we've got that out the way, have a look at our fireBullets function from tutorial 2.
_root[newname].onEnterFrame = function() {
var bullet_speed = 10;
this._x += bullet_speed;
if (this._x > 555) {
this.removeMovieClip();
}
}
So, take this bit. This is where we will add our hitTest. After the if statement, put this code:
for (var h = 1; h <= numEnemy; h++)
{
if (this.hitTest(_root["enemy"+h]))
{
this.removeMovieClip();
_root["enemy"+h].play();
}
}
First there is a for loop rather like the one in the enemies function, except it starts as 1, not 2 because it needs to cycle through all the enemies, not just the dupicated ones. Then, using the hitTest method I talked about earlier it checks if there is a collision. If there is, it removes the bullet movieclip and plays the death animation of the enemy. It doesn't do the reset function yet for the enemy, because remember we put that at the end of the death animation. So, your enemies can die, so its time your hero can as well!
if (this.hitTest(_root.hero))
{
_root.gotoAndStop(2);
}
Put that on the enemy with its movement code. Just to let you know, it basicly checks for a collision with the hero and then (if true) takes the movie to frame 2, the game over screen.
You've done it again! You have just completed one of the most important parts of your game. All that is needed now is a few enhancements, sound, scores, structured levels... And you'll have you very own online Flash game! If you have any problems email me at
SCORES
What is the point of playing a game if you don't know how well you played? You need to know your score because otherwise people just won't bother to play. Luckly for us, scores are actually quite simple. Lets look at the swf:
It's not that different from what we had in the last tutorial, but in the top left hand corner it displays your score. So first you need a dynamic text box.

Write score as static text and make a dynamic textbox next to it and give it the varible name "score" as shown above. Now to the beginning of your code put:
_root.score = 0;
This is just to set the original value of score to 0. But where do we put the code to add scores? If we put it in the hitTest bit of the bullet code, then the score will keep going up and up untill the death animation is finished. The best thing to do is to put the code at the end of the death animation. So, in your enemy movieclip on the last frame put:
_root.score += 50;
Simple! Finished!