Header Ads Widget

Responsive Advertisement

Flappy Bird Game


 <!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 - Crow Edition</title>

    <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">

    <style>

        body {

            margin: 0;

            padding: 0;

            font-family: 'Arial', sans-serif;

            background-color: #333;

            overflow: hidden;

        }

        

        .game-container {

            position: relative;

            width: 100vw;

            height: 100vh;

            display: flex;

            justify-content: center;

            align-items: center;

        }

        

        canvas {

            border: 1px solid #000;

            max-width: 100%;

            max-height: 100%;

        }

        

        .game-ui {

            position: absolute;

            top: 0;

            left: 0;

            width: 100%;

            padding: 20px;

            z-index: 10;

            pointer-events: none;

        }

        

        .score {

            font-size: 40px;

            font-weight: bold;

            color: white;

            text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);

            text-align: center;

        }

        

        .start-screen, .game-over {

            position: absolute;

            top: 0;

            left: 0;

            width: 100%;

            height: 100%;

            display: flex;

            flex-direction: column;

            justify-content: center;

            align-items: center;

            background-color: rgba(0, 0, 0, 0.5);

            z-index: 20;

        }

        

        .btn {

            padding: 10px 20px;

            font-size: 18px;

            background-color: #4CAF50;

            color: white;

            border: none;

            border-radius: 5px;

            cursor: pointer;

            margin-top: 20px;

            pointer-events: auto;

        }

        

        .btn:hover {

            background-color: #45a049;

        }

        

        .title {

            font-size: 48px;

            font-weight: bold;

            color: white;

            margin-bottom: 20px;

            text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);

        }

        

        .game-over-score {

            font-size: 32px;

            color: white;

            margin-bottom: 20px;

            text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);

        }

    </style>

</head>

