Step-by-Step Guide: Develop Flappy Bird Game Using HTML, CSS, and JavaScript (Source Code)

Faraz

By Faraz -

Create a Flappy Bird game from scratch using HTML, CSS, and JavaScript. Beginner-friendly guide with step-by-step instructions and interactive examples.


Develop Flappy Bird Game Using HTML, CSS, and JavaScript.jpg

Table of Contents

  1. Project Introduction
  2. HTML Code
  3. CSS Code
  4. JavaScript Code
  5. Preview
  6. Conclusion

Flappy Bird, the beloved classic side-scrolling game, has captivated players of all ages with its simple yet addictive gameplay. In this comprehensive tutorial, we're embarking on an exciting journey into the world of game development by creating our own version of Flappy Bird using the dynamic trio of web technologies: HTML, CSS, and JavaScript.

If you've ever wondered how your favorite games come to life on the screen, this tutorial is your gateway to unlocking the secrets behind interactive and engaging gaming experiences. By the end of this step-by-step guide, you'll have not only developed a fully functional Flappy Bird game but also gained valuable insights into the fundamental concepts that power many web-based games today.

As we delve into the process of crafting this iconic game, you'll discover how HTML provides the structural framework, CSS adds the visual flair, and JavaScript breathes life into every flutter of our pixelated bird. This tutorial is designed to be beginner-friendly, making it accessible to aspiring game developers with varying levels of programming experience.

Whether you're a coding enthusiast eager to expand your skill set or a curious gamer intrigued by the magic that happens behind the scenes, this tutorial is your passport to an exciting realm of creativity and innovation. So, buckle up, get ready to code, and let's embark on a thrilling adventure to create our very own Flappy Bird masterpiece!

Source Code

Step 1 (HTML Code):

To get started, we will first need to create a basic HTML file. In this file, we will include the main structure for our Flappy Bird game.

After creating the files just paste the following codes into your file. Make sure to save your HTML document with a .html extension, so that it can be properly viewed in a web browser.

Let's break down the code step by step:

1. <!DOCTYPE html>: This declares the document type and version of HTML being used.

2. <html>: This is the opening tag for the HTML document.

3. <head>: This section contains metadata about the web page and is not displayed on the actual page.

  • <title>Flappy Bird</title>: Sets the title of the web page that appears in the browser's title bar or tab.
  • <meta charset="utf-8">: Specifies the character encoding for the document (UTF-8, which supports a wide range of characters).
  • <meta name="viewport" content="width=device-width, initial-scale=1">: Defines the viewport settings for responsive design on various devices.
  • <link rel="stylesheet" href="styles.css">: Links an external stylesheet (CSS file) named "styles.css" to style the webpage.
  • <link href='https://fonts.googleapis.com/css?family=Pacifico' rel='stylesheet'>: Links to the Google Fonts API to load and apply the "Pacifico" font to the webpage.

4. <body>: This is the main content of the web page that is displayed to the user.

  • <canvas id="myCanvas" width=320 height=480 style="background:url('http://s2js.com/img/etc/flappyback.png'); background-size: 100%; height: 95% " >: This creates an HTML5 canvas element with an id of "myCanvas" and sets its width and height attributes to 320 and 480 pixels, respectively. The canvas is used to render graphics, in this case, for the game. The style attribute is used to apply CSS rules to the canvas, including setting its background to an image of a background for the game. The background image is loaded from a URL, and its size is set to cover the entire canvas area while maintaining a height of 95% of the viewport's height.

This is the basic structure of our Flappy Bird game using HTML, and now we can move on to styling it using CSS.

Step 2 (CSS Code):

Once the basic HTML structure of the game is in place, the next step is to add styling to the game using CSS.

Next, we will create our CSS file. In this file, we will use some basic CSS rules to style our game.

Here's a breakdown of what the code does:

1. body: This selector targets the entire body of the web page.

  • font-family: 'Pacifico';: This line sets the font family for the text content inside the body to a font named "Pacifico."
  • display: flex;: This line sets the display property of the body to "flex," which is a layout mode that allows for flexible arrangement of elements.
  • justify-content: center;: This line centers the flex items (elements) horizontally within the body. The items will be distributed in a way that leaves equal space on both sides.

