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

codinglabsolution

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




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



Welcome to our exciting journey into the world of game development, where we'll be creating our own version of the classic game, Flappy Bird, using HTML, CSS, and JavaScript. This comprehensive tutorial will guide you through each step of the process, from setting up the game structure to adding interactive elements and animations.


Whether you're a beginner or an experienced developer, this tutorial is designed to help you understand the core concepts of game development while having fun building your own game. By the end of this guide, you'll have a fully functional Flappy Bird game that you can play and share with others.


So, let's dive in and start building our Flappy Bird masterpiece together! Get ready to unleash your creativity and bring this iconic game to life on your screen. Let's make some magic happen!

Source Code

Step 1 (HTML Code):


To begin, let's create a new HTML file to lay the foundation for our Flappy Bird game. Follow these steps:


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

2. `<html>`: 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.

4. `<title>Flappy Bird</title>`: Sets the title of the web page that appears in the browser's title bar or tab.

5. `<meta charset="utf-8">`: Specifies the character encoding for the document (UTF-8, which supports a wide range of characters).

6. `<meta name="viewport" content="width=device-width, initial-scale=1">`: Defines the viewport settings for responsive design on various devices.

7. `<link rel="stylesheet" href="styles.css">`: Links an external stylesheet (CSS file) named "styles.css" to style the webpage.

8. `<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.

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

10. `<canvas id="myCanvas" width="320" height="480"></canvas>`: 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 for the game.


Now, save the file with a .html extension (e.g., index.html) to view it in a web browser. This sets up the basic structure for our Flappy Bird game using HTML. We'll style it using CSS in the next step.

<html>
<head>
 <title>Flappy Bird</title>
   <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="styles.css">
 <link href='https://fonts.googleapis.com/css?family=Pacifico' rel='stylesheet'>
 </head>
 <body>
<canvas id="myCanvas" width=320 height=480
 style="background:url('http://s2js.com/img/etc/flappyback.png');  background-size: 100%; height: 95% " >
<script src="script.js"></script>
</body>
</html>

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