Flappy Bird with HTML5

I can think of no better way to learn the skills needed for modern web development than writing games using HTML5. Also Flappy Bird is fun. So for your enjoyment and edification, I give you
Flappy Bird Written with HTML5
Press space or click/tap on the game to make the bird fly.
Avoid poles and boundaries. Enjoy!
Score:0
Speed:2
HTML for HTML 5 Flappy Bird Game
This is the code responsible for the main structure of the game and where ids
and classes
are attributed so we can access specific elements with JavaScript.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<div id="game"> <p id="instructions">Press space or click/tap on the game to make the bird fly.<br> Avoid poles and boundaries. Enjoy!</p> <div id="game-area"> <div id="bird"></div> <div class="pole" id="pole-1"></div> <div class="pole" id="pole-2"></div> </div> <div id="game-info"> <p>Score:<span id="score">0</span></p> <button id="restart-btn">Restart</button> <p>Speed:<span id="speed">2</span></p> </div> </div><!-- game --> |
CSS for HTML5 Flappy Bird Game
CSS provides the styling for the game, controlling how each element is displayed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
#game{ font-family: "Comic Sans MS", cursive, sans-serif; text-align: center; } #instructions{ text-align: center; } #game-area { margin: auto; position: relative; width: 400px; height: 300px; border: 2px solid green; background-color: deepskyblue; overflow: hidden; } #bird { position: absolute; background: url('https://compucademy.net/wp-content/uploads/2020/11/robbybird.png'); height: 27px; width: 42px; background-size: contain; background-repeat: no-repeat; top: 20%; left: 15%; } .pole { position: absolute; height: 100px; width: 30px; background-color: green; right: 0px; } #pole-1 { top: 0; } #pole-2 { bottom: 0; } #game-info { margin: 5px; font-size: 18px; } #game-info p{ display: inline; padding: 20px; } #restart-btn { padding: 5px 10px; background-color: green; color: white; font-size: 18px; border: none; cursor: pointer; outline: none; } |
JavaScript for HTML5 Flappy Bird Game
JavaScript is where the magic happens. JavaScript (or JS) is a hugely important language in the modern age as it is the primary language used to handle user interaction and dynamic manipulation of elements within a browser. It is also a significant language for server-side coding as well, often in the form of node.js
.
The following JS code has been added to the bottom of the body
tag for this page and controls how the game works. I have provided some comments to help you to understand some of the important features.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
"use strict"; // Save DOM objects to variables const bird = document.querySelector( '#bird' ); const poles = document.querySelectorAll( '.pole' ); const pole1 = document.querySelector( '#pole-1' ); const pole2 = document.querySelector( '#pole-2' ); const scoreSpan = document.querySelector( '#score' ); const speedSpan = document.querySelector( '#speed' ); const gameArea = document.querySelector( '#game-area' ); const restartBtn = document.querySelector( '#restart-btn' ); const containerWidth = gameArea.clientWidth; const containerHeight = gameArea.clientHeight; // make some variables accesible to functions. let speed; let score; let flapping; let playing; let scoreUpdated; function restart() { // Remove event listener to avoid multiple restarts. restartBtn.removeEventListener( 'click', restart ); speed = 2; score = 0; scoreUpdated = false; flapping = false; playing = true; speedSpan.textContent = speed; scoreSpan.textContent = score; poles.forEach( ( pole ) => { pole.style.right = 0; } ); bird.style.top = 20 + "%"; gameLoop(); } function update() { // Move poles // check on SO if/why we need such a wordy method. let polesCurrentPos = parseFloat( window.getComputedStyle( poles[0] ).getPropertyValue( "right" ) ); // Update score if ( polesCurrentPos > containerWidth * 0.85 ) { // or whatever bird pos is. if ( !scoreUpdated ) { score += 1; scoreUpdated = true; } scoreSpan.textContent = score; } // Check whether the poles went putside of game area. if ( polesCurrentPos > containerWidth ) { // Generate new poles. let newHeight = parseInt( Math.random() * 100 ); // Change the poles' height pole1.style.height = 100 + newHeight + "px"; pole2.style.height = 100 - newHeight + "px"; // Move poles back to the right-hand side of game area. polesCurrentPos = 0; // This is based on the "right" property. // Update speed speed += 0.25; speedSpan.textContent = parseInt( speed ); scoreUpdated = false; } poles.forEach( ( pole ) => { pole.style.right = polesCurrentPos + speed + "px"; } ); // Move bird let birdTop = parseFloat( window.getComputedStyle( bird ).getPropertyValue( "top" ) ); if ( flapping ) { bird.style.top = birdTop + -2 + "px"; } else if ( birdTop < containerHeight - bird.clientHeight ) { bird.style.top = birdTop + 2 + "px"; } // Check for collisions if ( collision( bird, pole1 ) || collision( bird, pole2 ) || birdTop <= 0 || birdTop > containerHeight - bird.clientHeight ) { gameOver(); } } function gameOver() { window.console.log( "game over" ); playing = false; restartBtn.addEventListener( 'click', restart ); } function gameLoop() { update(); if ( playing ) { requestAnimationFrame( gameLoop ); } } function collision( gameDiv1, gameDiv2 ) { // Get the top left coords of the first div let left1 = gameDiv1.getBoundingClientRect().left; let top1 = gameDiv1.getBoundingClientRect().top; // Get the dimensions of the first div let height1 = gameDiv1.clientHeight; let width1 = gameDiv1.clientWidth; let bottom1 = top1 + height1; let right1 = left1 + width1; let left2 = gameDiv2.getBoundingClientRect().left; let top2 = gameDiv2.getBoundingClientRect().top; let height2 = gameDiv2.clientHeight; let width2 = gameDiv2.clientWidth; let bottom2 = top2 + height2; let right2 = left2 + width2; if ( bottom1 < top2 || top1 > bottom2 || right1 < left2 || left1 > right2 ) return false; return true; } // Start flapping with space bar document.addEventListener( "keydown", function ( e ) { var key = e.key; if ( key === " " && playing ) { flapping = true; } } ); // Stop flapping with space bar document.addEventListener( "keyup", function ( e ) { e.preventDefault(); // Stops weird behaviour where releasing space calls restart() var key = e.key; if ( key === " " && playing ) { flapping = false; } } ); // Start flapping with mousedown gameArea.addEventListener( "mousedown", function ( e ) { if ( playing ) { flapping = true; } } ); // stop flapping with mousedown gameArea.addEventListener( "mouseup", function ( e ) { if ( playing ) { flapping = false; } } ); restart(); |
This is now my 100th blog post since I started this blog back in 2019. I wanted to keep it fairly short and sweet. Hopefully you will enjoy the Flappy Bird game, and if you have any questions for me about how it works, feel free to ask in the comments.
Happy computing!