2. canvas: This selector targets the <canvas> element(s) on the page.

  • border: 1x solid #0a3cda;: This line adds a border to the canvas element(s) with a width of 1x (which should likely be '1px' for one pixel) and a solid line style. The border color is set to a shade of blue (#0a3cda).
  • margin: 10px;: This line adds a margin of 10 pixels around the canvas element(s), creating spacing between the canvas and other elements.

This will give our Flappy Bird game an upgraded presentation. Create a CSS file with the name of styles.css and paste the given codes into your CSS file. Remember that you must create a file with the .css extension.

body {
  font-family: 'Pacifico';
  display: flex;
  justify-content: center;
}

canvas {
  border: 1x solid #0a3cda;
  margin: 10px;
} 

Step 3 (JavaScript Code):

Finally, we need to create a function in JavaScript. The code uses HTML5 Canvas to create a game where a bird sprite needs to navigate through a series of moving pipes. Here's an explanation of the main components and functions in the code.

1. Canvas Setup:

  • var ctx = myCanvas.getContext('2d');: Retrieves the 2D rendering context of the canvas element with the ID myCanvas. This context is used to draw graphics on the canvas.

2. Game Variables:

  • Various variables like FPS, jump_amount, max_fall_speed, acceleration, pipe_speed, and more are initialized to control the game's mechanics and behavior.

3. Sprite Class - MySprite:

  • This class defines a general sprite object with properties such as position (x, y), visibility, velocity (velocity_x, velocity_y), image (MyImg), rotation (angle), and flipping (flipV, flipH).
  • The prototype function Do_Frame_Things is responsible for rendering the sprite on the canvas, applying transformations like rotation and scaling.

4. Function - ImagesTouching(thing1, thing2):

  • Checks whether two sprites are touching each other by comparing their positions and dimensions.

5. Function - Got_Player_Input(MyEvent):

  • Handles player input events such as touch, mouse click, and key press.
  • Transitions between different game modes: 'prestart', 'running', and 'over'.

6. Event Listeners:

  • Sets up event listeners for touch, mouse click, and key press events to trigger the Got_Player_Input function.

7. Game Logic Functions:

  • make_bird_slow_and_fall(): Adjusts the bird's falling speed, checks for collision with the top and bottom boundaries, and handles the game-over condition.
  • add_pipe(x_pos, top_of_gap, gap_width): Adds a pair of pipes to the game with specified position and gap dimensions.
  • make_bird_tilt_appropriately(): Tilt the bird sprite upward when it's ascending and gradually bring it back to a level position when descending.
  • show_the_pipes(): Renders all the pipes on the canvas.
  • check_for_end_game(): Checks for collision between the bird and any of the pipes, triggering the game-over state.
  • display_intro_instructions(): Displays instructions for starting the game.
  • display_game_over(): Displays the game-over message along with the player's score.
  • display_bar_running_along_bottom(): Renders a moving bottom bar on the canvas.
  • reset_game(): Resets the game to its initial state, including bird position and pipe arrangement.

8. Loading Images:

  • The code loads various images for sprites, pipes, and bars using the Image class.

9. Main Loop - Do_a_Frame():

  • This function is the heart of the game loop. It handles different game modes, clears the canvas, updates and renders the bird sprite, updates pipe positions, handles tilting and falling of the bird, and checks for collision and game-over conditions.

10. Interval Setup:

  • setInterval(Do_a_Frame, 1000 / FPS);: Calls the Do_a_Frame function at a specified interval (controlled by the FPS variable) to create the animation loop for the game.

Create a JavaScript file with the name of script.js and paste the given codes into your JavaScript file and make sure it's linked properly to your HTML document, so that the scripts are executed on the page. Remember, youโ€™ve to create a file with .js extension.

var ctx = myCanvas.getContext('2d');
var FPS = 40;
var jump_amount = -10;
var max_fall_speed = +10;
var acceleration = 1;
var pipe_speed = -2;
var game_mode = 'prestart';
var time_game_last_running;
var bottom_bar_offset = 0;
var pipes = [];

