Free Flappy Bird Game Source Code in HTML, CSS & JavaScript

Here is that you are looking for a fun HTML5 game project to practice JavaScript, this Flappy Bird-style game is a great choice.

The game is simple: control the bird, keep it in the air, and try to pass through the gaps between the pipes without hitting them.

This project is built using HTML, CSS, and JavaScript. It uses the HTML5 Canvas element for the game graphics, so you do not need any external library or framework.

Everything is included in one HTML file, making it easy to copy, run, and customize.

Flappy Bird Game Source Code

Flappy Bird is a simple arcade-style game based on timing and quick reactions.

The player controls a bird that continuously moves forward while gravity pulls it downward. The player needs to press a button or tap the screen to make the bird move upward.

At the same time, pipes appear from the right side of the screen. The player must guide the bird through the gaps between the pipes.

The game becomes challenging because the pipes continue moving and the player needs to react at the right time.

Features of This Flappy Bird Game

This free Flappy Bird-style game includes:

  • Simple arcade gameplay code
  • HTML5 Canvas
  • JavaScript game code
  • Gravity effect
  • Bird jump/flap movement
  • Moving pipes
  • Random pipe gaps
  • Score counter
  • Start and restart button
  • Keyboard controls
  • Mobile tap support
  • Responsive game area
  • No external libraries code
  • Only Single HTML file

