1: Player-Controlled Side Shooter

This post is part of a series which will take you through the steps required to build your own Spaceship Shooter game in ActionScript 3. The instructions have been adapted from an ActionScript 2 tutorial passed on by a work colleague. Whilst the original source is unknown, thevirtualinstructor.com tutorial appears to be very similar and I suspect is the original source.

A quick note, the image above was created after following the Adobe Illustrator tutorial found at denisdesigns.com.

Variables: boolean, integers (whole numbers)

Tools & Techniques: selection statements (SWITCH-CASE, IF-THEN-ELSE), keyboard input

Start screens differ slightly in design across the different versions of Animate (Flash Pro) but you should be able to choose a new 'ActionScript 3.0' file (not to be confused by the 'ActionScript 3.0 Class' file).

 

I personally set my width and height to 800 x 450 pixels for a small 16:9 (typical widescreen) ratio. I also set to 30 fps (frames per second) as a nice round number. Don't get carried away thinking you're making the next call of duty with 60fps or more.

 

 

We need to create a New Symbol, a number of ways to do this and one of them is to locate the ‘Library’ tab, and click on the ‘New Symbol’ button as shown in the diagram below. Alternatively press Ctrl-F8.

 

 

Name your symbol and ensure Type is set to ‘Movie Clip’ as shown.

 

Take some time to draw your spaceship. I like to zoom to 400-800% and then fill the space.

Ensure the crosshair is located on the right-hand side of the ship and your spaceship should face to the right.

Note: you can’t move the crosshair, but you can move your objects in relation to it. This crosshair represents coordinate 0,0 in the symbol.

 

Return to the stage (click on ‘Scene 1’ located under the Flash filename), locate the ‘Ship’ symbol from the library, and drag it onto the stage.

 

 

Then switch to the ‘Properties’ tab and name the Instance to ‘player_mc’.

 

Objects & Classes - in Adobe Animate

My preferred distinction between objects and classes:

  • Object Instances (instances of symbols, an object)
  • Object Classes (symbols in the library).

Classes are the blueprint of an object. The symbol named ‘Ship’ is similar to an object class and we can have as many instances of this object from this class as we like.

Instances are the created object, based on the blueprint class. So ‘player_mc’ is one instance of the 'Ship' class and we could create more instances, each with their own name.

So a ‘Galaxy Class Starship’ may be an example of a class, the USS Enterprise is one instance of that class, the USS Challenger another instance of the same class. Another example, Ford-Fiesta and Ford Focus are classes, but my car is an instance of the Ford-Fiesta class. It has its own name to uniquely identify it, for arguments sake its registration plate could represent its name.

No two instances can have the same name. For easy identification any MovieClip symbol instance can have '_mc' at the end so we know its been instantiated onto the stage.

Now, let’s start coding!

Notice the timeline allows for multiple frames - you want to keep everything on the main timeline in ONE frame until otherwise stated. Each symbol has its own timeline - and this can become confusing to newcomers so be aware.

Good practice is to create a layer dedicated to your code, so go to your timeline and select the icon on the bottom left to create a new layer. Label your layers appropriately.

 

Right-click on the first frame on the ‘Actions’ layer, then select item on the menu named ‘Actions’.

 

A new window will open to enter your code.

ActionScript 3 is more complex than ActionScript 2, but it is also more powerful. AS3 is object-oriented in nature (though we some control coding directly in Adobe Animate instead of Flash Builder). The code below can be typed line-by-line in the order shown.

We start by declaring our global variables to recognise the status of the key presses. We will use the Boolean data type as it only allows true (key pressed) or false (key not pressed). An integer (whole number) variable will store the speed the spaceship will travel (pixels per frame).

