Tutorial: Shooter game using ActionScript 3.0
This is a tutorial describing a basic shooting game using ActionScript 3.0 with classes defined for the each of the component parts: bombs and antiaircraft (aa) as well as the gun, the ground and a health bar. The game opens with the following screen:
After clicking on the start button, a new screen appears along with what is termed a health bar. This bar will grow or shrink depending on bombs hitting the ground or being hit by antiaircraft shot by the gun. NOTE: an early version of the game required the player to click on the gun to make it have "the focus" and receive events such as the arrow key strokes. The version I describe here sets up the proper focus by program control. However, I would call what I have done a 'hack' to get it working exactly as I wanted. Notice that bombs are already falling.
Clicking the space bar stops the game (but bombs in motion continue to fall) and produces a text field with a summary. Notice below that there is debris from bombs and that the health bar is smaller than it started.
The player ends the game by pressing the space bar. Bombs in motion continue to fall. A text field appears reporting a score.
This is intended to be a basis for a game. A relatavely minor enhancement is to develop a scoring scheme. As you can see from the last screen shot, all I do is report the number of times a bomb lands on the ground and the total shots. I also note if the health bar has gone to zero. I keep the game going even if the health bar is zero. You can make a more elaborate system for your game. Other enhancements could be to add objects on the ground and to differentiate if bombs hit these objects. Notice that in my game, no checks are made for a bomb hitting the gun. You also can add guns!
Overview
Before getting to the implementation, here is an overview of this application in terms of events and [general] behavior: what happens when?
The events are:
- Clicking on the start button: this makes a new screen appear, starts bombs falling, and enables the program to receive key strokes
- Clicking on the right and left arrow keys move the gun
- Clicking on the up arrow key causes firing of the gun
- New bombs appear on some sort of timed action
- Each bomb is animated, falls downward, by a timing event
- Each aa in animated, goes upwards, by a timing event
- Clicking the space bar ends the game
Moving on, the next thing I thought about was: who does what. In many cases, this relates to the event handling of the events just listed. These very general ideas help me in the implementation. I will give detailed code later.
The event handler for the button sets off the chain of events for starting the game. This includes setting up timed events for dropping bombs.
An event handler—not clear where it is located—makes a probabilistic determination at regular time intervals on starting off a new bomb. The creation of a new bomb also sets up the event handling for a timed event.
The timer event handler associated with a bomb move the bomb down the screen and check if the ground has been reached.
The event handler for key strokes after detecting an left or right arrow, moves the gun. This same event handler after detecting the up arrow starts off an aa. The creation of a new aa sets up the event handling for a timed event. This event handler after detecting the pressing of the space bar initiates the ending of the game.
The timer event handler associated with an aa moves the aa up the screen AND checks if it collides (hits) any of the bombs. This means that somewhere there must be a list, that is, an array, of all the bombs.
With these general considerations in mind, I will now describe the implementation of the shooter using Flash and ActionScript 3.0. Thecritical feature of this application is the interaction between using the [traditional] Flash authoring system: creating symbols in the Library, placing them on the Stage in frames and writing frame code AND defining classes (also done 'in Flash' by opening a new ActionScript file) by writing ActionScript code in .as files. The symbols in the Library are each connected to the appropriate class using the Linkage panel in Flash CS3 and the Properties/Advanced panel in Flash CD4. The single instance of the bar and the multiple instances of the bombs and the aa's appear on the Stage as a result of coding. To put it another way, you do not move instances of the bar or the bomb or the aa to the Stage and give them instance names in the usual way. Instead, this is done all by code.
The application consists of the shooter1.fla file and 5 .as files: Gun.as, Aa.as, Bomb.as, Bar.as and Ground.as. The .fla file can be anywhere on the drive. The 5.as files are contained in a folder named shooter, which was contained in a folder called as3 at the top of the drive. Each of the .as files contain opening and closing coding for the shooter package. An outline for each is:
package shooter {
import statements
class definition
}
To reinforce a point that was difficult for me to grasp: each of the class definitions is part of the shooter package.
The shooter1.fla file consists of 2 frames and 2 layers. The screen shot below shows the shooter1 .fla file, the first frame:
There are 4 objects placed on the stage: gun, ground, a button named startbtn made using a button in the Common Library, and a dynamic text field named instructions. Note that I edited the oval rust button to change the text to start. I also changed the font.
The second frame is similar to the first.. The text in the textfield has changed and the button is no longer there. The health bar is NOT on the Stage. It will be created by the program.
Concepts
The code in the .fla file and in all the .as files will be shown with explanation later. Here I will go over the critical concepts.
The use of classes and objects is best explained with concrete examples and the shooter application is a very good one. Briefly, an object puts together data and code. A class defines the data (variables) and the code (methods) for the objects of that class. New objects of a given class are created using what is termed the constructor function that is given as part of the class definition.For a new bomb, there would be a statement with
new Bomb();
A class method is for the whole class. Recall the Math.random and Math.floor methods and the Math.PI constant. For class definitions that you or I make, we indicate a class method or a class variable by the modifier static. A static variable can be changed. The static term means there is just one variable. Other modifiers specify what code can access the variable or method. A public method or variable is accessible by any code. Some object oriented computer scientists may dislike this characterization, but publicstatic methods serve somewhat as global functions. Methods that are not static are for each object created in that class. The internal designation indicates that a variable or method is only used by code in the package. A private designation indicates that a variable or method is accessible only by code in the class. The default is internal. I have tried to go over and change this to private when appropriate. Similarly, I changed some public designations to internal to variables or methods used outside code in that particular class but in one of the other classes. Note that constructor methods must be public. Consider also that making designations overly broad does not produce any errors. What it does do is cause less checking to be done during the translation (aka compiling) process. If you were working on a big project involving many people, this would be a disadvantage.
For the shooter application, I decided to write class definitions for the things that would appear on the screen: this is the single gun, the single ground and the single bar, and multiple bombs and aa's.
The code in this and other applications makes use of the built-in features of Flash. The good news is that there is considerable functionality to build on. The bad news is that you need to figure out what things are called and where they are found and insert the appropriate import statements. You should think of the .as files I/you write as extending the language. These also need to be imported into your program so the frame action code contains an import statement citing the package I wrote.
Each of the symbols: bar, gun, bomb, ground, aa have Linkage settings to point to the corresponding Class definition. For example, right click on the bomb symbol in the Library and then click on Linkage…in CS3 or Properties and then Advanced in CS4. You need to click on Export for ActionScript and Export in first frame. The Base class will be pre-set to flash.display.MovieClip. You will need to put in shooter.Bomb as the source file for the Class. This indicates the Bomb.as file in the shooter package (folder).
CS3 screen shot (after clicking on Linkage, then clicking Export for ActionScript and typing in shooter.Bomb)
CS4 screen shot (after clicking on Properties and then Advanced, clicking on Export for ActionScript and typing in shooter.Bomb):
Each of these class definitions are defined as extensions of the MovieClip class. This takes two operations (that can be done in any order).
- Insert/New symbol and create a symbol in the usual way. Use the Linkage panel to connect the symbol to a class.
- Create a class (that is, write the class definition). The header statement defining a class contains the phraseextendsMovieClip This sets up the new class to inherit the variables and methods of the MovieClip class. Inheritance is one way to connect symbols to class objects.
[Note that this was not what was done in the jigsaw puzzle. In that program, a movie clip instance was placed on the Stage and named in the usual manner. This instance name was passed as a parameter to the Piece function. This is the constructor function for the Piece class. Each Piece object had a variable that held a reference to an instance already on the Stage.]
The class definition can specify variables and methods. These are in addition to the variables and methods for movie clips. The class definition can specify a constructor function. This is invoked implicitly for any instances of the symbol on the stage, for example, the gun or the ground. Each Piece object HAS-A jigsaw piece instance.
In general, think of inheritance as a way to re-use code. The subclass is an extension of the original class, called the superclass. In the situation here, I am building on MovieClip to form bomb, aa, etc. Some of the variables and methods will be used just the way there are in the original class (aka the superclass) but there probably will be new things! For example, any bomb object has a .x and a .y which will be used in the code. The .x and .y are variables in the MovieClip class.
[You can read about another use of inheritance in the Bouncing Things game. Balls (circles), rectangles and stars are created and bouncing around in a box. Inheritance is used to make some of the coding be shared.]
The gun responds to the left, right and up arrow by a call to addEventListener for the KeyboardEvent.KEY_DOWN event. The event handler will move the gun right or left for the right and left arrows. For the up arrow, the code creates a new aa. See comment below on the creation of bombs.
The clicking of the button is connected to a function in the usual way using addEventListener. One special thing that needs to be done is to call a class method called startup of the Bomb class. The call to startup includes sending the names of the ground and gun instances. This is necessary for the coding in the .as files to reference these instances. The startup method also sets the focus and does some manipulation (I call it a hack) to make sure the gun does not have a yellow box around it. The documentation indicates a way to avoid this but it did not work (see below).
Bombs are dropped based on a calculation involving Math.random. In terms of the implementation, dropping a bomb involves creating a new bomb object. When the player clicks on the up arrow, what I call an aa (for antiaircraft) is shot from the gun. The implementation for an aa is similar to that for the bomb: the program creates a new object. In both cases, for the new object to appear (to be displayed), it must be added to the display list. This is done by using the addChild method on something that already is being displayed.
Bombs move down and aa's move up using a Timer in the same way as a ball moved in bouncing ball and the cannonball moved in cannonball. In addition, the TIMER_COMPLETE event is used to remove the aa objects after they have gone up past the start of the Stage.
Bombs in motion are stopped on frame 1. When a bomb hits the ground, a gotoAndPlay command is issued to go to frame 2. Think of the target disintegrating in cannonball or the frame animation in rock paper scissors.
Implementation and Coding
Open up Flash and click on File/New to start a new Flash file. Rename the first layer board and add a new layer and name it actions. The board layer will hold the material and the actions layer will hold the [frame] code. Remember: most of the code of this application is in the .as files, not in the .fla file.
Create the symbols: gun, ground, aa, bomb, and bar. All except the bomb are 1 frame movies. The bomb has multiple frames, some of which can be keyframes and some regular frames. The frames from 2 on show an exploding bomb.
The first frame and the final frame each have a stop(); in the actions layer and the board layer as shown:
As described earlier, bring instances of the gun and the ground to the board layer and name themground and gun1. There was no special reason to give the gun the name of gun1, except to suggest a possible extension with multiple gun instances. I also used a button in the Window/Common Library and changed the text to Start. I gave the button the name startbtn.
Write the code for frame 1. I move on to describe the code in the main movie time line and then go on to the .as files. The code in frame1 is
import shooter.*; / Import the package that I create. The package (shooter folder) consists of 5 class definitions (5 .as files).startbtn.addEventListener
(MouseEvent.CLICK,startgame); / Set up the clicking on the button as an event with handler the function startgame.
function startgame(ev) { / Start function definition. Note that you need to specify a parameter even though the code doesn't use it.
Bomb.startup(ground, gun1); / Call a class function of the Bomb class. Think of this as 'telling' the Bomb class how to reference the ground and the gun AND also kicking off the dropping of the bombs.
gotoAndPlay(2); / Go the second frame
} / Close function definition
stop(); / Stop at this frame.
Create a second frame by Insert/Timeline/Keyframe. The code in actions layer, frame 2 is simply:
stop();
Change the text in the text field to be "Click on space bar to stop".
You need to specify where to find the .as files. Putting this a more correct way, you need to specify where to find the shooter package that contains the class definitions. In this example, I created a package called shooter. I created a folder called shooter in a folder called as3 on my C drive. The shooterfolder will contain files for each of the class definitions.
Click on File/Publish Settings and click on Flash
Click on Settings to the right of ActionScript 3.0. Click on the + sign and then the bull's eye to browse to the folder containing the package folder. In my case, this is C:\as3
A class definition is a specification of objects. It starts off with any import statements required and then includes specification of variables and methods. One method, the one with the name the same as the name of the class, is the constructor method. It is invoked to create a new object. As indicated earlier, each variable and each method can have the designation of static, meaning that it is NOT associated with a particular instance. Rather than continuing with general description, I describe how the features are used here.