You can copy the complete code below into a new HTML file and run it directly in your browser.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Flappy Bird Game</title>
    <style>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }
        body {
            font-family: Arial, sans-serif;
            background: linear-gradient(135deg, #0f172a, #1e3a8a);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 20px;
            color: white;
        }
        .game-container {
            width: 100%;
            max-width: 520px;
            text-align: center;
        }
        h1 {
            font-size: 38px;
            margin-bottom: 8px;
        }
        .description {
            color: #cbd5e1;
            margin-bottom: 15px;
        }
        .score {
            font-size: 25px;
            font-weight: bold;
            margin-bottom: 12px;
        }
        .game-box {
            width: 100%;
            background: #020617;
            border: 3px solid #334155;
            border-radius: 14px;
            padding: 8px;
        }
        canvas {
            display: block;
            width: 100%;
            height: auto;
            background: linear-gradient(
                #38bdf8,
                #bae6fd
            );
            border-radius: 8px;
            touch-action: manipulation;
        }
        .start-btn {
            margin-top: 18px;
            padding: 12px 28px;
            border: none;
            border-radius: 9px;
            background: #22c55e;
            color: white;
            font-size: 17px;
            font-weight: bold;
            cursor: pointer;
        }
        .start-btn:hover {
            background: #16a34a;
        }
        .controls {
            margin-top: 15px;
            color: #cbd5e1;
            line-height: 1.6;
        }
        @media (max-width: 500px) {
            h1 {
                font-size: 30px;
            }
            .score {
                font-size: 21px;
            }
        }
    </style>
</head>
<body>
<div class="game-container">
    <h1>Flappy Bird</h1>
    <p class="description">
        Tap or press Space to fly through the pipes.
    </p>
    <div class="score">
        Score: <span id="score">0</span>
    </div>
    <div class="game-box">
        <canvas
            id="gameCanvas"
            width="480"
            height="640">
        </canvas>
    </div>
    <button
        class="start-btn"
        id="startBtn">
        Start Game
    </button>
    <div class="controls">
        Press <strong>Space</strong> or
        <strong>tap the screen</strong> to flap.
    </div>
</div>
<script>
    const canvas =
        document.getElementById("gameCanvas");
    const ctx =
        canvas.getContext("2d");
    const scoreElement =
        document.getElementById("score");
    const startBtn =
        document.getElementById("startBtn");
    const bird = {
        x: 90,
        y: canvas.height / 2,
        width: 30,
        height: 24,
        velocity: 0
    };
    const gravity = 0.42;
    const flapStrength = -7;
    const pipeWidth = 65;
    const pipeGap = 155;
    const pipeSpeed = 2.7;
    let pipes = [];
    let score = 0;
    let gameRunning = false;
    let gameOver = false;
    let animationFrame;
    function resetGame() {
        bird.y =
            canvas.height / 2;
        bird.velocity = 0;
        pipes = [];
        score = 0;
        gameOver = false;
        scoreElement.textContent = score;
        addPipe();
    }
    function addPipe() {
        const minimumTop = 70;
        const maximumTop =
            canvas.height - pipeGap - 100;
        const topHeight =
            Math.floor(
                Math.random() *
                (maximumTop - minimumTop)
            ) + minimumTop;
        pipes.push({
            x: canvas.width,
            top: topHeight,
            bottom:
                topHeight + pipeGap,
            counted: false
        });
    }
    function flap() {
        if (!gameRunning) {
            startGame();
            return;
        }
        if (!gameOver) {
            bird.velocity =
                flapStrength;
        }
    }
    function startGame() {
        cancelAnimationFrame(animationFrame);
        resetGame();
        gameRunning = true;
        startBtn.textContent =
            "Restart Game";
        gameLoop();
    }
    function endGame() {
        gameRunning = false;
        gameOver = true;
        startBtn.textContent =
            "Start Again";
        draw();
    }
    function update() {
        if (!gameRunning) {
            return;
        }
        // Bird movement
        bird.velocity += gravity;
        bird.y += bird.velocity;
        // Add new pipes
        if (
            pipes.length === 0 ||
            pipes[pipes.length - 1].x
                < canvas.width - 220
        ) {
            addPipe();
        }
        // Move pipes
        pipes.forEach(pipe => {
            pipe.x -= pipeSpeed;
        });
        // Remove old pipes
        pipes =
            pipes.filter(
                pipe =>
                    pipe.x + pipeWidth > 0
            );
        // Score
        pipes.forEach(pipe => {
            if (
                !pipe.counted &&
                pipe.x + pipeWidth < bird.x
            ) {
                score++;
                pipe.counted = true;
                scoreElement.textContent =
                    score;
            }
        });
        // Collision with top/bottom
        if (
            bird.y < 0 ||
            bird.y + bird.height >
                canvas.height
        ) {
            endGame();
            return;
        }
        // Pipe collision
        for (const pipe of pipes) {
            const birdRight =
                bird.x + bird.width;
            const birdBottom =
                bird.y + bird.height;
            const horizontalCollision =
                birdRight > pipe.x &&
                bird.x < pipe.x + pipeWidth;
            const verticalCollision =
                bird.y < pipe.top ||
                birdBottom > pipe.bottom;
            if (
                horizontalCollision &&
                verticalCollision
            ) {
                endGame();
                return;
            }
        }
    }
    function drawBackground() {
        // Sky
        const gradient =
            ctx.createLinearGradient(
                0,
                0,
                0,
                canvas.height
            );
        gradient.addColorStop(
            0,
            "#38bdf8"
        );
        gradient.addColorStop(
            1,
            "#bae6fd"
        );
        ctx.fillStyle = gradient;
        ctx.fillRect(
            0,
            0,
            canvas.width,
            canvas.height
        );
        // Clouds
        ctx.fillStyle =
            "rgba(255,255,255,0.75)";
        drawCloud(80, 100);
        drawCloud(330, 160);
        drawCloud(220, 60);
        // Ground
        ctx.fillStyle = "#65a30d";
        ctx.fillRect(
            0,
            canvas.height - 45,
            canvas.width,
            45
        );
    }
    function drawCloud(x, y) {
        ctx.beginPath();
        ctx.arc(
            x,
            y,
            20,
            0,
            Math.PI * 2
        );
        ctx.arc(
            x + 25,
            y - 10,
            25,
            0,
            Math.PI * 2
        );
        ctx.arc(
            x + 55,
            y,
            20,
            0,
            Math.PI * 2
        );
        ctx.fill();
    }
    function drawBird() {
        // Body
        ctx.fillStyle = "#facc15";
        ctx.beginPath();
        ctx.arc(
            bird.x + 15,
            bird.y + 12,
            14,
            0,
            Math.PI * 2
        );
        ctx.fill();
        // Wing
        ctx.fillStyle = "#eab308";
        ctx.beginPath();
        ctx.ellipse(
            bird.x + 8,
            bird.y + 17,
            10,
            6,
            0,
            0,
            Math.PI * 2
        );
        ctx.fill();
        // Eye
        ctx.fillStyle = "white";
        ctx.beginPath();
        ctx.arc(
            bird.x + 20,
            bird.y + 7,
            5,
            0,
            Math.PI * 2
        );
        ctx.fill();
        ctx.fillStyle = "#111827";
        ctx.beginPath();
        ctx.arc(
            bird.x + 22,
            bird.y + 7,
            2,
            0,
            Math.PI * 2
        );
        ctx.fill();
        // Beak
        ctx.fillStyle = "#f97316";
        ctx.beginPath();
        ctx.moveTo(
            bird.x + 28,
            bird.y + 12
        );
        ctx.lineTo(
            bird.x + 40,
            bird.y + 16
        );
        ctx.lineTo(
            bird.x + 28,
            bird.y + 20
        );
        ctx.closePath();
        ctx.fill();
    }
    function drawPipes() {
        pipes.forEach(pipe => {
            ctx.fillStyle = "#16a34a";
            // Top pipe
            ctx.fillRect(
                pipe.x,
                0,
                pipeWidth,
                pipe.top
            );
            // Top pipe cap
            ctx.fillRect(
                pipe.x - 5,
                pipe.top - 18,
                pipeWidth + 10,
                18
            );
            // Bottom pipe
            ctx.fillRect(
                pipe.x,
                pipe.bottom,
                pipeWidth,
                canvas.height -
                pipe.bottom
            );
            // Bottom pipe cap
            ctx.fillRect(
                pipe.x - 5,
                pipe.bottom,
                pipeWidth + 10,
                18
            );
        });
    }
    function drawGameOver() {
        if (!gameOver) {
            return;
        }
        ctx.fillStyle =
            "rgba(0,0,0,0.55)";
        ctx.fillRect(
            0,
            0,
            canvas.width,
            canvas.height
        );
        ctx.fillStyle = "#ffffff";
        ctx.textAlign = "center";
        ctx.font =
            "bold 42px Arial";
        ctx.fillText(
            "Game Over",
            canvas.width / 2,
            canvas.height / 2 - 20
        );
        ctx.font =
            "24px Arial";
        ctx.fillText(
            "Score: " + score,
            canvas.width / 2,
            canvas.height / 2 + 25
        );
        ctx.font =
            "18px Arial";
        ctx.fillText(
            "Press Start Again to play",
            canvas.width / 2,
            canvas.height / 2 + 60
        );
    }
    function draw() {
        drawBackground();
        drawPipes();
        drawBird();
        drawGameOver();
    }
    function gameLoop() {
        update();
        draw();
        if (gameRunning) {
            animationFrame =
                requestAnimationFrame(
                    gameLoop
                );
        }
    }
    document.addEventListener(
        "keydown",
        function(event) {
            if (
                event.code === "Space" ||
                event.key === "ArrowUp"
            ) {
                event.preventDefault();
                flap();
            }
        }
    );
    canvas.addEventListener(
        "pointerdown",
        function() {
            flap();
        }
    );
    startBtn.addEventListener(
        "click",
        function() {
            startGame();
        }
    );
    resetGame();
    draw();
</script>
</body>
</html>

How to Run the Game Code

Running this game is very simple.

Step 1: Create an HTML File

Open Notepad, VS Code, or any other code editor.

Create a new file named:

index.html

Step 2: Paste the Code

Copy the complete Flappy Bird source code above and paste it into the file.

Save the file.

Step 3: Open It in Your Browser

Open index.html in Chrome, Edge, Firefox, or another modern browser.

The game will appear immediately.

Press the Start Game button to begin.

How Users Will Play

The controls and commands to play game are very simple.

On a computer, press the Space key or Arrow Up key to make the bird fly upward.

On a mobile device, simply tap the game area.

The bird will automatically move forward while gravity pulls it down.

Your job is to keep the bird between the pipes.

Every time you successfully pass a pipe, your score increases.

Try to get the highest score possible without hitting a pipe or the ground.

How the Game Works

The game uses the HTML5 Canvas element to draw the bird, pipes, clouds, sky, and ground.

JavaScript controls the complete game logic.

When the player presses Space, Arrow Up, or taps the screen, the bird receives an upward movement.

The pipes are created at random heights and move from right to left.

JavaScript checks the bird’s position against each pipe. If the bird touches a pipe, the game ends.

The same collision system also checks whether the bird reaches the top or bottom of the game