Push-Up Peaktastic

copy code

Push-Up Peaktastic

CODE:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Bounce Ascent</title>
    <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
    <style>
        .bounceascent7845-body {
            font-family: 'Roboto', sans-serif;
            margin: 0;
            padding: 0;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            color: #ffffff;
        }
        .bounceascent7845-game-container {
            display: flex;
            flex-direction: column;
            align-items: center;
        }
        .bounceascent7845-game-area {
            width: 90vw;
            max-width: 600px;
            height: 80vh;
            background: rgba(255, 255, 255, 0.1);
            border-radius: 20px;
            position: relative;
            overflow: hidden;
            box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
            backdrop-filter: blur(5px);
        }
        .bounceascent7845-platform {
            width: 100px;
            height: 20px;
            background: linear-gradient(90deg, #00d2ff 0%, #3a7bd5 100%);
            position: absolute;
            border-radius: 10px;
            cursor: move;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            transition: box-shadow 0.3s ease;
        }
        .bounceascent7845-platform:hover {
            box-shadow: 0 6px 8px rgba(0, 0, 0, 0.2);
        }
        .bounceascent7845-object {
            position: absolute;
            font-size: 24px;
            color: #FFD700;
            text-shadow: 0 0 10px rgba(255, 215, 0, 0.7);
            will-change: transform;
        }
        .bounceascent7845-controls {
            margin-top: 20px;
            display: flex;
            gap: 20px;
        }
        .bounceascent7845-button {
            padding: 10px 20px;
            font-size: 16px;
            cursor: pointer;
            background: linear-gradient(90deg, #4facfe 0%, #00f2fe 100%);
            color: white;
            border: none;
            border-radius: 50px;
            transition: transform 0.3s ease, box-shadow 0.3s ease;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        }
        .bounceascent7845-button:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 8px rgba(0, 0, 0, 0.2);
        }
        .bounceascent7845-stats {
            font-size: 16px;
            font-weight: bold;
            margin-bottom: 10px;
            display: flex;
            justify-content: space-between;
            width: 90vw;
            max-width: 600px;
        }
        .bounceascent7845-instructions {
            position: absolute;
            top: 10px;
            left: 10px;
            background: rgba(255, 255, 255, 0.2);
            padding: 10px;
            border-radius: 10px;
            font-size: 14px;
            max-width: 200px;
        }
        @media (max-width: 768px) {
            .bounceascent7845-game-area {
                width: 95vw;
                height: 70vh;
            }
            .bounceascent7845-instructions {
                display: none;
            }
            .bounceascent7845-stats {
                font-size: 14px;
            }
        }
    </style>
</head>
<body class="bounceascent7845-body">
    <div class="bounceascent7845-game-container">
        <div class="bounceascent7845-stats">
            <div>Total: <span id="total">0</span></div>
            <div>Bounced up: <span id="bouncedUp">0</span></div>
            <div>% of bounced up: <span id="percentageBounced">0%</span></div>
        </div>
        <div class="bounceascent7845-game-area" id="gameArea">
            <div class="bounceascent7845-instructions">
                Drag platforms to bounce objects. Push objects above the top edge to score!
            </div>
        </div>
        <div class="bounceascent7845-controls">
            <button class="bounceascent7845-button" id="startButton">Start Game</button>
            <button class="bounceascent7845-button" id="newGameButton">New Game</button>
        </div>
    </div>

    <script>
        const gameArea = document.getElementById('gameArea');
        const totalElement = document.getElementById('total');
        const bouncedUpElement = document.getElementById('bouncedUp');
        const percentageBouncedElement = document.getElementById('percentageBounced');
        const startButton = document.getElementById('startButton');
        const newGameButton = document.getElementById('newGameButton');

        let total = 0;
        let bouncedUp = 0;
        let animationId;
        let objects = [];
        let platforms = [];
        let gameRunning = false;

        const objectIcons = ['fa-star', 'fa-heart', 'fa-bolt', 'fa-diamond', 'fa-moon'];
        const gravity = 0.2;
        const bounceCoefficient = 0.8;

        const isMobile = window.innerWidth <= 768;
        const objectSpawnRate = isMobile ? 0.01 : 0.03; // Increased by 50% for desktop
        const objectSpeed = isMobile ? 1 : 2;
        const platformCount = isMobile ? 2 : 3;
        const jumpHeightFactor = isMobile ? 0.3 : 0.6; // Doubled for desktop

        class GameObject {
            constructor(x, y, width, height) {
                this.x = x;
                this.y = y;
                this.width = width;
                this.height = height;
                this.velocityX = 0;
                this.velocityY = 0;
            }

            intersects(other) {
                return this.x < other.x + other.width &&
                       this.x + this.width > other.x &&
                       this.y < other.y + other.height &&
                       this.y + this.height > other.y;
            }
        }

        class Platform extends GameObject {
            constructor(x, y) {
                super(x, y, 100, 20);
                this.element = document.createElement('div');
                this.element.className = 'bounceascent7845-platform';
                this.element.style.left = `${x}px`;
                this.element.style.top = `${y}px`;
                gameArea.appendChild(this.element);

                this.setupDragging();
            }

            setupDragging() {
                let isDragging = false;
                let startX, startY, startLeft, startTop;

                const onMouseDown = (e) => {
                    isDragging = true;
                    startX = e.clientX || e.touches[0].clientX;
                    startY = e.clientY || e.touches[0].clientY;
                    startLeft = this.x;
                    startTop = this.y;
                    e.preventDefault();
                };

                const onMouseMove = (e) => {
                    if (!isDragging) return;
                    const x = e.clientX || e.touches[0].clientX;
                    const y = e.clientY || e.touches[0].clientY;
                    const newLeft = startLeft + x - startX;
                    const newTop = startTop + y - startY;
                    this.x = Math.max(0, Math.min(gameArea.offsetWidth - this.width, newLeft));
                    this.y = Math.max(0, Math.min(gameArea.offsetHeight - this.height, newTop));
                    this.updatePosition();
                };

                const onMouseUp = () => {
                    isDragging = false;
                };

                this.element.addEventListener('mousedown', onMouseDown);
                this.element.addEventListener('touchstart', onMouseDown);
                document.addEventListener('mousemove', onMouseMove);
                document.addEventListener('touchmove', onMouseMove);
                document.addEventListener('mouseup', onMouseUp);
                document.addEventListener('touchend', onMouseUp);
            }

            updatePosition() {
                this.element.style.left = `${this.x}px`;
                this.element.style.top = `${this.y}px`;
            }
        }

        class FallingObject extends GameObject {
            constructor(x) {
                super(x, -24, 24, 24);
                this.element = document.createElement('i');
                this.element.className = `bounceascent7845-object fas ${objectIcons[Math.floor(Math.random() * objectIcons.length)]}`;
                this.element.style.left = `${x}px`;
                this.element.style.top = `${this.y}px`;
                gameArea.appendChild(this.element);

                this.rotation = 0;
                this.angularVelocity = (Math.random() - 0.5) * 10;
                this.velocityX = (Math.random() - 0.5) * 4 * objectSpeed;
            }

            update() {
                this.velocityY += gravity * objectSpeed;
                this.x += this.velocityX;
                this.y += this.velocityY;
                this.rotation += this.angularVelocity;

                if (this.x < 0 || this.x + this.width > gameArea.offsetWidth) {
                    this.velocityX *= -1;
                }

                this.updatePosition();
            }

            updatePosition() {
                this.element.style.left = `${this.x}px`;
                this.element.style.top = `${this.y}px`;
                this.element.style.transform = `rotate(${this.rotation}deg)`;
            }

            remove() {
                gameArea.removeChild(this.element);
            }
        }

        function createPlatform() {
            const x = Math.random() * (gameArea.offsetWidth - 100);
            const y = Math.random() * (gameArea.offsetHeight - 20);
            platforms.push(new Platform(x, y));
        }

        function createObject() {
            const x = Math.random() * (gameArea.offsetWidth - 24);
            objects.push(new FallingObject(x));
            total++;
            updateStats();
        }

        function checkCollisions() {
            objects.forEach((object, index) => {
                if (object.y + object.height < 0) {
                    object.remove();
                    objects.splice(index, 1);
                    bouncedUp++;
                    updateStats();
                    return;
                }

                if (object.y > gameArea.offsetHeight) {
                    object.remove();
                    objects.splice(index, 1);
                    updateStats();
                    return;
                }

                platforms.forEach(platform => {
                    if (object.intersects(platform)) {
                        const objectBottom = object.y + object.height;
                        const platformTop = platform.y;

                        if (objectBottom >= platformTop && objectBottom <= platformTop + platform.height && object.velocityY > 0) {
                            object.y = platform.y - object.height;
                            // Adjust the bounce height using the jumpHeightFactor
                            object.velocityY = -Math.sqrt(2 * gravity * gameArea.offsetHeight * jumpHeightFactor);
                            object.velocityX += (Math.random() - 0.5) * 2;
                            object.angularVelocity = (Math.random() - 0.5) * 20;
                        }
                    }
                });
            });
        }

        function updateStats() {
            totalElement.textContent = total;
            bouncedUpElement.textContent = bouncedUp;
            const percentage = total > 0 ? ((bouncedUp / total) * 100).toFixed(2) : 0;
            percentageBouncedElement.textContent = `${percentage}%`;
        }

        function gameLoop() {
            objects.forEach(object => object.update());
            checkCollisions();

            if (Math.random() < objectSpawnRate) createObject();

            animationId = requestAnimationFrame(gameLoop);
        }

        function startGame() {
            if (!gameRunning) {
                gameRunning = true;
                total = 0;
                bouncedUp = 0;
                updateStats();
                objects.forEach(obj => obj.remove());
                objects = [];
                platforms.forEach(platform => platform.element.remove());
                platforms = [];
                for (let i = 0; i < platformCount; i++) {
                    createPlatform();
                }
                gameLoop();
            }
        }

        startButton.addEventListener('click', startGame);
        newGameButton.addEventListener('click', () => {
            cancelAnimationFrame(animationId);
            startGame();
        });
    </script>
</body>
</html>