5: Scoring & Lives

This tutorial builds on Part 4 of the six-part tutorial series on building a Space Shooter and you will use some of the same techniques as used there.

We will be adding a score system (every kill increments score by 1) and lives (every collision between player and enemy removes 1 life).

A game over screen will now be available and will present the final score.

Prerequisites: Please complete Tutorial 4 first.

Tools & Techniques: displaying results in textboxes, changing the visibility of symbols on stage, converting integer to string.

We’re going to create two new symbols. The first is called ‘UserInterface’.

Create 4 text boxes as shown below with similar text content ("Score:", "0123456789", "Lives:", "0123456789" respectively).

Note: we insert the numbers '0-9' as placeholders and because Adobe Animate sometimes reverts fonts of numbers to defaults if we do not place them ourselves first.

The two text boxes on the left are labels and so static text can be selected (default settings).

Versions Note: Flash Professional CS5.5 and earlier use 'TFL Text' as opposed to 'Dynamic Text' which was introduced in CS6.

Select the two text boxes on the right and use the drop-down box to change from 'Static Text' to  'Dynamic Text'. This allows an instance name to be set. The top text box should be named 'Score_txt' as shown below in the properties pane.

The lower text box should be named 'Lives_txt'.

You will later be outputting to both 'Score_txt' and 'Lives_txt'.

Create a new layer in the main timeline labelled 'user interface'.

Drag an instance of the 'UserInterface' symbol from the library as shown below into this new layer:

Give the instance of UserInterface an identifier, I have called it 'ScoreBoard_mc':

Part 2 of this tutorial is to create our game over screen, so create a new symbol called 'EndGame'.

This display will need to be the same dimensions (size) as the stage. Draw a box (I chose a blue gradient) that will fit the size of the stage (e.g. in mine it is set to the '0,0' origin with dimensions 800 x 450 px).

Insert 3 text boxes as shown below (properties to follow).

You may like to add some design work on a layer of its own. The assets you have already created may be reused here:

The text boxes have a number of properties as shown below, but in summary:

  1. Game Over - 'Static Text' centre-aligned
  2. Score label - 'Static Text' right-aligned
  3. Final Score - 'Dynamic Text' left-aligned

 

You can then drag this symbol onto the stage in its own 'game over' layer (above spaceship and background layers, located at ‘x = 0’ and ‘y = 0’). You should also give it an instance name, 'gameover_mc'.

We will create the global variables for the lives and score and set the display elements to equal these variables (converted to string/text data types).

Place these with the other global declarations, perhaps after the following lines:

 

var speed: int;
var bulletSpeed: int = 15;
var bullets_arr: Array = [];
var cooldown: int = 0;
var enemies_arr: Array = [];

var score: int = 0;
var lives: int = 3;

We need to set/reset these variables in our 'initialise' subroutine, presenting the values in textboxes to the user, and hiding 'gameover_mc' symbol instance:

The 'gameover_mc' symbol obscures our player and background when we start the game, so the next section of code hides it.

Where you place this snippet shouldn't matter, but its logical to place it after the variable settings, but before the call to initialise():

 

speed = 8;
bulletSpeed = 15;
bullets_arr = [];
cooldown = 0;
enemies_arr = [];

//reset score/lives
score = 0;
lives = 3;

//display new score/lives on screen
Scoreboard_mc.Score_txt.text = String(score);
Scoreboard_mc.Lives_txt.text = String(lives);

//make the EndGame symbol invisible
gameover_mc.visible = false;

The score will be also need to be incremented each time an enemy is killed and this score should be updated on screen.

In the 'bulletHitEnemy' subroutine, within the if statement and after the following lines:

 

//remove the bullet and enemy from the stage
stage.removeChild(bullets_arr[b]);
stage.removeChild(enemies_arr[e]);

//remove the bullet and enemy from their arrays
bullets_arr.removeAt(b);
enemies_arr.removeAt(e);

 

and before the 'break;' line, insert the following:

score += 1;
Scoreboard_mc.Score_txt.text = String(score);

The lives will need to be decremented (subtract 1) when the player hits the enemy and updated on screen much as with the score.

This section is more complicated, because we also need to ask if lives equals zero (lives == 0), and if it is then we need to run our end game code.

In the 'enemyHitPlayer' subroutine, within the if statement and after the following lines:

 

//remove the enemy from the stage
stage.removeChild(enemies_arr[e]);

//remove the enemy from the array
enemies_arr.removeAt(e);

 

insert the following code block (notes below):

lives -= 1;
Scoreboard_mc.Lives_txt.text = String(lives);

if (lives <= 0) 
{
    //remove event listeners to cease all actions on stage
    stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
    stage.removeEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
    stage.removeEventListener(Event.ENTER_FRAME, playerMovement);

    //remove bullets (as these will appear...
    //...in front of our EndGame symbol)
    for (var i: int = 0; i <= bullets_arr.length - 1; i++) 
    {
        stage.removeChild(bullets_arr[i]);
    }

    //remove enemies (as these will appear...
    //...in front of our EndGame symbol)
    for (var j: int = 0; j <= enemies_arr.length - 1; j++) 
    {
        stage.removeChild(enemies_arr[j]);
    }

    //set final score
    gameover_mc.FinalScore_txt.text = String(score);

    //show EndGame symbol
    gameover_mc.visible = true;
}

The code above does the following:

  • removes the event listeners that spawns and controls enemies, and allows the player to be moved
  • loops through all bullets and removes them from the stage
  • loops through all enemies and removes them from the stage
  • updates the final score textbox with the latest score
  • makes the game over screen visible