function MySprite(img_url) {
  this.x = 0;
  this.y = 0;
  this.visible = true;
  this.velocity_x = 0;
  this.velocity_y = 0;
  this.MyImg = new Image();
  this.MyImg.src = img_url || '';
  this.angle = 0;
  this.flipV = false;
  this.flipH = false;
}
MySprite.prototype.Do_Frame_Things = function () {
  ctx.save();
  ctx.translate(this.x + this.MyImg.width / 2, this.y + this.MyImg.height / 2);
  ctx.rotate((this.angle * Math.PI) / 180);
  if (this.flipV) ctx.scale(1, -1);
  if (this.flipH) ctx.scale(-1, 1);
  if (this.visible)
    ctx.drawImage(this.MyImg, -this.MyImg.width / 2, -this.MyImg.height / 2);
  this.x = this.x + this.velocity_x;
  this.y = this.y + this.velocity_y;
  ctx.restore();
};
function ImagesTouching(thing1, thing2) {
  if (!thing1.visible || !thing2.visible) return false;
  if (
    thing1.x >= thing2.x + thing2.MyImg.width ||
    thing1.x + thing1.MyImg.width <= thing2.x
  )
    return false;
  if (
    thing1.y >= thing2.y + thing2.MyImg.height ||
    thing1.y + thing1.MyImg.height <= thing2.y
  )
    return false;
  return true;
}
function Got_Player_Input(MyEvent) {
  switch (game_mode) {
    case 'prestart': {
      game_mode = 'running';
      break;
    }
    case 'running': {
      bird.velocity_y = jump_amount;
      break;
    }
    case 'over':
      if (new Date() - time_game_last_running > 1000) {
        reset_game();
        game_mode = 'running';
        break;
      }
  }
  MyEvent.preventDefault();
}
addEventListener('touchstart', Got_Player_Input);
addEventListener('mousedown', Got_Player_Input);
addEventListener('keydown', Got_Player_Input);
function make_bird_slow_and_fall() {
  if (bird.velocity_y < max_fall_speed) {
    bird.velocity_y = bird.velocity_y + acceleration;
  }
  if (bird.y > myCanvas.height - bird.MyImg.height) {
    bird.velocity_y = 0;
    game_mode = 'over';
  }
  if (bird.y < 0 - bird.MyImg.height) {
    bird.velocity_y = 0;
    game_mode = 'over';
  }
}

