Untitled

 avatar
unknown
plain_text
a month ago
9.8 kB
4
Indexable
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Mini Geometry Dash</title>
    <style>
        body {
            margin: 0;
            background: #111;
            color: white;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            min-height: 100vh;
            overflow: hidden;
        }
        h1 {
            margin: 5px 0;
            font-size: 24px;
            letter-spacing: 2px;
        }
        #gameContainer {
            position: relative;
            box-shadow: 0 10px 30px rgba(0,0,0,0.5);
            border-radius: 4px;
            overflow: hidden;
        }
        canvas {
            background: linear-gradient(#2b004f, #0d001a);
            display: block;
        }
        .ui-layer {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            pointer-events: none;
        }
        #screenMenu, #screenGameOver {
            background: rgba(0, 0, 0, 0.75);
            position: absolute;
            inset: 0;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            pointer-events: auto;
            transition: opacity 0.2s;
        }
        .hidden {
            display: none !important;
            opacity: 0;
        }
        button {
            background: #00e676;
            color: black;
            border: none;
            padding: 12px 35px;
            font-size: 18px;
            font-weight: bold;
            border-radius: 25px;
            cursor: pointer;
            box-shadow: 0 4px 15px rgba(0,230,118,0.4);
            transition: transform 0.1s, background 0.2s;
        }
        button:hover {
            background: #00b359;
            transform: scale(1.05);
        }
        button:active {
            transform: scale(0.95);
        }
        #scoreBoard {
            position: absolute;
            top: 15px;
            left: 15px;
            font-size: 18px;
            font-weight: bold;
            text-shadow: 2px 2px 4px rgba(0,0,0,0.8);
        }
        .instructions {
            margin-top: 15px;
            font-size: 14px;
            color: #aaa;
            text-align: center;
        }
    </style>
