This is my version of the Space Invaders game.
We are going to create just 3 levels , but you can go on and create as many as you like. I will use the mouse to move the defender and fire bullets
Go here to play the game
First off , Make the movie 700 x 400 and set the frame rate at 25 frames/per/second. Then make 3 layers and call them : actions, text, defender.
In frame 1 , layer "text" Put some text describing your gameplay("use the mouse"), a title and a start button. You can put some background graphics etc as well in here
Make a Start button. Select your button, and open the code window (F9) and put this code in:
on(release){ _root.gotoAndStop(2); }This is very basic. All it does, of course, is take us to frame 2.
Create 3 alien sprites. Make them 30x30. Also make a defender about 40X25. Call the mc "Defender". Call the Alien mc's "Alien", "Bug" and "Skull". Go to the Library window(F11) and right click on Alien. Select "Linkage" and then tick "Export for Actionscript" and "Export in first frame". In the identifier box , name it "alien". Do the same for Bug and Skull. Call them "bug" and "skull" in the identifier box. That will be their actionscript mc name. If you leave these names the same you will not need to change the code even if you create different creatures.
Make a bomb mc and a Bullet mc. Name them "Bomb" and "Bullet". In their linkage windows call them "bomb" and "bullet".
So that is it for the sprites. We have a: Alien, Bug, Skull, Bomb, Bullet, and a Defender.
Select your "actions" layer and put this code in :
stop();This code stops the playhead going to frame 2 until the user has pressed the start button, and initialises our variables that we will use later.
bombNum = 0;
lives = 5;
score = 0;
speed=15;
We will write a global function which will allow use to initialize the various types of baddies and to call it in one line of code. We can reuse it by simply passing the name of the baddie to the function. like so : initAliens("bug") or initAliens("skull"). Notice that we pass the linkage name and not the MC name.
Here it is. Copy this after the speed = 10 line, in the actions layer, frame 1 :
_global.initAliens = function(mc) {
depth = 0;
for (var i = 0; i<3; i++) {
for (var j = 0; j<10; j++) {
attachMovie(mc, mc+i+"_"+j, 100+depth);
_root[mc+i+"_"+j]._x = j*40;
_root[mc+i+"_"+j]._y = i*40-80;
depth++;
}
}
};
It is pretty self-explanatory. I use a 2 Dimensional Array, 3 by 10 , and use 2 for loops to go through and name and attach the aliens according to their rows and columns. Then their x and y positions are determined by their row and column numbers. I have given them depths of 100+. That is because the bullets will be given number from 0+. It is good to give each sprite and their duplicates the same hundreds number. I will be using 200+ for the bombs. So if I had more ranges of duplicated or attached clips i would use 300+, 400+, etc... Each mc must be on its own depth, otherwise it will be overwritten.
We will now write the global function that will allow us to move the aliens and allows us to test for any collisions with the defender's bullets. We have jammed a lot in here because I want to have as few loops as possible so that the game runs as fast as can be. 3 arguments will be passed to the function: the mc name(alien, bug, or skull), the next frame number, and the baddies' speed. Write it on frame 1, actions layer after the above code. Here it is:
_global.moveAliens = function(mc, frame,alspeed) {
_root.deadcount = 0;
for (var i = 0; i<3; i++) {
for (var j = 0; j<10; j++) {
_root[mc+i+"_"+j]._x += speed;
if(_root[mc+i+"_"+j].hitTest(_root.defender)){
cleanup(mc);
_root.gotoAndStop(1);
}
if (_root[mc+i+"_"+j] != null) {
++_root.deadcount;
}
bulleti = 6;
while (--bulleti>0) {
if (_root[mc+i+"_"+j].hittest(eval("_root.bullet"+bulleti))) {
_root[mc+i+"_"+j].removeMovieClip();
eval("_root.bullet"+bulleti).removeMovieClip();
_root.score += 1;
}
}
if (_root[mc+i+"_"+j]._x<0) {
speed = alspeed;
dropdown = true;
break;
}
if (_root[mc+i+"_"+j]._x>Stage.width) {
// set direction to left
speed = -alspeed;
dropdown = true;
break;
}
}
}
if (dropdown) {
for (var i = 0; i<3; i++) {
for (var j = 0; j<10; j++) {
_root[mc+i+"_"+j]._y += 20;
}
}
}
dropdown = false;
if (_root.deadcount == 0) {
_root.bombspeed = 0.0;
_root.gotoAndStop(frame);
}
};
So what does this do. We set up 2 loops to go through each alien. We :
This function will randomly drop bombs at a random time set by bombspeed, the argument passed to this function. I have used the deprecated random() function as well as the newer Math.random() which returns a random number between 0 and 1. I have also set the bombs to have a random starting x and y position. If the bombNumber is greater than 10 , it simply starts again at 0. Add this code in frame 1 , actions layer, after the above moveAliens function:
_global.initBombs = function(bombspeed) {
if (Math.random()<bombspeed) {
attachMovie("bomb", "bomb"+bombNum, 200+bombNum);
eval("_root.bomb"+bombNum)._x = random(700);
eval("_root.bomb"+bombNum)._y = 300*Math.random();
bombNum++;
if (bombNum>10) {
bombNum = 0;
}
}
};
This function will move the bombs and do collision detection on the defender.
If the bomb hits a defender, it will be removed and lives will be decremented.
If all the lives are gone, then the user will be returned to frame 1, The mouse will be shown, the bombspeed set to 0 so that the bombs will stop falling in frame 1, and all the baddies will be set to invisible.
If any bombs go offscreen , they are removed. Notice the use of a break statement after the collision detection. There is no need to continue with testing if it goes offscreen. Use a break when you dont need to continue in a loop and save time and speed. I have also used break statements in the moveAliens function after a baddie has hit the wall.
_global.moveBombs = function(mc) {
var bombi = 0;
while (bombi<11) {
_root["bomb"+bombi]._y += 5;
if (_root["bomb"+bombi].hittest(_root.defender)) {
_root["bomb"+bombi].removeMovieClip();
_root.lives -= 1;
if (_root.lives<=0) {
Mouse.show();
_root.bombspeed = 0.0;
_root.gotoAndStop(1);
for (var i = 0; i<3; i++) {
for (var j = 0; j<10; j++) {
_root[mc+i+"_"+j]._visible = false;
}
}
break;
}
}
if (_root["bomb"+bombi]._y>Stage.height) {
_root["bomb"+bombi].removeMovieClip();
}
bombi++;
}
};
This function cleans up before the user is returned to frame 1. It sets the bombspeed to 0 , and makes all the baddies invisible. If not done the baddies continue in the foreground when a user is taken back to frame 1.
Put this code in frame 1, actions layer , after the moveBombs function :
_global.cleanup = function(mc) {
_root.bombspeed = 0.0;
for (var i = 0; i<3; i++) {
for (var j = 0; j<10; j++) {
_root[mc+i+"_"+j]._visible = false;
}
}
};
That finishes off frame 1. To recap,
In each layer hit F6 to make new keyframes. In frame 2, "text" layer, delete all text and the button and create 2 dynamic textFields. Write "score" and "lives" in their variable fields in their respective properties windows. I have put them up the top left and right. Make some static text fields next to each and write something like "Score: " and " Lives :".
Select Frame 2, "defender" layer. Drag the Defender mc from the Library to the bottom of the stage. In the "properties" window, type "defender" in the instance name box.
Select Frame 2, "actions" layer and type this in the Action window:
stop();
bulletNum = 0;
dropdown = false;
speed = 10;
_root.bombspeed = 0.1;
initAliens("alien");
This code stops the playhead at this frame, initialises the variables for this frame, and calls the global function initAliens("alien") that we declared in frame 1. We will reuse this line in each level to initialise our baddies.
After that we will put in our code for our our onLoad method. All it does it hide the mouse. So, type in this after the above code : </>
_root.onLoad = function() {
Mouse.hide();
};
Now we need to write our code for our enterFrame method. I have made everything fit into this one loop. It is our timer and every 25 times per second(our framerate), this code is executed. Enter this code in frame 2, "actions" layer after the onload method:
_root.onEnterFrame = function() {
_root.defender._x = _root._xmouse;
_root.defender._y = 385;
var y = 0;
while (y<6) {
eval("_root.bullet"+y)._y -= 30;
y++;
}
moveBombs("alien");
moveAliens("alien", 3,10);
initBombs(_root.bombspeed);
};
In the enterframe method we mainly use the functions we wrote earlier and we will reuse them on every level. We will:
Write the method for when the mouse clicks. Put this code in frame 2, actions layer after the enterframe method :
_root.onMouseDown = function() {
attachMovie("bullet", "bullet"+bulletNum, bulletNum);
eval("_root.bullet"+bulletNum)._x = _root.defender._x;
eval("_root.bullet"+bulletNum)._y = _root.defender._y;
++bulletNum;
if (bulletNum>5) {
bulletNum = 0;
}
};
That finishes frame 2. In our Defender layer we should have our Defender mc with the instance name of "defender".
In the text layer we should have a dyamic textfield with variable name "score" and another dynamic textfield with variable name "lives". If you want you can also have a couple of static textfields with "Score:" and "Lives :" written in them.
In our "actions" layer we should have the code that we outlined above. It should contain the following :
Simple. We have done all the hard yards and it is downhill from here.
Hit F6 to create 3 new keyframes for each layer. The text and defender layers we dont have to touch.
Copy the code from Frame 2 ,"actions" layer and paste it into the "actions" layer ,frame 3.
Change the speed (in line 5) from 10 to 15.
Replace "alien" with "bug" wherever it occurs on this frame. Use the "Replace" icon at the top of the Actions window. (Between the magnifying glass icon and the crosshairs). When you open the Replace Dialog box , write "alien" (with the quotation marks)into the "Find What:" Textbox and write "bug" into the "Replace with:" textbox. Click the "replace" button until all the occurences of "alien" are replaced by "bug". You will do this in the next frame as well.
In this frame you should have a line that reads :
initAliens("bug"); (on line 7)
and on lines 25 and 26
moveBombs("bug");
moveAliens("bug", 4,15);
And change the 3 to a 4 on the above line to take us to frame 4 , the next level.
That is all for Frame 3. Hit F6 to make keyframes for frame 4 on all layers.
Copy and paste the code from frame 3, "actions" layer to frame 4. As before , you will only have to make a few changes, similar to frame 3. Use the replace dialog box to replace "bug" with "skull".
Here are the changes outlined :
Add the following code to the bottom of frame 4 "actions" layer:
dropdown = false;
// if all aliens are dead
if (_root.deadcount == 0) {
// go to next level
_root.gotoAndStop(frame);
};
That is all for Frame 4. Hit F6 to make keyframes for frame 5 on all layers.
On frame 5, "defender" layer , delete the defender mc.
On the "actions" layer , you will need only a single line of code:
stop();
In the "text" layer, frame 5, you can delete the lives textfields and leave the score there. Write some sort of text stating that "You have won etc" .
Create a restart button and put this code in it to re-initialize the score and lives and to go to frame 2(Level 1):
on (release) {
_root.lives = 5;
_root.score = 0;
_root.gotoAndStop(2);
}
One more thing: