I make games and write tutorials on lessmilk.com

This is the blog where I write about my projects

How to make a Flappy Bird in HTML5 - Part 1

Flappy Bird is a nice little game with easy to understand mechanics, and I thought it would be a perfect fit for an HTML5 game tutorial. So we are going to make a simplified version of Flappy Bird, in only 65 lines of Javascript with the Phaser framework.

Click here to test the game we are going to build.

Note: this tutorial was originally for Phaser 1.1, but was recently updated for Phaser 2.0.

Set Up

You should download this empty template that I made for this tutorial. In it you will find:

  • phaser.min.js, the Phaser framework v2.0.5
  • index.html, where the game will be displayed
  • main.js, a file where we will write all our code
  • assets/, a directory with 2 images (bird.png and pipe.png)

You should also download the code editor Brackets, that will make our life easier to set up a webserver.

Empty Project

In the index.html file we add this simple code:

<!DOCTYPE html>  
<html>

<head>  
    <meta charset="utf-8" />
    <title> Flappy Bird Clone </title>

    <script type="text/javascript" src="phaser.min.js"></script>
    <script type="text/javascript" src="main.js"></script>
</head>

<body>

    <p> Press the spacebar to jump </p>
    <div id="gameDiv"> </div>

</body>  
</html>  

It will load all the necessary Javascript files, and add a "gameDiv" element where our game will be displayed.

In the main.js file we should add this, which will create an empty Phaser project:

// Initialize Phaser, and create a 400x490px game
var game = new Phaser.Game(400, 490, Phaser.AUTO, 'gameDiv');

// Create our 'main' state that will contain the game
var mainState = {

    preload: function() { 
        // This function will be executed at the beginning     
        // That's where we load the game's assets  
    },

    create: function() { 
        // This function is called after the preload function     
        // Here we set up the game, display sprites, etc.  
    },

    update: function() {
        // This function is called 60 times per second    
        // It contains the game's logic   
    },
};

// Add and start the 'main' state to start the game
game.state.add('main', mainState);  
game.state.start('main');  

We are going to fill in the preload(), create() and update() functions, and add some new functions to make the game work.

The Bird

Let's first focus on adding a bird to the game that can be controlled with the spacebar key.

Everything is quite simple and well commented, so you should be able to understand easily the code below. For better readability, I removed the Phaser initialization and states management code that you can see above.

First we update the preload(), create() and update() functions.

preload: function() {  
    // Change the background color of the game
    game.stage.backgroundColor = '#71c5cf';

    // Load the bird sprite
    game.load.image('bird', 'assets/bird.png'); 
},

create: function() {  
    // Set the physics system
    game.physics.startSystem(Phaser.Physics.ARCADE);

    // Display the bird on the screen
    this.bird = this.game.add.sprite(100, 245, 'bird');

    // Add gravity to the bird to make it fall
    game.physics.arcade.enable(this.bird);
    this.bird.body.gravity.y = 1000;  

    // Call the 'jump' function when the spacekey is hit
    var spaceKey = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
    spaceKey.onDown.add(this.jump, this);     
},

update: function() {  
    // If the bird is out of the world (too high or too low), call the 'restartGame' function
    if (this.bird.inWorld == false)
        this.restartGame();
},

And just below this, we add these two new functions:

// Make the bird jump 
jump: function() {  
    // Add a vertical velocity to the bird
    this.bird.body.velocity.y = -350;
},

// Restart the game
restartGame: function() {  
    // Start the 'main' state, which restarts the game
    game.state.start('main');
},

Testing

Now it's time to test our game. Open the index.html file with the Brackets editor, then click on the small icon in the top right corner:

It will launch a live preview of the game, where you should have a bird jumping when you press the spacebar key.

If you don't want to use Brackets, then you'll have to use a local webserver to test the game.

The Pipes

A Flappy Bird game without pipes is not really interesting, so let's change that.

First, we load the pipe sprite in the preload() function.

game.load.image('pipe', 'assets/pipe.png');  

Since we are going to handle a lot of pipes in the game, it's easier to use a Phaser feature called 'group'. The group will contain 20 pipes that we will be able to use as we want. So we add this in the create() function.

this.pipes = game.add.group(); // Create a group  
this.pipes.enableBody = true;  // Add physics to the group  
this.pipes.createMultiple(20, 'pipe'); // Create 20 pipes  

Now we need a new function to add a pipe in the game. By default, all the pipes contained in the group are dead and not displayed. So we pick a dead pipe, display it, and make sure to automatically kill it when it's no longer visible. This way we never run out of pipes.

addOnePipe: function(x, y) {  
    // Get the first dead pipe of our group
    var pipe = this.pipes.getFirstDead();

    // Set the new position of the pipe
    pipe.reset(x, y);

    // Add velocity to the pipe to make it move left
    pipe.body.velocity.x = -200; 

    // Kill the pipe when it's no longer visible 
    pipe.checkWorldBounds = true;
    pipe.outOfBoundsKill = true;
},

The previous function displays one pipe, but we need to display 6 pipes in a row with a hole somewhere in the middle. So let's create a new function that does just that.

addRowOfPipes: function() {  
    // Pick where the hole will be
    var hole = Math.floor(Math.random() * 5) + 1;

    // Add the 6 pipes 
    for (var i = 0; i < 8; i++)
        if (i != hole && i != hole + 1) 
            this.addOnePipe(400, i * 60 + 10);   
},

To actually add pipes in the game, we need to call the addRowOfPipes() function every 1.5 seconds. We can do this by adding a timer in the create() function.

this.timer = game.time.events.loop(1500, this.addRowOfPipes, this);  

Now you can save your file and test the code. This is slowly starting to look like a real game.

Scoring and Collisions

The last thing we need to finish the game is adding a score and handling collisions. And this is quite easy to do.

We add this in the create() function to display a score label in the top left.

this.score = 0;  
this.labelScore = game.add.text(20, 20, "0", { font: "30px Arial", fill: "#ffffff" });  

And we put this in the addRowOfPipes(), to increase the score by 1 each time new pipes are created.

this.score += 1;  
this.labelScore.text = this.score;  

Next, we add this line in the update() function to call restartGame() each time the bird collides with a pipe.

game.physics.arcade.overlap(this.bird, this.pipes, this.restartGame, null, this);  

And we are done! Congratulation, you now have an HTML5 Flappy Bird clone. You can download the full source code here.

What's Next?

The game is working, but it's a little bit boring. In the next tutorial we'll see how we can make it better by adding sounds and animations. Read part 2.

For your information, I also wrote a book on how to make a full featured game with Phaser. More information on: DiscoverPhaser.com.


Want to get my free ebook "How To Plan, Create, and Promote Games", and be notified when one of my new games or blog posts is out? Then join more than 5,000 people on my newsletter.

Register to the newsletter:

No spam, and unsubscribe at any time.


comments powered by Disqus