<body class="bg-gray-800">

    <div class="game-container">

        <canvas id="gameCanvas" width="320" height="480"></canvas>

        

        <div class="game-ui">

            <div class="score" id="score">0</div>

        </div>

        

        <div class="start-screen" id="startScreen">

            <div class="title">Flappy Crow</div>

            <p class="text-white text-xl mb-4">Click or press Spacebar to flap</p>

            <button class="btn" id="startButton">Start Game</button>

        </div>

        

        <div class="game-over" id="gameOverScreen" style="display: none;">

            <div class="title">Game Over</div>

            <div class="game-over-score" id="finalScore">Score: 0</div>

            <button class="btn" id="restartButton">Play Again</button>

        </div>

    </div>

    

    <script>

        document.addEventListener('DOMContentLoaded', () => {

            const canvas = document.getElementById('gameCanvas');

            const ctx = canvas.getContext('2d');

            const scoreDisplay = document.getElementById('score');

            const finalScoreDisplay = document.getElementById('finalScore');

            const startScreen = document.getElementById('startScreen');

            const gameOverScreen = document.getElementById('gameOverScreen');

            const startButton = document.getElementById('startButton');

            const restartButton = document.getElementById('restartButton');

            

            // Game variables

            let gameRunning = false;

            let gameOver = false;

            let score = 0;

            let frames = 0;

            let daytime = true;

            let cycleCounter = 0;

            

            // Bird settings

            const bird = {

                x: 50,

                y: canvas.height / 2,

                width: 38,

                height: 28,

                gravity: 0.25,

                velocity: 0,

                jump: 4.6,

                rotation: 0,

                

                draw: function() {

                    ctx.save();

                    ctx.translate(this.x, this.y);

                    ctx.rotate(this.rotation);

                    

                    // Draw crow body (black)

                    ctx.fillStyle = '#000000'; // Crow body - pure black

                    ctx.beginPath();

                    ctx.arc(0, 0, 13, 0, Math.PI * 2);

                    ctx.fill();

                    

                    // Crow tail feathers

                    ctx.beginPath();

                    ctx.moveTo(-8, 0);

                    ctx.lineTo(-20, -5);

                    ctx.lineTo(-20, 5);

                    ctx.closePath();

                    ctx.fill();

                    

                    // Wing - slightly different shade

                    ctx.fillStyle = '#191919';

                    ctx.beginPath();

                    ctx.ellipse(-2, 5, 12, 7, 0, 0, Math.PI * 2);

                    ctx.fill();

                    

                    // Wing detail

                    ctx.strokeStyle = '#333333';

                    ctx.lineWidth = 1;

                    ctx.beginPath();

                    ctx.moveTo(-10, 3);

                    ctx.lineTo(5, 7);

                    ctx.stroke();

                    

                    // Eye

                    ctx.fillStyle = 'white';

                    ctx.beginPath();

                    ctx.arc(8, -4, 4, 0, Math.PI * 2);

                    ctx.fill();

                    

                    // Pupil

                    ctx.fillStyle = 'black';

                    ctx.beginPath();

                    ctx.arc(9, -4, 2, 0, Math.PI * 2);

                    ctx.fill();

                    

                    // Beak

                    ctx.fillStyle = '#333333'; // Dark gray beak

                    ctx.beginPath();

                    ctx.moveTo(10, 0);

                    ctx.lineTo(22, -1);

                    ctx.lineTo(22, 1);

                    ctx.closePath();

                    ctx.fill();

                    

                    // Head feather tufts (crow's slight head crest)

                    ctx.fillStyle = '#000000';

                    ctx.beginPath();

                    ctx.moveTo(0, -10);

                    ctx.lineTo(5, -16);

                    ctx.lineTo(8, -12);

                    ctx.closePath();

                    ctx.fill();

                    

                    ctx.restore();

                },

                

                flap: function() {

                    this.velocity = -this.jump;

                },

                

                update: function() {

                    // Apply gravity

                    this.velocity += this.gravity;

                    this.y += this.velocity;

                    

                    // Limit bird movement to canvas bounds

                    if (this.y + this.height/2 >= canvas.height - foreground.height) {

                        this.y = canvas.height - foreground.height - this.height/2;

                        this.velocity = 0;

                        gameRunning = false;

                        gameOver = true;

                    }

                    

                    if (this.y - this.height/2 <= 0) {

                        this.y = this.height/2;

                        this.velocity = 0;

                    }

                    

                    // Set bird rotation based on velocity

                    if (this.velocity >= 5) {

                        this.rotation = Math.PI/4; // 45 degrees down

                    } else if (this.velocity <= 0) {

                        this.rotation = -Math.PI/6; // 30 degrees up

                    } else {

                        this.rotation = 0;

                    }

                }

            };

            

            // Background

            const background = {

                x: 0,

                y: 0,

                width: canvas.width,

                height: canvas.height - 112,

                

                draw: function() {

                    // Create gradient background instead of solid color

                    let skyGradient;

                    

                    if (daytime) {

                        // Day sky - blue gradient

                        skyGradient = ctx.createLinearGradient(0, 0, 0, this.height);

                        skyGradient.addColorStop(0, '#1E90FF'); // Deep blue at top

                        skyGradient.addColorStop(0.7, '#87CEEB'); // Sky blue

                        skyGradient.addColorStop(1, '#E0F7FA'); // Light blue near horizon

                    } else {

                        // Night sky - dark blue gradient with stars

                        skyGradient = ctx.createLinearGradient(0, 0, 0, this.height);

                        skyGradient.addColorStop(0, '#000033'); // Deep blue at top

                        skyGradient.addColorStop(0.7, '#0A1172'); // Midnight blue

                        skyGradient.addColorStop(1, '#1F4788'); // Lighter blue near horizon

                    }

                    

                    // Fill background with gradient

                    ctx.fillStyle = skyGradient;

                    ctx.fillRect(0, 0, canvas.width, this.height);

                    

                    // Add sun or moon

                    if (daytime) {

                        // Sun

                        ctx.fillStyle = '#FFFF00';

                        ctx.beginPath();

                        ctx.arc(canvas.width - 50, 50, 30, 0, Math.PI * 2);

                        ctx.fill();

                        

                        // Sun rays

                        ctx.strokeStyle = '#FFFF00';

                        ctx.lineWidth = 2;

                        for (let i = 0; i < 8; i++) {

                            ctx.beginPath();

                            ctx.moveTo(canvas.width - 50, 50);

                            let angle = i * Math.PI / 4;

                            ctx.lineTo(

                                canvas.width - 50 + Math.cos(angle) * 45, 

                                50 + Math.sin(angle) * 45

                            );

                            ctx.stroke();

                        }

                        

                        // Fluffy clouds

                        ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';

                        

                        // Cloud 1

                        ctx.beginPath();

                        ctx.arc(80, 80, 25, 0, Math.PI * 2);

                        ctx.arc(120, 70, 35, 0, Math.PI * 2);

                        ctx.arc(160, 85, 25, 0, Math.PI * 2);

                        ctx.fill();

                        

                        // Cloud 2

                        ctx.beginPath();

                        ctx.arc(250, 100, 30, 0, Math.PI * 2);

                        ctx.arc(290, 90, 40, 0, Math.PI * 2);

                        ctx.arc(330, 105, 30, 0, Math.PI * 2);

                        ctx.fill();

                        

                    } else {

                        // Moon

                        ctx.fillStyle = '#FFFFCC';

                        ctx.beginPath();

                        ctx.arc(canvas.width - 50, 50, 25, 0, Math.PI * 2);

                        ctx.fill();

                        

                        // Moon crater 1

                        ctx.fillStyle = 'rgba(200, 200, 200, 0.3)';

                        ctx.beginPath();

                        ctx.arc(canvas.width - 60, 40, 7, 0, Math.PI * 2);

                        ctx.fill();

                        

                        // Moon crater 2

                        ctx.beginPath();

                        ctx.arc(canvas.width - 45, 60, 5, 0, Math.PI * 2);

                        ctx.fill();

                        

                        // Stars

                        ctx.fillStyle = 'white';

                        const stars = [

                            {x: 30, y: 50}, {x: 70, y: 30}, {x: 150, y: 60},

                            {x: 200, y: 40}, {x: 250, y: 70}, {x: 100, y: 90},

                            {x: 180, y: 120}, {x: 220, y: 150}, {x: 120, y: 170}

                        ];

                        

                        stars.forEach(star => {

                            ctx.beginPath();

                            ctx.arc(star.x, star.y, 1.5, 0, Math.PI * 2);

                            ctx.fill();

                        });

                        

                        // Draw some twinkling stars

                        const twinkleFactor = Math.sin(frames * 0.05) * 0.5 + 0.5;

                        ctx.fillStyle = `rgba(255, 255, 255, ${twinkleFactor})`;

                        

                        const twinklingStars = [

                            {x: 50, y: 70}, {x: 120, y: 40}, {x: 170, y: 80},

                            {x: 240, y: 60}, {x: 280, y: 90}, {x: 80, y: 110}

                        ];

                        

                        twinklingStars.forEach(star => {

                            ctx.beginPath();

                            ctx.arc(star.x, star.y, 2, 0, Math.PI * 2);

                            ctx.fill();

                        });

                    }

                    

                    // Add distant mountains

                    const mountainColor = daytime ? '#7986CB' : '#303F9F';

                    ctx.fillStyle = mountainColor;

                    

                    // Mountain range

                    ctx.beginPath();

                    ctx.moveTo(0, this.height);

                    ctx.lineTo(0, this.height - 80);

                    ctx.lineTo(40, this.height - 100);

                    ctx.lineTo(80, this.height - 60);

                    ctx.lineTo(120, this.height - 130);

                    ctx.lineTo(180, this.height - 80);

                    ctx.lineTo(220, this.height - 110);

                    ctx.lineTo(280, this.height - 70);

                    ctx.lineTo(320, this.height - 90);

                    ctx.lineTo(320, this.height);

                    ctx.closePath();

                    ctx.fill();

                    

                    // Snow caps on mountains if daytime

                    if (daytime) {

                        ctx.fillStyle = 'white';

                        ctx.beginPath();

                        ctx.moveTo(115, this.height - 130);

                        ctx.lineTo(120, this.height - 130);

                        ctx.lineTo(125, this.height - 125);

                        ctx.lineTo(115, this.height - 125);

                        ctx.closePath();

                        ctx.fill();

                        

                        ctx.beginPath();

                        ctx.moveTo(215, this.height - 110);

                        ctx.lineTo(220, this.height - 110);

                        ctx.lineTo(225, this.height - 105);

                        ctx.lineTo(215, this.height - 105);

                        ctx.closePath();

                        ctx.fill();

                    }

                }

            };

            

            // Foreground

            const foreground = {

                x: 0,

                y: canvas.height - 112,

                width: canvas.width,

                height: 112,

                dx: 2, // Scroll speed

                

                draw: function() {

                    // Ground gradient

                    const groundGradient = ctx.createLinearGradient(0, this.y, 0, canvas.height);

                    

                    if (daytime) {

                        groundGradient.addColorStop(0, '#7CFC00'); // Grass top

                        groundGradient.addColorStop(0.2, '#5EAE5E'); // Grass middle

                        groundGradient.addColorStop(1, '#8B4513'); // Dirt bottom

                    } else {

                        groundGradient.addColorStop(0, '#3A5F0B'); // Dark grass top

                        groundGradient.addColorStop(0.2, '#2F4F2F'); // Dark grass middle

                        groundGradient.addColorStop(1, '#3D2314'); // Dark dirt bottom

                    }

                    

                    ctx.fillStyle = groundGradient;

                    ctx.fillRect(0, this.y, canvas.width, this.height);

                    

                    // Draw grass tufts

                    ctx.fillStyle = daytime ? '#7CFC00' : '#3A5F0B';

                    for (let i = 0; i < canvas.width; i += 15) {

                        const height = 5 + Math.random() * 5;

                        ctx.fillRect(i, this.y, 3, -height);

                    }

                    

                    // Draw a path

                    ctx.fillStyle = daytime ? '#D2B48C' : '#5D4037';

                    ctx.fillRect(0, this.y + 20, canvas.width, 10);

                    

                    // Draw pebbles on the path

                    ctx.fillStyle = daytime ? '#A9A9A9' : '#424242';

                    for (let i = 0; i < canvas.width; i += 20) {

                        const x = i + Math.random() * 10;

                        ctx.beginPath();

                        ctx.arc(x, this.y + 25, 2, 0, Math.PI * 2);

                        ctx.fill();

                    }

                },

                

                update: function() {

                    if (gameRunning) {

                        this.x = (this.x - this.dx) % (canvas.width/4);

                    }

                }

            };

            

            // Pipes

            const pipes = {

                position: [],

                gap: 100,

                maxYPos: -150,

                dx: 2,

                

                draw: function() {

                    for (let i = 0; i < this.position.length; i++) {

                        let p = this.position[i];

                        

                        // Pipe gradient

                        const pipeGradient = ctx.createLinearGradient(p.x, 0, p.x + p.width, 0);

                        

                        if (daytime) {

                            pipeGradient.addColorStop(0, '#32CD32'); // Left edge

                            pipeGradient.addColorStop(0.5, '#73BF2E'); // Middle

                            pipeGradient.addColorStop(1, '#32CD32'); // Right edge

                        } else {

                            pipeGradient.addColorStop(0, '#1B5E20'); // Left edge

                            pipeGradient.addColorStop(0.5, '#2E7D32'); // Middle

                            pipeGradient.addColorStop(1, '#1B5E20'); // Right edge

                        }

                        

                        // Top pipe

                        ctx.fillStyle = pipeGradient;

                        ctx.fillRect(p.x, p.y, p.width, p.height);

                        

                        // Pipe cap gradient

                        const capGradient = ctx.createLinearGradient(p.x - 2, 0, p.x + p.width + 4, 0);

                        

                        if (daytime) {

                            capGradient.addColorStop(0, '#228B22'); // Left edge

                            capGradient.addColorStop(0.5, '#588A1B'); // Middle

                            capGradient.addColorStop(1, '#228B22'); // Right edge

                        } else {

                            capGradient.addColorStop(0, '#0F3D0F'); // Left edge

                            capGradient.addColorStop(0.5, '#1B4D1B'); // Middle

                            capGradient.addColorStop(1, '#0F3D0F'); // Right edge

                        }

                        

                        // Pipe cap

                        ctx.fillStyle = capGradient;

                        ctx.fillRect(p.x - 2, p.y + p.height - 10, p.width + 4, 10);

                        

                        // Bottom pipe

                        let bottomPipeY = p.y + p.height + this.gap;

                        ctx.fillStyle = pipeGradient;

                        ctx.fillRect(p.x, bottomPipeY, p.width, canvas.height - bottomPipeY - foreground.height);

                        

                        // Pipe cap

                        ctx.fillStyle = capGradient;

                        ctx.fillRect(p.x - 2, bottomPipeY, p.width + 4, 10);

                    }

                },

                

                update: function() {

                    if (!gameRunning) return;

                    

                    if (frames % 100 === 0) {

                        this.position.push({

                            x: canvas.width,

                            y: this.maxYPos * (Math.random() + 1),

                            width: 52,

                            height: 320

                        });

                    }

                    

                    for (let i = 0; i < this.position.length; i++) {

                        let p = this.position[i];

                        

                        // Move pipes to the left

                        p.x -= this.dx;

                        

                        // If a pipe goes off screen, remove it

                        if (p.x + p.width < 0) {

                            this.position.shift();

                            

                            // Increment score when pipe passes

                            score++;

                            scoreDisplay.innerText = score;

                        }

                        

                        // Check for collision

                        // Top pipe

                        if (

                            bird.x + bird.width/2 > p.x && 

                            bird.x - bird.width/2 < p.x + p.width && 

                            bird.y - bird.height/2 < p.y + p.height && 

                            bird.y + bird.height/2 > p.y

                        ) {

                            gameRunning = false;

                            gameOver = true;

                        }

                        

                        // Bottom pipe

                        if (

                            bird.x + bird.width/2 > p.x && 

                            bird.x - bird.width/2 < p.x + p.width && 

                            bird.y - bird.height/2 < p.y + p.height + this.gap + (canvas.height - p.y - p.height - this.gap - foreground.height) && 

                            bird.y + bird.height/2 > p.y + p.height + this.gap

                        ) {

                            gameRunning = false;

                            gameOver = true;

                        }

                    }

                }

            };

            

            // Day/Night cycle

            function updateDayNightCycle() {

                if (gameRunning) {

                    cycleCounter++;

                    

                    // Change between day and night every 30 seconds (approximately 1800 frames)

                    if (cycleCounter >= 1800) {

                        daytime = !daytime;

                        cycleCounter = 0;

                    }

                }

            }

            

            // Game functions

            function draw() {

                background.draw();

                pipes.draw();

                foreground.draw();

                bird.draw();

            }

            

            function update() {

                bird.update();

                foreground.update();

                pipes.update();

                updateDayNightCycle();

            }

            

            function loop() {

                update();

                draw();

                

                frames++;

                

                if (gameOver) {

                    finalScoreDisplay.innerText = `Score: ${score}`;

                    gameOverScreen.style.display = 'flex';

                    return;

                }

                

                requestAnimationFrame(loop);

            }

            

            function init() {

                gameRunning = true;

                gameOver = false;

                score = 0;

                frames = 0;

                cycleCounter = 0;

                daytime = true;

                bird.y = canvas.height / 2;

                bird.velocity = 0;

                pipes.position = [];

                

                scoreDisplay.innerText = score;

                startScreen.style.display = 'none';

                gameOverScreen.style.display = 'none';

                

                loop();

            }

            

            // Event Listeners

            startButton.addEventListener('click', init);

            restartButton.addEventListener('click', init);

            

            canvas.addEventListener('click', () => {

                if (gameRunning) {

                    bird.flap();

                }

            });

            

            document.addEventListener('keydown', (e) => {

                if (e.code === 'Space' && gameRunning) {

                    bird.flap();

                }

            });

            

            // Initial draw

            draw();

        });

    </script>

</body>

</html>


Post a Comment

0 Comments