We will also call a subroutine called 'initialise' (we'll create this procedure next) to assign all variables a default value and to add the Event Listeners (more on those to follow).

//Variables here are used across the application
//and can be referenced by the various functions
var up:Boolean;
var down:Boolean;
var left:Boolean;
var right:Boolean;

var speed:int;

initialise();

 

Next we create the subroutine 'initialise' as type 'void' (as it does not return a value). Everything inside the subroutine will be encased in parenthesise '{ ... }'.

The four Boolean variables to detect key presses will be defaulted to false. The integer for speed is set to 8, and this is the number of pixels it will move on every frame.

Maths Moment: 8px per frame, 30 frames per second (8 x 30) = 240px per second.

Event Listeners wait for set events, such as keyboard buttons being pressed down or being released and frames on the timeline being played. There is only one frame, but it will be played 30 times every second (or 24 if you use the default fps setting).

There are two parameters in the 'addEventListener' function. The first is the event that triggers the action (KEY_DOWN, KEY_UP, and ENTER_FRAME). The second is the subroutine that will be called if the listener is triggered, and these will be created by us too (keyDownHandler, keyUpHandler, playerMovement).

 

function initialise():void
{
    up = false;
    down = false;
    left = false;
    right = false;
 
    speed = 8;

    //Event listeners wait to be triggered before running functions
    stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
    stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
    stage.addEventListener(Event.ENTER_FRAME, playerMovement);
}

Create the function for pressing relevant keyboard keys. Pressing a key will set the appropriate variable to TRUE. A selection statement is used called SWITCH CASE, though a nested IF-THEN-ELSE statement would also work.

Note: functions that end with ‘:void’ are procedures and do not return a value.

function keyDownHandler (event:KeyboardEvent):void
{
    switch( event.keyCode )
    {
        case Keyboard.UP:
            up = true;
            break;
        case Keyboard.DOWN:
            down = true;
            break;
        case Keyboard.LEFT:
            left = true;
            break;
        case Keyboard.RIGHT:
            right = true;
            break;
    }
}

 

The next function will reset those variables previously set, returning them to FALSE. This function is called when the appropriate keyboard key is released, thus triggering the event listener.

 

function keyUpHandler(event:KeyboardEvent):void
{
    switch( event.keyCode )
    {
        case Keyboard.UP:
            up = false;
            break;
        case Keyboard.DOWN:
            down = false;
            break;
        case Keyboard.LEFT:
            left = false;
            break;
        case Keyboard.RIGHT:
            right = false;
            break;
    }
}

The final function is triggered 30 times every second (when the frame is entered). There are four separate IF-THEN selection statements that run code only when a direction-key is being pressed AND the opposite key is NOT pressed AND only when the symbol is within the stage boundaries.

Dependent upon which IF-THEN statement is triggered, the symbol’s x-y coordinates will be changed based on the ‘speed’ variable. The symbol may also be moved diagonally.

function playerMovement(event:Event):void
{
    // if(left is true and right is not true ... AND within stage
    if ( left && !right && player_mc.x > 0) 
    {
        player_mc.x -= speed;
    }

    //if(right is true and left is not true) ... AND within stage
    if( right && !left && player_mc.x < stage.stageWidth) 
    {
        player_mc.x += speed;
    }

    //if(up is true and down is not true) ... AND within stage
    if( up && !down && player_mc.y > 0) 
    {
        player_mc.y -= speed;
    }

    // if(down is true and up is not true) ... AND within stage
    if( down && !up && player_mc.y < stage.stageHeight) 
    {
        player_mc.y += speed;
    }
}

Selection Statements - Switch Case

Selection statements are used to make a decision based on an input. With the Switch-Case statement (Select-Case in VB.NET) we can run code based on the value in a variable.

    switch(expression)
    {
       
case n:
            statements;

            break;
        case n:
            statement
s;
            break;
        default:
            statement
s;
            break;
    }

Our switch statements looks the keyCode attribute of the event parameter (passed in when a key is pressed). The keyCode is an integer based on the ASCII code that represents the key. There are functions that provide us with the value of special keys, such as Keyboard.UP for the up arrow key. We can also use the ASCII character codes themselves, where A = 65, B = 66, C = 67, D = 68, etc. You can search for more ASCII codes too.

You may like to change the direction keys to ‘W, A, S, D’ rather than arrow keys (common in many games). If so you would have to change both ‘switch-case’ statements with the keyUpHandler looking like this (keyDownHandler will have true values instead):

switch( event.keyCode )
{
    case 87:
        up = false;
        break;
    case 83:
        down = false;
        break;
    case 65:
        left = false;
        break;
    case 68:
        right = false;
        break;
}

Selection Statements - IF...THEN...ELSE

If statements give more control where we want to compare a value using logical or comparison operators. The standard statement looks like this:

    if (condition)
    {
            then-statements;

    }
    else
    {
            else-statements;
    }

Equality and Comparison Operators

  ==    : EQUALITY, checks whether the value on the left is the same as the value on the right and returns true if they are the same. In maths (and some programming languages like VB.NET) a single equals sign is used, '='. However in a large number of common languages the single sign is used to assign a value in an assignment statement.

  !=    : INEQUALITY, exact opposite to equality check mentioned above. If values on either side are the same then returns false.

  >    : GREATER THAN, checks that the value left of the sign is greater than the value on the right and returns true if this is the case. If values are equal, or the value on the right is less than that on the left, false is returned.

  >=    : GREATER THAN OR EQUAL, checks that the value left of the sign is greater than or equal to the value on the right and returns true if this is the case.

  <    : LESS THAN, checks that the value left of the sign is less than the value on the right and returns true if this is the case. If values are equal, or the value on the right is greater than that on the left, false is returned.

  <=    : LESS THAN OR EQUAL, checks that the value left of the sign is less than or equal to the value on the right and returns true if this is the case.

Logical Operators

  &&    : Logical AND, if both expressions on each side of the operator are true, returns true.

  ||    : Logical OR, if either or both expressions on each side of the operator are true, returns true.

  !    : Logical NOT, inverts a Boolean value from true to false, or false to true.