Tutorials

Game Development extension: add laser shooting to Flappy Bird

This tutorial is a great continuous learning activity for students who have completed our game development workshop, or the Cambridge Coding Summer School.

If you do not have a currently functioning flappy bird game – no worries! You can find a version on Github to get started: https://github.com/u-coding/CambridgeCoding-Flappy-bird-extension-tutorial-Starting-code

This tutorial will be comprised of two parts. Part 1 will cover how to add an element of functionality to your flappy bird game: the ability to shoot at incoming pipes. In Part 2, will cover how to implement the bullets functionality to act as one of the game’s bonuses.

asteroid-test

Asteriod Rush – created by Chris and Anton at our 2015 Coding Summer School

Part 1

Step 1

Let us start by loading the bullet image in the preload function. Take any image of a bullet off the internet to use for this tutorial and save it in the assets folder of your project.  

game.load.image("bullet", "assets/bullet.png");

Writing code which adds firing functionality to the flappy bird game is relatively straightforward. We will use an array to store the bullets (this is the trick we previously used to create pipes in your game scene).

Let’s start by initialising a new array. As it is a global variable, make sure it is initialised at the top of the file, outside any functions.

//Initially empty array to store the bullets
var bullets = [];

Now create a new function called fire. This is where we will put our firing code (make sure it is outside other functions in your code).

function fire() {
    // leave empty for now, we’ll complete it later
}

This function will be called whenever the user wants to fire a bullet. Let’s set up an event handler for pressing the right arrow key (feel free to use a different input for the event handler). Add the following code in the create function.

// call the fire function when the right arrow key is pressed
game.input.keyboard.addKey(Phaser.Keyboard.RIGHT).onDown.add(fire);

Even though the fire function is called when the right arrow is pressed, nothing happens. We need to write some code inside the fire function so that bullets are created and used in the game. We will give it similar properties to our pipes: enabling physics, determining speed, and adding it to a global array.

Add the following code to the fire function.

// The initial position of the bullet is the current position of the player
var bullet = game.add.sprite(player.x, player.y, "bullet");
game.physics.arcade.enable(bullet);
bullet.body.velocity.x = 400;
// Add the new bullet to the bullets array, (this is helpful for later)
bullets.push(bullet);

If you play your game now, you will press the right arrow key and bullets will fly!

Step 2

Now let’s make bullets destroy pipes – otherwise, bullets that fly across the screen are not very useful…

When building the initial game, we added code to ‘kill the player’ when it hit a pipe. This code will be similar to the code for bullets to destroy pipes.

Remember that the update function is called on every frame of the game. It’s the place to check for collisions between bullets and pipes. Inside the update function, add the following code.

// For each pipe test the overlap with bullets and destroy any match
for (var i = 0; i < pipes.length; i++)
{
    game.physics.arcade.overlap(pipes[i], bullets, function() {
    pipes[i].destroy();
    });
}

Now try your game, the pipes will now be destroyed when bullets hit them!

All of the code is on Github: https://github.com/u-coding/CambridgeCoding-Flappy-bird-extension-tutorial-Part-1

 Great work! You have completed the first part of the tutorial.

Part 2

Step 3

(If you completed our summer school, this section will go by quickly. You will have to adapt your code only slightly.)

With an unlimited amount of bullets, the game is too easy! Let’s make bullets a scarce resource that the player finds occasionally in the game.

Let us begin by loading an image into the preload function. This image will be used as a sprite the user can collect. You can either use the same image (../assets/bullet.png) or a different one. Add the code into the preload function.

game.load.image("bonus", "../assets/bonus.png");

We will create another empty array, at the top of the code. This is useful for testing collisions (as we did above for the bullets and the pipes).

// Initialise the bonus variable to an empty array
var bonuses = [ ];

Now let us create a function to make bonuses. This code will be similar to making pipes.

function generateBonus() {
    // This will be filled later
}

Reread your generatePipe function and try to make something similar for bonuses in the generateBonus function: create the sprite, enable the physics, set the speed, store in the global array. If you’re stuck, look at the solution below.

var bonus = game.add.sprite(900, 200, "bonus");
game.physics.arcade.enable(bonus);
bonus.body.velocity.x = -200;
bonuses.push(bonus);

In the game, we now need to generate a pipe every second, or a bonus. So we will need to edit our previous code. Edit the line of code that calls the generatePipe function every second. Instead of calling generatePipe, make it call a function generate that we’ll write next. The new line of code should look like:

game.time.events.loop(Phaser.Timer.SECOND, generate);

Now declare the generate function (we will explain why in a minute).

function generate() {
 // We will fill that in a minute
}

In order to generate either a pipe or a bonus every second, we are using a separate function (called generate) to decide at random which object to generate.

Now add the following code within the generate function.

// Generate a random integer within 1-5 inclusive.
var randomNumber = game.rnd.integerInRange(1, 5)
// depending on the random number, call either generatePipe or generateBonus
if (randomNumber === 1) {
    generateBonus();
} else {
    generatePipes();
}

This means that bonuses and pipes will be generated! (How can you change the likelihood of a bonus appearing? Answer: change the second argument of the integerInRange function.)
Bonuses appear during the game. However, it is impossible to interact with them yet. Now let’s add some code to link shooting functionality to the bonus generation.

Step 4

In order to combine bonuses with firing functionality, we will use if statements and variables holding boolean values (boolean values are either true or false). Start by creating a global variable (so place it at the top of your code, outside of any functions), this will dictate whether or not the user can use the firing functionality.

// Initialise the activeGun variable with the boolean value false.
var activeGun = false;

Also add the following code in the update function, this will allow the interaction between the bonus and the player to change the boolean value we created above.

//Sets the variable to true when the player and the bonus collide.
game.physics.arcade.overlap(player, bonus, function(){
activeGun = true;
});

Now, in order to have the boolean affect the way our fire function works, wrap the code in an if statement, and use the boolean we made as its condition.

// If this variable is true, the code of the fire function will be called.
function fire() {
    if (activeGun) {
        // original code from your fire function goes here.
    }
}

If you run the code, you will now see that the player will only be able to fire after it has touched a bonus. You should also notice that the bullets have no limit once the player has hit the bonus. In the final step we will add a limit to the number of bullets available per bonus collision.

Step 5

Start by creating a global variable to hold the number of bullets fired.

// Initialise bulletCounter with the value 0
var bulletCounter = 0;

In order to order for the counter to hold the correct number of bullets fired,  add the following code to the fire function. Every time the fire function is called, the value will increase by one.

// Increases the value of bulletCounter by one.
bulletCounter++;

Finally, regulate the number of bullets available, by adding another if statement in the fire function.

if (bulletCounter === 5) {
    bulletCounter = 0;
    activeGun = false;
}

Now if you test the code, you will have five bullets to use. Whenever the player gets the bonus.

Congratulations! You have completed the tutorial.  what you have learned and make other cool games.

Want to learn more about Game Development? Check out the Cambridge Coding Summer School: http://cambridgecoding.com/summer-school


ABOUT THE AUTHOR

Ben-Dixon

BEN DIXON

Ben is a Software Developer and Sixth Form student at St George’s College in Weybridge. His areas of specialty include Virtual Reality software and web development.

Leave a comment