</head>
<body>

    <h1>GEOMETRY DASH</h1>
    
    <div id="gameContainer">
        <canvas id="gameCanvas" width="800" height="400"></canvas>
        
        <!-- Score -->
        <div id="scoreBoard">Score: <span id="scoreVal">0</span></div>

        <!-- Main Menu -->
        <div id="screenMenu">
            <button id="btnStart">PLAY</button>
            <div class="instructions">Press SPACEBAR, UP ARROW, or CLICK to Jump</div>
        </div>

        <!-- Game Over Screen -->
        <div id="screenGameOver" class="hidden">
            <h2 style="color: #ff1744; font-size: 32px; margin-bottom: 15px;">CRASHED!</h2>
            <button id="btnRestart">RETRY</button>
        </div>
    </div>

    <script>
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');

        // UI Screens
        const screenMenu = document.getElementById('screenMenu');
        const screenGameOver = document.getElementById('screenGameOver');
        const scoreVal = document.getElementById('scoreVal');
        
        // Buttons
        document.getElementById('btnStart').addEventListener('click', startGame);
        document.getElementById('btnRestart').addEventListener('click', startGame);

        // Game Constants & Physics
        const GRAVITY = 1.4;
        const JUMP_FORCE = -18;
        const FLOOR_Y = 320;
        const GAME_SPEED = 8;

        // Game Variables
        let gameState = 'MENU'; // MENU, PLAYING, GAMEOVER
        let score = 0;
        let obstacles = [];
        let particles = [];
        let obstacleTimer = 0;

        // Player Object
        const player = {
            x: 100,
            y: FLOOR_Y - 40,
            w: 40,
            h: 40,
            vy: 0,
            rotation: 0,
            isGrounded: false,
            color: '#00e676'
        };

        // Input Management
        const inputKeys = {};
        window.addEventListener('keydown', (e) => {
            inputKeys[e.code] = true;
            if ((e.code === 'Space' || e.code === 'ArrowUp') && gameState === 'PLAYING') {
                triggerJump();
            }
        });
        window.addEventListener('keyup', (e) => inputKeys[e.code] = false);
        canvas.addEventListener('mousedown', () => {
            if (gameState === 'PLAYING') triggerJump();
        });

        function triggerJump() {
            if (player.isGrounded) {
                player.vy = JUMP_FORCE;
                player.isGrounded = false;
            }
        }

        // Obstacle Spawning
        function spawnObstacle() {
            // Randomly pick between Spike (Triangle) or Block (Square)
            const type = Math.random() > 0.4 ? 'spike' : 'block';
            obstacles.push({
                x: canvas.width + 50,
                y: FLOOR_Y,
                w: 40,
                h: type === 'spike' ? 42 : 40,
                type: type,
                passed: false
            });
        }

        // Particle System for the Trail
        function createExplosion(x, y) {
            for (let i = 0; i < 20; i++) {
                particles.push({
                    x: x,
                    y: y,
                    vx: (Math.random() - 0.5) * 10,
                    vy: (Math.random() - 0.5) * 10,
                    size: Math.random() * 6 + 2,
                    color: player.color,
                    alpha: 1
                });
            }
        }

        function handleParticles() {
            // Floor trail sparks while running
            if (player.isGrounded && Math.random() > 0.4) {
                particles.push({
                    x: player.x,
                    y: FLOOR_Y,
                    vx: -3 - Math.random() * 3,
                    vy: -Math.random() * 2,
                    size: Math.random() * 4 + 1,
                    color: '#fff',
                    alpha: 0.8
                });
            }

            for (let i = particles.length - 1; i >= 0; i--) {
                let p = particles[i];
                p.x += p.vx;
                p.y += p.vy;
                p.alpha -= 0.03;
                
                if (p.alpha <= 0) {
                    particles.splice(i, 1);
                } else {
                    ctx.save();
                    ctx.globalAlpha = p.alpha;
                    ctx.fillStyle = p.color;
                    ctx.fillRect(p.x, p.y, p.size, p.size);
                    ctx.restore();
                }
            }
        }

        // Initialize/Reset Game Loop
        function startGame() {
            gameState = 'PLAYING';
            score = 0;
            scoreVal.textContent = score;
            obstacles = [];
            particles = [];
            obstacleTimer = 0;
            
            player.y = FLOOR_Y - player.h;
            player.vy = 0;
            player.rotation = 0;
            player.isGrounded = true;

            screenMenu.classList.add('hidden');
            screenGameOver.classList.add('hidden');
        }

        function gameOver() {
            gameState = 'GAMEOVER';
            createExplosion(player.x + player.w/2, player.y + player.h/2);
            screenGameOver.classList.remove('hidden');
        }

        // Collision Check (AABB & Triangle approximate logic)
        function checkCollision(rect1, rect2) {
            return (
                rect1.x < rect2.x + rect2.w &&
                rect1.x + rect1.w > rect2.x &&
                rect1.y < rect2.y && // Obstacle base line
                rect1.y + rect1.h > rect2.y - rect2.h
            );
        }

        // Primary Game Loop Engine
        function update() {
            // Clear canvas with structural color
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            // Draw Background Grid/Details
            ctx.strokeStyle = 'rgba(255, 255, 255, 0.05)';
            ctx.lineWidth = 1;
            for(let i = 0; i < canvas.width; i += 40) {
                ctx.beginPath();
                ctx.moveTo(i - (score * GAME_SPEED % 40), 0);
                ctx.lineTo(i - (score * GAME_SPEED % 40), FLOOR_Y);
                ctx.stroke();
            }

            // Draw Ground Floor
            ctx.fillStyle = '#0d021a';
            ctx.fillRect(0, FLOOR_Y, canvas.width, canvas.height - FLOOR_Y);
            ctx.strokeStyle = '#00e676';
            ctx.lineWidth = 4;
            ctx.beginPath();
            ctx.moveTo(0, FLOOR_Y);
            ctx.lineTo(canvas.width, FLOOR_Y);
            ctx.stroke();

            handleParticles();

            if (gameState === 'PLAYING') {
                // Physics Calculations
                player.vy += GRAVITY;
                player.y += player.vy;

                // Ground Check
                if (player.y >= FLOOR_Y - player.h) {
                    player.y = FLOOR_Y - player.h;
                    player.vy = 0;
                    player.isGrounded = true;
                    // Snap rotation to nearest 90 degrees when touching ground
                    player.rotation = Math.round(player.rotation / (Math.PI / 2)) * (Math.PI / 2);
                } else {

Editor is loading...
Leave a Comment