function add_pipe(x_pos, top_of_gap, gap_width) {
  var top_pipe = new MySprite();
  top_pipe.MyImg = pipe_piece;
  top_pipe.x = x_pos;
  top_pipe.y = top_of_gap - pipe_piece.height;
  top_pipe.velocity_x = pipe_speed;
  pipes.push(top_pipe);
  var bottom_pipe = new MySprite();
  bottom_pipe.MyImg = pipe_piece;
  bottom_pipe.flipV = true;
  bottom_pipe.x = x_pos;
  bottom_pipe.y = top_of_gap + gap_width;
  bottom_pipe.velocity_x = pipe_speed;
  pipes.push(bottom_pipe);
}
function make_bird_tilt_appropriately() {
  if (bird.velocity_y < 0) {
    bird.angle = -15;
  } else if (bird.angle < 70) {
    bird.angle = bird.angle + 4;
  }
}
function show_the_pipes() {
  for (var i = 0; i < pipes.length; i++) {
    pipes[i].Do_Frame_Things();
  }
}
function check_for_end_game() {
  for (var i = 0; i < pipes.length; i++)
    if (ImagesTouching(bird, pipes[i])) game_mode = 'over';
}
function display_intro_instructions() {
  ctx.font = '25px Arial';
  ctx.fillStyle = 'red';
  ctx.textAlign = 'center';
  ctx.fillText(
    'Press, touch or click to start',
    myCanvas.width / 2,
    myCanvas.height / 4
  );
}
function display_game_over() {
  var score = 0;
  for (var i = 0; i < pipes.length; i++)
    if (pipes[i].x < bird.x) score = score + 0.5;
  ctx.font = '30px Arial';
  ctx.fillStyle = 'red';
  ctx.textAlign = 'center';
  ctx.fillText('Game Over', myCanvas.width / 2, 100);
  ctx.fillText('Score: ' + score, myCanvas.width / 2, 150);
  ctx.font = '20px Arial';
  ctx.fillText('Click, touch, or press to play again', myCanvas.width / 2, 300);
}
function display_bar_running_along_bottom() {
  if (bottom_bar_offset < -23) bottom_bar_offset = 0;
  ctx.drawImage(
    bottom_bar,
    bottom_bar_offset,
    myCanvas.height - bottom_bar.height
  );
}
function reset_game() {
  bird.y = myCanvas.height / 2;
  bird.angle = 0;
  pipes = []; // erase all the pipes from the array
  add_all_my_pipes(); // and load them back in their starting positions
}
function add_all_my_pipes() {
  add_pipe(500, 100, 140);
  add_pipe(800, 50, 140);
  add_pipe(1000, 250, 140);
  add_pipe(1200, 150, 120);
  add_pipe(1600, 100, 120);
  add_pipe(1800, 150, 120);
  add_pipe(2000, 200, 120);
  add_pipe(2200, 250, 120);
  add_pipe(2400, 30, 100);
  add_pipe(2700, 300, 100);
  add_pipe(3000, 100, 80);
  add_pipe(3300, 250, 80);
  add_pipe(3600, 50, 60);
  var finish_line = new MySprite('http://s2js.com/img/etc/flappyend.png');
  finish_line.x = 3900;
  finish_line.velocity_x = pipe_speed;
  pipes.push(finish_line);
}
var pipe_piece = new Image();
pipe_piece.onload = add_all_my_pipes;
pipe_piece.src = 'http://s2js.com/img/etc/flappypipe.png';
function Do_a_Frame() {
  ctx.clearRect(0, 0, myCanvas.width, myCanvas.height);
  bird.Do_Frame_Things();
  display_bar_running_along_bottom();
  switch (game_mode) {
    case 'prestart': {
      display_intro_instructions();
      break;
    }
    case 'running': {
      time_game_last_running = new Date();
      bottom_bar_offset = bottom_bar_offset + pipe_speed;
      show_the_pipes();
      make_bird_tilt_appropriately();
      make_bird_slow_and_fall();
      check_for_end_game();
      break;
    }
    case 'over': {
      make_bird_slow_and_fall();
      display_game_over();
      break;
    }
  }
}
var bottom_bar = new Image();
bottom_bar.src = 'http://s2js.com/img/etc/flappybottom.png';

var bird = new MySprite('http://s2js.com/img/etc/flappybird.png');
bird.x = myCanvas.width / 3;
bird.y = myCanvas.height / 2;

setInterval(Do_a_Frame, 1000 / FPS);

Final Output:

Develop Flappy Bird Game Using HTML, CSS, and JavaScript.gif

Conclusion:

Congratulations, you've soared through the exhilarating journey of creating your own Flappy Bird game using HTML, CSS, and JavaScript! ๐ŸŽ‰ You've taken a significant step into the world of web-based game development, and your accomplishment is something to be proud of.

Throughout this tutorial, you've learned the essential building blocks of game creation, from setting up the game canvas and styling it with CSS, to implementing intricate game mechanics using JavaScript. By mastering these foundational skills, you've gained a solid understanding of how to bring your imaginative ideas to life on the digital playground.

Remember, game development is a continuous learning journey. Embrace challenges, stay curious, and keep honing your skills. The game you've created is not just a final product but a stepping stone towards even greater accomplishments in the ever-evolving world of game design and development.

So, go ahead and spread your wings, unleash your creativity, and let your imagination take flight. Your game development adventure has just begun, and who knows, your next creation might just become the next gaming sensation! Happy coding and happy gaming! ๐Ÿ•น๏ธ๐Ÿš€

Thatโ€™s a wrap!

I hope you enjoyed this post. Now, with these examples, you can create your own amazing page.

Did you like it? Let me know in the comments below ๐Ÿ”ฅ and you can support me by buying me a coffee.

And donโ€™t forget to sign up to our email newsletter so you can get useful content like this sent right to your inbox!

Thanks!
Faraz ๐Ÿ˜Š

End of the article

Subscribe to my Newsletter

Get the latest posts delivered right to your inbox


Latest Post