Untitled

 avatar
unknown
plain_text
9 months ago
19 kB
20
Indexable
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Turtle Jump Game</title>
    <style>
        body {
            margin: 0;
            padding: 20px;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            background: linear-gradient(to bottom, #87CEEB 0%, #98FB98 100%);
            font-family: Arial, sans-serif;
        }
        
        .game-container {
            text-align: center;
        }
        
        canvas {
            border: 2px solid #333;
            background: linear-gradient(to bottom, #87CEEB 0%, #90EE90 70%, #228B22 100%);
            display: block;
            margin: 0 auto;
        }
        
        .score {
            font-size: 24px;
            font-weight: bold;
            margin-bottom: 10px;
            color: #333;
        }
        
        .instructions {
            margin-top: 10px;
            color: #666;
        }
        
        .game-over {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: rgba(255, 255, 255, 0.9);
            padding: 20px;
            border-radius: 10px;
            text-align: center;
            display: none;
        }
    </style>
</head>
<body>
    <div class="game-container">
        <div class="score">Score: <span id="score">0</span></div>
        <canvas id="gameCanvas" width="800" height="400"></canvas>
        <div class="instructions">
            Press SPACEBAR or click to jump! Avoid rocks, plants, and swooping birds!
        </div>
        <div class="game-over" id="gameOver">
            <h2>Game Over!</h2>
            <p>Final Score: <span id="finalScore">0</span></p>
            <p>Press SPACEBAR or click to restart</p>
        </div>
    </div>

    <script>
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        const scoreElement = document.getElementById('score');
        const gameOverElement = document.getElementById('gameOver');
        const finalScoreElement = document.getElementById('finalScore');

        // Game variables
        let gameRunning = true;
        let score = 0;
        let gameSpeed = 3;

        // Turtle object
        const turtle = {
            x: 50,
            y: 300,
            width: 40,
            height: 30,
            velocityY: 0,
            jumpPower: -12,
            gravity: 0.6,
            grounded: true,
            color: '#228B22'
        };

        // Obstacles and birds arrays
        let obstacles = [];
        let birds = [];
        let obstacleTimer = 0;
        let birdTimer = 0;

        // Ground
        const ground = {
            y: 330,
            height: 70
        };

        // Draw turtle
        function drawTurtle() {
            ctx.fillStyle = turtle.color;
            
            // Shell (oval)
            ctx.beginPath();
            ctx.ellipse(turtle.x + 20, turtle.y + 10, 18, 12, 0, 0, 2 * Math.PI);
            ctx.fill();
            
            // Shell pattern
            ctx.strokeStyle = '#006400';
            ctx.lineWidth = 2;
            ctx.beginPath();
            ctx.ellipse(turtle.x + 20, turtle.y + 10, 18, 12, 0, 0, 2 * Math.PI);
            ctx.stroke();
            
            // Shell segments
            ctx.beginPath();
            ctx.moveTo(turtle.x + 8, turtle.y + 10);
            ctx.lineTo(turtle.x + 32, turtle.y + 10);
            ctx.moveTo(turtle.x + 20, turtle.y - 2);
            ctx.lineTo(turtle.x + 20, turtle.y + 22);
            ctx.stroke();
            
            // Head
            ctx.fillStyle = '#32CD32';
            ctx.beginPath();
            ctx.arc(turtle.x + 40, turtle.y + 15, 8, 0, 2 * Math.PI);
            ctx.fill();
            
            // Eye
            ctx.fillStyle = '#000';
            ctx.beginPath();
            ctx.arc(turtle.x + 43, turtle.y + 12, 2, 0, 2 * Math.PI);
            ctx.fill();
            
            // Legs
            ctx.fillStyle = '#32CD32';
            ctx.fillRect(turtle.x + 5, turtle.y + 20, 8, 6);
            ctx.fillRect(turtle.x + 27, turtle.y + 20, 8, 6);
        }

        // Draw bird
        function drawBird(bird) {
            ctx.save();
            ctx.translate(bird.x + bird.width/2, bird.y + bird.height/2);
            ctx.rotate(bird.angle);
            
            // Bird body
            ctx.fillStyle = bird.color;
            ctx.beginPath();
            ctx.ellipse(0, 0, 12, 8, 0, 0, 2 * Math.PI);
            ctx.fill();
            
            // Bird head
            ctx.beginPath();
            ctx.arc(8, -2, 6, 0, 2 * Math.PI);
            ctx.fill();
            
            // Beak
            ctx.fillStyle = '#FFA500';
            ctx.beginPath();
            ctx.moveTo(12, -2);
            ctx.lineTo(18, -1);
            ctx.lineTo(12, 1);
            ctx.closePath();
            ctx.fill();
            
            // Eye
            ctx.fillStyle = '#000';
            ctx.beginPath();
            ctx.arc(10, -3, 1.5, 0, 2 * Math.PI);
            ctx.fill();
            
            // Wings (animated)
            ctx.fillStyle = bird.color;
            const wingFlap = Math.sin(Date.now() * 0.02 + bird.id) * 0.3;
            
            // Left wing
            ctx.beginPath();
            ctx.ellipse(-5, 0, 8, 4, wingFlap, 0, 2 * Math.PI);
            ctx.fill();
            
            // Right wing
            ctx.beginPath();
            ctx.ellipse(-5, 0, 8, 4, -wingFlap, 0, 2 * Math.PI);
            ctx.fill();
            
            // Tail
            ctx.beginPath();
            ctx.ellipse(-12, 0, 6, 3, 0, 0, 2 * Math.PI);
            ctx.fill();
            
            ctx.restore();
        }

        // Draw obstacle (rock)
        function drawRock(obstacle) {
            ctx.fillStyle = '#696969';
            ctx.beginPath();
            ctx.arc(obstacle.x + obstacle.width/2, obstacle.y + obstacle.height/2, obstacle.width/2, 0, 2 * Math.PI);
            ctx.fill();
            
            // Rock texture
            ctx.fillStyle = '#556B2F';
            ctx.beginPath();
            ctx.arc(obstacle.x + 8, obstacle.y + 8, 3, 0, 2 * Math.PI);
            ctx.fill();
            ctx.beginPath();
            ctx.arc(obstacle.x + 18, obstacle.y + 12, 2, 0, 2 * Math.PI);
            ctx.fill();
        }

        // Draw plant obstacle
        function drawPlant(obstacle) {
            // Stem
            ctx.fillStyle = '#228B22';
            ctx.fillRect(obstacle.x + obstacle.width/2 - 2, obstacle.y + 15, 4, obstacle.height - 15);
            
            // Leaves
            ctx.fillStyle = '#32CD32';
            
            // Left leaves
            ctx.beginPath();
            ctx.ellipse(obstacle.x + 8, obstacle.y + 20, 8, 4, -Math.PI/4, 0, 2 * Math.PI);
            ctx.fill();
            
            ctx.beginPath();
            ctx.ellipse(obstacle.x + 6, obstacle.y + 30, 7, 3, -Math.PI/6, 0, 2 * Math.PI);
            ctx.fill();
            
            // Right leaves
            ctx.beginPath();
            ctx.ellipse(obstacle.x + 22, obstacle.y + 18, 8, 4, Math.PI/4, 0, 2 * Math.PI);
            ctx.fill();
            
            ctx.beginPath();
            ctx.ellipse(obstacle.x + 24, obstacle.y + 28, 7, 3, Math.PI/6, 0, 2 * Math.PI);
            ctx.fill();
            
            // Top leaves
            ctx.beginPath();
            ctx.ellipse(obstacle.x + 15, obstacle.y + 10, 6, 8, 0, 0, 2 * Math.PI);
            ctx.fill();
            
            // Flower (sometimes)
            if (obstacle.hasFlower) {
                ctx.fillStyle = '#FF69B4';
                ctx.beginPath();
                ctx.arc(obstacle.x + 15, obstacle.y + 5, 4, 0, 2 * Math.PI);
                ctx.fill();
                
                // Flower center
                ctx.fillStyle = '#FFD700';
                ctx.beginPath();
                ctx.arc(obstacle.x + 15, obstacle.y + 5, 2, 0, 2 * Math.PI);
                ctx.fill();
            }
        }

        // Draw cactus obstacle
        function drawCactus(obstacle) {
            // Main body
            ctx.fillStyle = '#228B22';
            ctx.fillRect(obstacle.x + 8, obstacle.y + 10, 14, obstacle.height - 10);
            
            // Side arms
            ctx.fillRect(obstacle.x + 2, obstacle.y + 20, 10, 6);
            ctx.fillRect(obstacle.x + 18, obstacle.y + 25, 10, 6);
            
            // Spikes
            ctx.fillStyle = '#8B4513';
            ctx.lineWidth = 1;
            
            // Main body spikes
            for (let i = 0; i < 6; i++) {
                ctx.fillRect(obstacle.x + 10 + i * 2, obstacle.y + 15 + i * 4, 1, 3);
                ctx.fillRect(obstacle.x + 18 - i, obstacle.y + 18 + i * 3, 1, 3);
            }
            
            // Side arm spikes
            ctx.fillRect(obstacle.x + 4, obstacle.y + 21, 1, 2);
            ctx.fillRect(obstacle.x + 8, obstacle.y + 22, 1, 2);
            ctx.fillRect(obstacle.x + 20, obstacle.y + 26, 1, 2);
            ctx.fillRect(obstacle.x + 24, obstacle.y + 27, 1, 2);
        }

        // Draw ground
        function drawGround() {
            ctx.fillStyle = '#8B4513';
            ctx.fillRect(0, ground.y, canvas.width, ground.height);
            
            // Grass on top
            ctx.fillStyle = '#228B22';
            ctx.fillRect(0, ground.y, canvas.width, 10);
        }

        // Update turtle physics
        function updateTurtle() {
            turtle.velocityY += turtle.gravity;
            turtle.y += turtle.velocityY;

            // Ground collision
            if (turtle.y >= ground.y - turtle.height) {
                turtle.y = ground.y - turtle.height;
                turtle.velocityY = 0;
                turtle.grounded = true;
            } else {
                turtle.grounded = false;
            }
        }

        // Jump function
        function jump() {
            if (turtle.grounded && gameRunning) {
                turtle.velocityY = turtle.jumpPower;
                turtle.grounded = false;
            }
        }

        // Create obstacle
        function createObstacle() {
            const obstacleTypes = ['rock', 'plant', 'cactus'];
            const type = obstacleTypes[Math.floor(Math.random() * obstacleTypes.length)];
            
            let obstacle = {
                x: canvas.width,
                type: type
            };

            switch(type) {
                case 'rock':
                    obstacle.y = ground.y - 25;
                    obstacle.width = 25;
                    obstacle.height = 25;
                    break;
                case 'plant':
                    obstacle.y = ground.y - 40;
                    obstacle.width = 30;
                    obstacle.height = 40;
                    obstacle.hasFlower = Math.random() > 0.5;
                    break;
                case 'cactus':
                    obstacle.y = ground.y - 45;
                    obstacle.width = 30;
                    obstacle.height = 45;
                    break;
            }

            obstacles.push(obstacle);
        }

        // Create bird
        function createBird() {
            const birdColors = ['#8B4513', '#DC143C', '#4169E1', '#32CD32', '#FF8C00'];
            const attackPatterns = ['swoop', 'dive', 'circle'];
            
            let bird = {
                x: canvas.width + 50,
                y: Math.random() * 150 + 50, // Start somewhere in upper area
                width: 25,
                height: 20,
                velocityX: -(gameSpeed + Math.random() * 2 + 1),
                velocityY: 0,
                color: birdColors[Math.floor(Math.random() * birdColors.length)],
                pattern: attackPatterns[Math.floor(Math.random() * attackPatterns.length)],
                angle: 0,
                id: Math.random(), // For wing animation
                phase: 0, // For attack pattern timing
                targetY: 0
            };

            // Set target based on pattern
            switch(bird.pattern) {
                case 'swoop':
                    bird.targetY = turtle.y + Math.random() * 40 - 20;
                    break;
                case 'dive':
                    bird.targetY = ground.y - 30;
                    break;
                case 'circle':
                    bird.targetY = turtle.y - 50;
                    break;
            }

            birds.push(bird);
        }

        // Update birds
        function updateBirds() {
            birdTimer++;
            
            // Create new bird
            if (birdTimer > 180 - Math.floor(score / 150) * 10) {
                createBird();
                birdTimer = 0;
            }

            // Update existing birds
            for (let i = birds.length - 1; i >= 0; i--) {
                let bird = birds[i];
                bird.phase += 0.05;

                // Update bird movement based on pattern
                switch(bird.pattern) {
                    case 'swoop':
                        // Swooping motion - sine wave towards target
                        bird.x += bird.velocityX;
                        bird.y += Math.sin(bird.phase * 2) * 2;
                        if (bird.x < turtle.x + 100 && bird.x > turtle.x - 50) {
                            bird.velocityY = (bird.targetY - bird.y) * 0.1;
                            bird.y += bird.velocityY;
                        }
                        bird.angle = Math.atan2(bird.velocityY, bird.velocityX);
                        break;
                        
                    case 'dive':
                        // Diving attack
                        bird.x += bird.velocityX;
                        if (bird.x < turtle.x + 150) {
                            bird.velocityY += 0.5; // Accelerate downward
                            bird.y += bird.velocityY;
                        }
                        bird.angle = Math.atan2(bird.velocityY, bird.velocityX);
                        break;
                        
                    case 'circle':
                        // Circling pattern
                        bird.x += bird.velocityX * 0.7;
                        bird.y = bird.targetY + Math.sin(bird.phase * 3) * 30;
                        bird.angle = bird.phase * 3;
                        break;
                }

                // Remove birds that are off screen
                if (bird.x + bird.width < -50 || bird.y > canvas.height + 50) {
                    birds.splice(i, 1);
                    score += 5; // Small bonus for surviving a bird
                }
            }
        }

        // Update obstacles
        function updateObstacles() {
            obstacleTimer++;
            
            // Create new obstacle
            if (obstacleTimer > 100 - Math.floor(score / 100) * 8) {
                createObstacle();
                obstacleTimer = 0;
            }

            // Move obstacles
            for (let i = obstacles.length - 1; i >= 0; i--) {
                obstacles[i].x -= gameSpeed;

                // Remove off-screen obstacles
                if (obstacles[i].x + obstacles[i].width < 0) {
                    obstacles.splice(i, 1);
                    score += 10;
                }
            }
        }

        // Collision detection
        function checkCollisions() {
            // Check obstacle collisions
            for (let obstacle of obstacles) {
                if (turtle.x < obstacle.x + obstacle.width &&
                    turtle.x + turtle.width > obstacle.x &&
                    turtle.y < obstacle.y + obstacle.height &&
                    turtle.y + turtle.height > obstacle.y) {
                    gameOver();
                }
            }

            // Check bird collisions
            for (let bird of birds) {
                if (turtle.x < bird.x + bird.width &&
                    turtle.x + turtle.width > bird.x &&
                    turtle.y < bird.y + bird.height &&
                    turtle.y + turtle.height > bird.y) {
                    gameOver();
                }
            }
        }

        // Game over
        function gameOver() {
            gameRunning = false;
            finalScoreElement.textContent = score;
            gameOverElement.style.display = 'block';
        }

        // Restart game
        function restart() {
            gameRunning = true;
            score = 0;
            obstacles = [];
            birds = [];
            obstacleTimer = 0;
            birdTimer = 0;
            turtle.y = 300;
            turtle.velocityY = 0;
            turtle.grounded = true;
            gameOverElement.style.display = 'none';
        }

        // Game loop
        function gameLoop() {
            // Clear canvas
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            if (gameRunning) {
                // Update game objects
                updateTurtle();
                updateObstacles();
                updateBirds();
                checkCollisions();

                // Increase game speed gradually
                gameSpeed = 3 + Math.floor(score / 200) * 0.5;
            }

            // Draw everything
            drawGround();
            drawTurtle();
            
            // Draw obstacles
            for (let obstacle of obstacles) {
                switch(obstacle.type) {
                    case 'rock':
                        drawRock(obstacle);
                        break;
                    case 'plant':
                        drawPlant(obstacle);
                        break;
                    case 'cactus':
                        drawCactus(obstacle);
                        break;
                }
            }

            // Draw birds
            for (let bird of birds) {
                drawBird(bird);
            }

            // Update score display
            scoreElement.textContent = score;

            requestAnimationFrame(gameLoop);
        }

        // Event listeners
        document.addEventListener('keydown', function(event) {
            if (event.code === 'Space') {
                event.preventDefault();
                if (gameRunning) {
                    jump();
                } else {
                    restart();
                }
            }
        });

        canvas.addEventListener('click', function() {
            if (gameRunning) {
                jump();
            } else {
                restart();
            }
        });

        // Start the game
        gameLoop();
    </script>
</body>
</html>
Editor is loading...
Leave a Comment