Cosmic Bubble Pop – Interactive Adventure

Cosmic Bubble Pop – Interactive Adventure

I’ll create an incredibly satisfying digital bubble wrap experience with realistic 3D bubbles, smooth animations, and programmatically generated pop sounds. This will be a fully interactive stress-relief tool with multiple features!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Cosmic Bubble Pop - Interactive Adventure</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            overflow: hidden;
            position: relative;
            height: 100vh;
            background: #000;
        }

        /* Animated starfield background */
        .starfield {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: -1;
        }

        .star {
            position: absolute;
            background: white;
            border-radius: 50%;
            animation: twinkle 3s infinite;
        }

        @keyframes twinkle {
            0%, 100% { opacity: 0.3; }
            50% { opacity: 1; }
        }

        .shooting-star {
            position: absolute;
            width: 2px;
            height: 2px;
            background: white;
            box-shadow: 0 0 10px 2px rgba(255, 255, 255, 0.8);
            animation: shoot 3s linear infinite;
        }

        @keyframes shoot {
            from {
                transform: translateX(0) translateY(0);
                opacity: 1;
            }
            to {
                transform: translateX(-500px) translateY(300px);
                opacity: 0;
            }
        }

        /* Main game container */
        .game-container {
            position: relative;
            width: 100%;
            height: 100vh;
            display: flex;
            flex-direction: column;
        }

        /* Header with stats */
        header {
            background: rgba(0, 0, 0, 0.7);
            backdrop-filter: blur(10px);
            padding: 1rem 2rem;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
            z-index: 100;
            position: relative;
            border-bottom: 2px solid rgba(255, 255, 255, 0.1);
        }

        .header-content {
            max-width: 1400px;
            margin: 0 auto;
            display: flex;
            justify-content: space-between;
            align-items: center;
            flex-wrap: wrap;
            gap: 1rem;
        }

        h1 {
            font-size: 2rem;
            background: linear-gradient(135deg, #ff6ec7, #7873ff, #4fc3f7);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            background-clip: text;
            display: flex;
            align-items: center;
            gap: 0.5rem;
            text-shadow: 0 0 20px rgba(255, 110, 199, 0.5);
        }

        .stats {
            display: flex;
            gap: 2rem;
            align-items: center;
        }

        .stat-item {
            display: flex;
            flex-direction: column;
            align-items: center;
            position: relative;
        }

        .stat-value {
            font-size: 2rem;
            font-weight: bold;
            background: linear-gradient(135deg, #ff6ec7, #7873ff);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            background-clip: text;
            transition: transform 0.3s ease;
        }

        .stat-value.pop-animation {
            animation: statPop 0.3s ease;
        }

        @keyframes statPop {
            0%, 100% { transform: scale(1); }
            50% { transform: scale(1.3); }
        }

        .stat-label {
            font-size: 0.875rem;
            color: rgba(255, 255, 255, 0.7);
            text-transform: uppercase;
            letter-spacing: 1px;
        }

        .combo-indicator {
            position: absolute;
            top: -30px;
            left: 50%;
            transform: translateX(-50%);
            background: linear-gradient(135deg, #ff6ec7, #7873ff);
            color: white;
            padding: 0.25rem 0.75rem;
            border-radius: 20px;
            font-size: 0.875rem;
            font-weight: bold;
            opacity: 0;
            transition: opacity 0.3s ease;
        }

        .combo-indicator.active {
            opacity: 1;
            animation: pulse 0.5s ease infinite;
        }

        @keyframes pulse {
            0%, 100% { transform: translateX(-50%) scale(1); }
            50% { transform: translateX(-50%) scale(1.1); }
        }

        .controls {
            display: flex;
            gap: 1rem;
            flex-wrap: wrap;
        }

        button {
            padding: 0.75rem 1.5rem;
            border: none;
            border-radius: 50px;
            font-size: 1rem;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s ease;
            position: relative;
            overflow: hidden;
        }

        .btn-primary {
            background: linear-gradient(135deg, #ff6ec7, #7873ff);
            color: white;
            box-shadow: 0 4px 15px rgba(255, 110, 199, 0.4);
        }

        .btn-secondary {
            background: rgba(255, 255, 255, 0.1);
            color: white;
            border: 2px solid rgba(255, 255, 255, 0.3);
            backdrop-filter: blur(5px);
        }

        .btn-power {
            background: linear-gradient(135deg, #ffd700, #ffed4e);
            color: #333;
            box-shadow: 0 4px 15px rgba(255, 215, 0, 0.4);
        }

        button:hover {
            transform: translateY(-2px);
            box-shadow: 0 10px 20px rgba(0, 0, 0, 0.3);
        }

        button:active {
            transform: translateY(0);
        }

        /* Power-up indicator */
        .power-up-indicator {
            position: fixed;
            top: 100px;
            left: 50%;
            transform: translateX(-50%);
            background: linear-gradient(135deg, #ffd700, #ffed4e);
            color: #333;
            padding: 1rem 2rem;
            border-radius: 50px;
            font-weight: bold;
            font-size: 1.2rem;
            box-shadow: 0 10px 30px rgba(255, 215, 0, 0.5);
            opacity: 0;
            transition: opacity 0.3s ease;
            z-index: 200;
        }

        .power-up-indicator.active {
            opacity: 1;
            animation: powerUpPulse 1s ease infinite;
        }

        @keyframes powerUpPulse {
            0%, 100% { transform: translateX(-50%) scale(1); }
            50% { transform: translateX(-50%) scale(1.05); }
        }

        /* Bubble container */
        .bubble-container {
            flex: 1;
            padding: 2rem;
            display: flex;
            justify-content: center;
            align-items: center;
            position: relative;
            overflow: hidden;
        }

        .bubble-wrap {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(60px, 1fr));
            gap: 8px;
            max-width: 1200px;
            width: 100%;
            padding: 2rem;
            background: rgba(255, 255, 255, 0.05);
            border-radius: 20px;
            backdrop-filter: blur(5px);
            border: 1px solid rgba(255, 255, 255, 0.1);
        }

        .bubble {
            width: 60px;
            height: 60px;
            border-radius: 50%;
            cursor: pointer;
            transition: all 0.3s ease;
            position: relative;
            animation: bubbleAppear 0.5s ease;
        }

        /* Regular bubble */
        .bubble.regular {
            background: radial-gradient(circle at 30% 30%, 
                rgba(255, 255, 255, 0.9) 0%, 
                rgba(255, 255, 255, 0.7) 10%, 
                rgba(200, 230, 255, 0.8) 30%, 
                rgba(150, 200, 255, 0.6) 60%, 
                rgba(100, 150, 255, 0.4) 100%);
            box-shadow: 
                inset -5px -5px 10px rgba(0, 0, 0, 0.1),
                inset 5px 5px 10px rgba(255, 255, 255, 0.5),
                0 5px 15px rgba(100, 150, 255, 0.3);
        }

        /* Rainbow bubble - special */
        .bubble.rainbow {
            background: linear-gradient(135deg, 
                #ff0000 0%, 
                #ff7f00 14%, 
                #ffff00 28%, 
                #00ff00 42%, 
                #0000ff 56%, 
                #4b0082 70%, 
                #9400d3 84%, 
                #ff0000 100%);
            background-size: 400% 400%;
            animation: rainbowFlow 3s ease infinite;
            box-shadow: 
                inset -5px -5px 10px rgba(0, 0, 0, 0.3),
                inset 5px 5px 10px rgba(255, 255, 255, 0.4),
                0 5px 20px rgba(255, 0, 255, 0.5);
        }

        @keyframes rainbowFlow {
            0% { background-position: 0% 50%; }
            50% { background-position: 100% 50%; }
            100% { background-position: 0% 50%; }
        }

        /* Golden bubble - bonus points */
        .bubble.golden {
            background: radial-gradient(circle at 30% 30%, 
                #fff8dc 0%, 
                #ffd700 20%, 
                #ffb347 50%, 
                #ff8c00 100%);
            box-shadow: 
                inset -5px -5px 10px rgba(0, 0, 0, 0.2),
                inset 5px 5px 10px rgba(255, 255, 255, 0.5),
                0 5px 20px rgba(255, 215, 0, 0.6);
        }

        .bubble.golden::after {
            content: '★';
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            font-size: 1.5rem;
            color: #fff;
            text-shadow: 0 0 10px rgba(255, 215, 0, 0.8);
        }

        /* Cosmic bubble - special effect */
        .bubble.cosmic {
            background: radial-gradient(circle at 30% 30%, 
                #e0b0ff 0%, 
                #9370db 20%, 
                #6a0dad 50%, 
                #4b0082 100%);
            box-shadow: 
                inset -5px -5px 10px rgba(0, 0, 0, 0.3),
                inset 5px 5px 10px rgba(255, 255, 255, 0.3),
                0 5px 20px rgba(147, 112, 219, 0.6);
        }

        .bubble.cosmic::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            border-radius: 50%;
            background: radial-gradient(circle at 70% 70%, 
                rgba(255, 255, 255, 0.8) 0%, 
                transparent 30%);
            animation: cosmicPulse 2s ease infinite;
        }

        @keyframes cosmicPulse {
            0%, 100% { transform: scale(1); opacity: 0.7; }
            50% { transform: scale(1.1); opacity: 1; }
        }

        /* Explosive bubble - chain reaction */
        .bubble.explosive {
            background: radial-gradient(circle at 30% 30%, 
                #ff6b6b 0%, 
                #ff4444 20%, 
                #cc0000 50%, 
                #990000 100%);
            box-shadow: 
                inset -5px -5px 10px rgba(0, 0, 0, 0.3),
                inset 5px 5px 10px rgba(255, 255, 255, 0.3),
                0 5px 20px rgba(255, 0, 0, 0.6);
        }

        .bubble.explosive::after {
            content: '💥';
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            font-size: 1.2rem;
        }

        @keyframes bubbleAppear {
            from {
                transform: scale(0);
                opacity: 0;
            }
            to {
                transform: scale(1);
                opacity: 1;
            }
        }

        .bubble::before {
            content: '';
            position: absolute;
            top: 10%;
            left: 20%;
            width: 30%;
            height: 30%;
            background: radial-gradient(circle, 
                rgba(255, 255, 255, 0.9) 0%, 
                transparent 70%);
            border-radius: 50%;
        }

        .bubble:hover {
            transform: scale(1.1);
        }

        .bubble.popping {
            animation: pop 0.4s ease forwards;
        }

        @keyframes pop {
            0% {
                transform: scale(1);
            }
            50% {
                transform: scale(1.3);
                opacity: 0.8;
            }
            100% {
                transform: scale(0);
                opacity: 0;
            }
        }

        .bubble.regenerating {
            animation: regenerate 0.5s ease forwards;
        }

        @keyframes regenerate {
            from {
                transform: scale(0);
                opacity: 0;
            }
            to {
                transform: scale(1);
                opacity: 1;
            }
        }

        /* Screen shake effect */
        .screen-shake {
            animation: shake 0.5s ease;
        }

        @keyframes shake {
            0%, 100% { transform: translateX(0); }
            10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
            20%, 40%, 60%, 80% { transform: translateX(5px); }
        }

        /* Particle effects */
        .particle {
            position: absolute;
            width: 8px;
            height: 8px;
            border-radius: 50%;
            pointer-events: none;
            animation: particleFly 1s ease-out forwards;
        }

        @keyframes particleFly {
            from {
                transform: translate(0, 0) scale(1);
                opacity: 1;
            }
            to {
                transform: translate(var(--tx), var(--ty)) scale(0);
                opacity: 0;
            }
        }

        /* Ripple effect */
        .ripple {
            position: absolute;
            border-radius: 50%;
            pointer-events: none;
            animation: rippleEffect 0.6s ease-out forwards;
        }

        @keyframes rippleEffect {
            from {
                width: 0;
                height: 0;
                opacity: 1;
            }
            to {
                width: 100px;
                height: 100px;
                opacity: 0;
            }
        }

        /* Floating text */
        .floating-text {
            position: absolute;
            font-weight: bold;
            font-size: 1.5rem;
            color: white;
            text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
            pointer-events: none;
            animation: floatUp 1s ease-out forwards;
        }

        @keyframes floatUp {
            from {
                transform: translateY(0);
                opacity: 1;
            }
            to {
                transform: translateY(-50px);
                opacity: 0;
            }
        }

        /* Chain reaction effect */
        .chain-reaction {
            position: absolute;
            width: 100px;
            height: 100px;
            border-radius: 50%;
            background: radial-gradient(circle, 
                rgba(255, 100, 100, 0.8) 0%, 
                transparent 70%);
            pointer-events: none;
            animation: chainReaction 0.5s ease-out forwards;
        }

        @keyframes chainReaction {
            from {
                transform: scale(0);
                opacity: 1;
            }
            to {
                transform: scale(3);
                opacity: 0;
            }
        }

        /* Settings panel */
        .settings-panel {
            position: fixed;
            right: -300px;
            top: 50%;
            transform: translateY(-50%);
            width: 280px;
            background: rgba(0, 0, 0, 0.8);
            backdrop-filter: blur(10px);
            border-radius: 20px 0 0 20px;
            box-shadow: -5px 0 20px rgba(0, 0, 0, 0.5);
            padding: 2rem;
            transition: right 0.3s ease;
            z-index: 200;
            border: 1px solid rgba(255, 255, 255, 0.1);
        }

        .settings-panel.open {
            right: 0;
        }

        .settings-toggle {
            position: absolute;
            left: -40px;
            top: 50%;
            transform: translateY(-50%);
            width: 40px;
            height: 80px;
            background: rgba(0, 0, 0, 0.8);
            border-radius: 10px 0 0 10px;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            box-shadow: -3px 0 10px rgba(0, 0, 0, 0.3);
            color: white;
        }

        .setting-item {
            margin-bottom: 1.5rem;
        }

        .setting-label {
            display: block;
            margin-bottom: 0.5rem;
            font-weight: 600;
            color: white;
        }

        input[type="range"] {
            width: 100%;
            height: 6px;
            border-radius: 3px;
            background: rgba(255, 255, 255, 0.2);
            outline: none;
            -webkit-appearance: none;
        }

        input[type="range"]::-webkit-slider-thumb {
            -webkit-appearance: none;
            appearance: none;
            width: 20px;
            height: 20px;
            border-radius: 50%;
            background: linear-gradient(135deg, #ff6ec7, #7873ff);
            cursor: pointer;
        }

        input[type="range"]::-moz-range-thumb {
            width: 20px;
            height: 20px;
            border-radius: 50%;
            background: linear-gradient(135deg, #ff6ec7, #7873ff);
            cursor: pointer;
            border: none;
        }

        .checkbox-wrapper {
            display: flex;
            align-items: center;
            gap: 0.5rem;
        }

        input[type="checkbox"] {
            width: 20px;
            height: 20px;
            cursor: pointer;
        }

        /* Achievement notification */
        .achievement {
            position: fixed;
            top: 100px;
            right: -400px;
            background: rgba(0, 0, 0, 0.8);
            backdrop-filter: blur(10px);
            padding: 1.5rem;
            border-radius: 15px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
            display: flex;
            align-items: center;
            gap: 1rem;
            transition: right 0.5s ease;
            z-index: 300;
            border: 1px solid rgba(255, 255, 255, 0.2);
        }

        .achievement.show {
            right: 20px;
        }

        .achievement-icon {
            font-size: 2rem;
        }

        .achievement-text h3 {
            color: #ff6ec7;
            margin-bottom: 0.25rem;
        }

        .achievement-text p {
            color: rgba(255, 255, 255, 0.8);
            font-size: 0.875rem;
        }

        /* Power-up bar */
        .power-up-bar {
            position: fixed;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%);
            display: flex;
            gap: 1rem;
            padding: 1rem;
            background: rgba(0, 0, 0, 0.7);
            backdrop-filter: blur(10px);
            border-radius: 50px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
            z-index: 100;
        }

        .power-up-slot {
            width: 60px;
            height: 60px;
            border-radius: 50%;
            background: rgba(255, 255, 255, 0.1);
            border: 2px solid rgba(255, 255, 255, 0.3);
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 1.5rem;
            cursor: pointer;
            transition: all 0.3s ease;
        }

        .power-up-slot.active {
            background: linear-gradient(135deg, #ffd700, #ffed4e);
            border-color: #ffd700;
            animation: powerUpGlow 1s ease infinite;
        }

        @keyframes powerUpGlow {
            0%, 100% { box-shadow: 0 0 10px rgba(255, 215, 0, 0.5); }
            50% { box-shadow: 0 0 20px rgba(255, 215, 0, 0.8); }
        }

        .power-up-slot:hover {
            transform: scale(1.1);
        }

        @media (max-width: 768px) {
            h1 {
                font-size: 1.5rem;
            }
            
            .bubble {
                width: 50px;
                height: 50px;
            }
            
            .bubble-wrap {
                gap: 6px;
                padding: 1rem;
            }
            
            .settings-panel {
                width: 250px;
            }
            
            .power-up-bar {
                bottom: 10px;
                padding: 0.5rem;
            }
            
            .power-up-slot {
                width: 50px;
                height: 50px;
                font-size: 1.2rem;
            }
        }
    </style>
</head>
<body>
    <!-- Animated starfield background -->
    <div class="starfield" id="starfield"></div>

    <div class="game-container">
        <header>
            <div class="header-content">
                <h1>
                    <span>🌌</span>
                    Cosmic Bubble Pop
                </h1>
                <div class="stats">
                    <div class="stat-item">
                        <div class="combo-indicator" id="comboIndicator">COMBO x2</div>
                        <div class="stat-value" id="popCount">0</div>
                        <div class="stat-label">Popped</div>
                    </div>
                    <div class="stat-item">
                        <div class="stat-value" id="scoreCount">0</div>
                        <div class="stat-label">Score</div>
                    </div>
                    <div class="stat-item">
                        <div class="stat-value" id="highScore">0</div>
                        <div class="stat-label">Best</div>
                    </div>
                </div>
                <div class="controls">
                    <button class="btn-primary" onclick="resetBubbles()">
                        🔄 Reset
                    </button>
                    <button class="btn-power" onclick="activatePowerUp()">
                        ⚡ Power-Up
                    </button>
                    <button class="btn-secondary" onclick="toggleSound()">
                        🔊 Sound: <span id="soundStatus">ON</span>
                    </button>
                </div>
            </div>
        </header>

        <main class="bubble-container" id="gameContainer">
            <div class="bubble-wrap" id="bubbleWrap"></div>
        </main>

        <!-- Power-up indicator -->
        <div class="power-up-indicator" id="powerUpIndicator">
            POWER-UP ACTIVE!
        </div>

        <!-- Power-up bar -->
        <div class="power-up-bar">
            <div class="power-up-slot" id="powerUp1" onclick="usePowerUp(1)">❄️</div>
            <div class="power-up-slot" id="powerUp2" onclick="usePowerUp(2)">⚡</div>
            <div class="power-up-slot" id="powerUp3" onclick="usePowerUp(3)">🌟</div>
            <div class="power-up-slot" id="powerUp4" onclick="usePowerUp(4)">💎</div>
        </div>

        <!-- Settings panel -->
        <div class="settings-panel" id="settingsPanel">
            <div class="settings-toggle" onclick="toggleSettings()">
                ⚙️
            </div>
            <h3 style="margin-bottom: 1.5rem; color: white;">Settings</h3>
            
            <div class="setting-item">
                <label class="setting-label">Bubble Size</label>
                <input type="range" id="bubbleSize" min="40" max="80" value="60" 
                       oninput="updateBubbleSize(this.value)">
                <span id="sizeValue" style="color: rgba(255, 255, 255, 0.7);">60px</span>
            </div>
            
            <div class="setting-item">
                <label class="setting-label">Pop Volume</label>
                <input type="range" id="volume" min="0" max="100" value="50" 
                       oninput="updateVolume(this.value)">
                <span id="volumeValue" style="color: rgba(255, 255, 255, 0.7);">50%</span>
            </div>
            
            <div class="setting-item">
                <label class="setting-label">Special Bubble Chance</label>
                <input type="range" id="specialChance" min="0" max="50" value="20" 
                       oninput="updateSpecialChance(this.value)">
                <span id="specialValue" style="color: rgba(255, 255, 255, 0.7);">20%</span>
            </div>
            
            <div class="setting-item">
                <label class="setting-label">Screen Shake</label>
                <div class="checkbox-wrapper">
                    <input type="checkbox" id="screenShake" checked 
                           onchange="toggleScreenShake(this.checked)">
                    <label for="screenShake" style="color: rgba(255, 255, 255, 0.7);">Enable</label>
                </div>
            </div>
            
            <div class="setting-item">
                <label class="setting-label">Auto Regenerate</label>
                <div class="checkbox-wrapper">
                    <input type="checkbox" id="autoRegenerate" checked 
                           onchange="toggleAutoRegenerate(this.checked)">
                    <label for="autoRegenerate" style="color: rgba(255, 255, 255, 0.7);">Enable</label>
                </div>
            </div>
        </div>

        <!-- Achievement notification -->
        <div class="achievement" id="achievement">
            <div class="achievement-icon">🏆</div>
            <div class="achievement-text">
                <h3 id="achievementTitle">Achievement!</h3>
                <p id="achievementDesc">You've popped 100 bubbles!</p>
            </div>
        </div>
    </div>

    <script>
        // Game variables
        let audioContext;
        let soundEnabled = true;
        let volume = 0.5;
        let bubbleSize = 60;
        let specialChance = 0.2;
        let screenShakeEnabled = true;
        let autoRegenerate = true;
        
        // Game stats
        let popCount = 0;
        let score = 0;
        let highScore = localStorage.getItem('cosmicHighScore') || 0;
        let combo = 0;
        let lastPopTime = 0;
        let powerUpActive = false;
        let powerUpType = null;
        let powerUpTimer = null;
        
        // Power-up states
        let powerUps = {
            1: { name: 'Freeze', icon: '❄️', active: false, cooldown: 0 },
            2: { name: 'Lightning', icon: '⚡', active: false, cooldown: 0 },
            3: { name: 'Starburst', icon: '🌟', active: false, cooldown: 0 },
            4: { name: 'Diamond', icon: '💎', active: false, cooldown: 0 }
        };
        
        // Initialize starfield
        function createStarfield() {
            const starfield = document.getElementById('starfield');
            const starCount = 200;
            
            for (let i = 0; i < starCount; i++) {
                const star = document.createElement('div');
                star.className = 'star';
                star.style.width = Math.random() * 3 + 'px';
                star.style.height = star.style.width;
                star.style.left = Math.random() * 100 + '%';
                star.style.top = Math.random() * 100 + '%';
                star.style.animationDelay = Math.random() * 3 + 's';
                starfield.appendChild(star);
            }
            
            // Create shooting stars
            setInterval(() => {
                if (Math.random() > 0.7) {
                    const shootingStar = document.createElement('div');
                    shootingStar.className = 'shooting-star';
                    shootingStar.style.left = Math.random() * 100 + '%';
                    shootingStar.style.top = Math.random() * 50 + '%';
                    starfield.appendChild(shootingStar);
                    
                    setTimeout(() => {
                        shootingStar.remove();
                    }, 3000);
                }
            }, 2000);
        }
        
        // Initialize audio context
        function initAudio() {
            if (!audioContext) {
                audioContext = new (window.AudioContext || window.webkitAudioContext)();
            }
        }
        
        // Generate pop sound with pitch variation
        function playPopSound(bubbleType = 'regular') {
            if (!soundEnabled || !audioContext) return;
            
            const oscillator = audioContext.createOscillator();
            const gainNode = audioContext.createGain();
            
            oscillator.connect(gainNode);
            gainNode.connect(audioContext.destination);
            
            // Different pitch for different bubble types
            const baseFreq = {
                'regular': 200,
                'rainbow': 400,
                'golden': 300,
                'cosmic': 150,
                'explosive': 250
            };
            
            oscillator.frequency.setValueAtTime(baseFreq[bubbleType] || 200, audioContext.currentTime);
            oscillator.frequency.exponentialRampToValueAtTime(50, audioContext.currentTime + 0.1);
            
            gainNode.gain.setValueAtTime(volume, audioContext.currentTime);
            gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.1);
            
            oscillator.start(audioContext.currentTime);
            oscillator.stop(audioContext.currentTime + 0.1);
        }
        
        // Create bubble element
        function createBubble() {
            const bubble = document.createElement('div');
            bubble.className = 'bubble';
            bubble.style.width = bubbleSize + 'px';
            bubble.style.height = bubbleSize + 'px';
            
            // Determine bubble type
            let bubbleType = 'regular';
            const rand = Math.random();
            
            if (rand < specialChance) {
                const types = ['rainbow', 'golden', 'cosmic', 'explosive'];
                bubbleType = types[Math.floor(Math.random() * types.length)];
            }
            
            bubble.classList.add(bubbleType);
            bubble.dataset.type = bubbleType;
            
            bubble.addEventListener('click', function(e) {
                popBubble(this, e);
            });
            
            bubble.addEventListener('touchstart', function(e) {
                e.preventDefault();
                popBubble(this, e.touches[0]);
            });
            
            return bubble;
        }
        
        // Pop bubble
        function popBubble(bubble, event) {
            if (bubble.classList.contains('popping')) return;
            
            initAudio();
            const bubbleType = bubble.dataset.type || 'regular';
            playPopSound(bubbleType);
            
            bubble.classList.add('popping');
            
            // Update combo
            const currentTime = Date.now();
            if (currentTime - lastPopTime < 1000) {
                combo++;
                updateCombo();
            } else {
                combo = 1;
                updateCombo();
            }
            lastPopTime = currentTime;
            
            // Calculate points
            let points = 10;
            switch (bubbleType) {
                case 'rainbow':
                    points = 50;
                    createRainbowEffect(event.pageX, event.pageY);
                    break;
                case 'golden':
                    points = 30;
                    createGoldenEffect(event.pageX, event.pageY);
                    break;
                case 'cosmic':
                    points = 40;
                    createCosmicEffect(event.pageX, event.pageY);
                    break;
                case 'explosive':
                    points = 20;
                    createExplosiveEffect(bubble, event.pageX, event.pageY);
                    break;
                default:
                    createRegularEffect(event.pageX, event.pageY);
            }
            
            // Apply combo multiplier
            points *= combo;
            score += points;
            
            // Update stats
            popCount++;
            updateStat('popCount', popCount);
            updateStat('scoreCount', score);
            
            // Update high score
            if (score > highScore) {
                highScore = score;
                localStorage.setItem('cosmicHighScore', highScore);
                updateStat('highScore', highScore);
            }
            
            // Create floating text
            createFloatingText(event.pageX, event.pageY, `+${points}`);
            
            // Check achievements
            checkAchievements();
            
            // Regenerate bubble
            if (autoRegenerate) {
                setTimeout(() => {
                    bubble.classList.remove('popping');
                    bubble.classList.add('regenerating');
                    setTimeout(() => {
                        bubble.classList.remove('regenerating');
                    }, 500);
                }, 1000);
            }
        }
        
        // Update combo display
        function updateCombo() {
            const indicator = document.getElementById('comboIndicator');
            if (combo > 1) {
                indicator.textContent = `COMBO x${combo}`;
                indicator.classList.add('active');
            } else {
                indicator.classList.remove('active');
            }
        }
        
        // Create regular pop effect
        function createRegularEffect(x, y) {
            createParticles(x, y, '#ffffff', 8);
            createRipple(x, y, 'rgba(255, 255, 255, 0.5)');
        }
        
        // Create rainbow effect
        function createRainbowEffect(x, y) {
            const colors = ['#ff0000', '#ff7f00', '#ffff00', '#00ff00', '#0000ff', '#4b0082', '#9400d3'];
            colors.forEach(color => {
                createParticles(x, y, color, 5);
            });
            createRipple(x, y, 'rgba(255, 0, 255, 0.7)');
            
            if (screenShakeEnabled) {
                document.body.classList.add('screen-shake');
                setTimeout(() => {
                    document.body.classList.remove('screen-shake');
                }, 500);
            }
        }
        
        // Create golden effect
        function createGoldenEffect(x, y) {
            createParticles(x, y, '#ffd700', 12);
            createRipple(x, y, 'rgba(255, 215, 0, 0.7)');
            createFloatingText(x, y, 'BONUS!');
        }
        
        // Create cosmic effect
        function createCosmicEffect(x, y) {
            createParticles(x, y, '#9370db', 10);
            createRipple(x, y, 'rgba(147, 112, 219, 0.7)');
            
            // Create additional cosmic particles
            for (let i = 0; i < 5; i++) {
                setTimeout(() => {
                    const px = x + (Math.random() - 0.5) * 100;
                    const py = y + (Math.random() - 0.5) * 100;
                    createParticles(px, py, '#e0b0ff', 3);
                }, i * 100);
            }
        }
        
        // Create explosive effect
        function createExplosiveEffect(bubble, x, y) {
            createParticles(x, y, '#ff4444', 15);
            createRipple(x, y, 'rgba(255, 0, 0, 0.7)');
            
            // Create chain reaction
            const chainReaction = document.createElement('div');
            chainReaction.className = 'chain-reaction';
            chainReaction.style.left = (x - 50) + 'px';
            chainReaction.style.top = (y - 50) + 'px';
            document.body.appendChild(chainReaction);
            
            setTimeout(() => {
                chainReaction.remove();
            }, 500);
            
            // Pop nearby bubbles
            const bubbles = document.querySelectorAll('.bubble:not(.popping)');
            const rect = bubble.getBoundingClientRect();
            
            bubbles.forEach(b => {
                const bRect = b.getBoundingClientRect();
                const distance = Math.sqrt(
                    Math.pow(rect.left - bRect.left, 2) + 
                    Math.pow(rect.top - bRect.top, 2)
                );
                
                if (distance < 150 && b !== bubble) {
                    setTimeout(() => {
                        const event = new MouseEvent('click', {
                            clientX: bRect.left + bRect.width / 2,
                            clientY: bRect.top + bRect.height / 2
                        });
                        b.dispatchEvent(event);
                    }, 100);
                }
            });
            
            if (screenShakeEnabled) {
                document.body.classList.add('screen-shake');
                setTimeout(() => {
                    document.body.classList.remove('screen-shake');
                }, 500);
            }
        }
        
        // Create particles
        function createParticles(x, y, color, count) {
            for (let i = 0; i < count; i++) {
                const particle = document.createElement('div');
                particle.className = 'particle';
                particle.style.background = color;
                
                const angle = (Math.PI * 2 * i) / count;
                const distance = 50 + Math.random() * 50;
                const tx = Math.cos(angle) * distance;
                const ty = Math.sin(angle) * distance;
                
                particle.style.setProperty('--tx', tx + 'px');
                particle.style.setProperty('--ty', ty + 'px');
                particle.style.left = x + 'px';
                particle.style.top = y + 'px';
                
                document.body.appendChild(particle);
                
                setTimeout(() => {
                    particle.remove();
                }, 1000);
            }
        }
        
        // Create ripple effect
        function createRipple(x, y, color) {
            const ripple = document.createElement('div');
            ripple.className = 'ripple';
            ripple.style.background = `radial-gradient(circle, ${color} 0%, transparent 70%)`;
            ripple.style.left = (x - 50) + 'px';
            ripple.style.top = (y - 50) + 'px';
            document.body.appendChild(ripple);
            
            setTimeout(() => {
                ripple.remove();
            }, 600);
        }
        
        // Create floating text
        function createFloatingText(x, y, text) {
            const floatingText = document.createElement('div');
            floatingText.className = 'floating-text';
            floatingText.textContent = text;
            floatingText.style.left = x + 'px';
            floatingText.style.top = y + 'px';
            document.body.appendChild(floatingText);
            
            setTimeout(() => {
                floatingText.remove();
            }, 1000);
        }
        
        // Update stat with animation
        function updateStat(statId, value) {
            const element = document.getElementById(statId);
            element.textContent = value;
            element.classList.add('pop-animation');
            setTimeout(() => {
                element.classList.remove('pop-animation');
            }, 300);
        }
        
        // Check achievements
        function checkAchievements() {
            const achievements = [
                { count: 10, title: 'First Steps!', desc: 'You popped 10 bubbles!' },
                { count: 50, title: 'Bubble Master!', desc: 'You popped 50 bubbles!' },
                { count: 100, title: 'Bubble Legend!', desc: 'You popped 100 bubbles!' },
                { count: 500, title: 'Bubble God!', desc: 'You popped 500 bubbles!' },
                { count: 1000, title: 'Unstoppable!', desc: 'You popped 1000 bubbles!' }
            ];
            
            achievements.forEach(achievement => {
                if (popCount === achievement.count) {
                    showAchievement(achievement.title, achievement.desc);
                }
            });
            
            // Score achievements
            if (score === 500) {
                showAchievement('Score Master!', 'You reached 500 points!');
            }
            if (score === 1000) {
                showAchievement('Score Legend!', 'You reached 1000 points!');
            }
            
            // Combo achievements
            if (combo === 10) {
                showAchievement('Combo King!', '10x combo achieved!');
            }
            if (combo === 20) {
                showAchievement('Combo God!', '20x combo achieved!');
            }
        }
        
        // Show achievement notification
        function showAchievement(title, desc) {
            const achievement = document.getElementById('achievement');
            document.getElementById('achievementTitle').textContent = title;
            document.getElementById('achievementDesc').textContent = desc;
            
            achievement.classList.add('show');
            setTimeout(() => {
                achievement.classList.remove('show');
            }, 3000);
        }
        
        // Activate power-up
        function activatePowerUp() {
            if (powerUpActive) return;
            
            const availablePowerUps = Object.keys(powerUps).filter(key => !powerUps[key].active && powerUps[key].cooldown === 0);
            if (availablePowerUps.length === 0) return;
            
            const randomPowerUp = availablePowerUps[Math.floor(Math.random() * availablePowerUps.length)];
            usePowerUp(parseInt(randomPowerUp));
        }
        
        // Use specific power-up
        function usePowerUp(powerUpId) {
            if (powerUps[powerUpId].active || powerUps[powerUpId].cooldown > 0) return;
            
            powerUpActive = true;
            powerUpType = powerUpId;
            powerUps[powerUpId].active = true;
            
            document.getElementById(`powerUp${powerUpId}`).classList.add('active');
            document.getElementById('powerUpIndicator').classList.add('active');
            
            // Apply power-up effect
            switch (powerUpId) {
                case 1: // Freeze
                    freezeAllBubbles();
                    break;
                case 2: // Lightning
                    lightningStrike();
                    break;
                case 3: // Starburst
                    starburst();
                    break;
                case 4: // Diamond
                    doublePoints();
                    break;
            }
            
            // Set cooldown
            setTimeout(() => {
                powerUpActive = false;
                powerUpType = null;
                powerUps[powerUpId].active = false;
                powerUps[powerUpId].cooldown = 10;
                
                document.getElementById(`powerUp${powerUpId}`).classList.remove('active');
                document.getElementById('powerUpIndicator').classList.remove('active');
                
                // Cooldown countdown
                const cooldownInterval = setInterval(() => {
                    powerUps[powerUpId].cooldown--;
                    if (powerUps[powerUpId].cooldown <= 0) {
                        clearInterval(cooldownInterval);
                    }
                }, 1000);
            }, 5000);
        }
        
        // Power-up effects
        function freezeAllBubbles() {
            const bubbles = document.querySelectorAll('.bubble:not(.popping)');
            bubbles.forEach(bubble => {
                bubble.style.animationPlayState = 'paused';
                bubble.style.filter = 'hue-rotate(200deg)';
            });
            
            setTimeout(() => {
                bubbles.forEach(bubble => {
                    bubble.style.animationPlayState = 'running';
                    bubble.style.filter = 'none';
                });
            }, 5000);
        }
        
        function lightningStrike() {
            const bubbles = document.querySelectorAll('.bubble:not(.popping)');
            const randomBubbles = Array.from(bubbles).sort(() => 0.5 - Math.random()).slice(0, 10);
            
            randomBubbles.forEach((bubble, index) => {
                setTimeout(() => {
                    const rect = bubble.getBoundingClientRect();
                    createLightningEffect(rect.left + rect.width / 2, rect.top + rect.height / 2);
                    const event = new MouseEvent('click', {
                        clientX: rect.left + rect.width / 2,
                        clientY: rect.top + rect.height / 2
                    });
                    bubble.dispatchEvent(event);
                }, index * 100);
            });
        }
        
        function createLightningEffect(x, y) {
            const lightning = document.createElement('div');
            lightning.style.position = 'absolute';
            lightning.style.left = x + 'px';
            lightning.style.top = '0px';
            lightning.style.width = '2px';
            lightning.style.height = y + 'px';
            lightning.style.background = 'linear-gradient(to bottom, transparent, #ffffff, transparent)';
            lightning.style.boxShadow = '0 0 10px #ffffff';
            lightning.style.zIndex = '1000';
            document.body.appendChild(lightning);
            
            setTimeout(() => {
                lightning.remove();
            }, 200);
        }
        
        function starburst() {
            const centerX = window.innerWidth / 2;
            const centerY = window.innerHeight / 2;
            
            for (let i = 0; i < 20; i++) {
                const angle = (Math.PI * 2 * i) / 20;
                const distance = 200 + Math.random() * 200;
                const x = centerX + Math.cos(angle) * distance;
                const y = centerY + Math.sin(angle) * distance;
                
                createParticles(x, y, '#ffff00', 5);
                createRipple(x, y, 'rgba(255, 255, 0, 0.7)');
            }
            
            if (screenShakeEnabled) {
                document.body.classList.add('screen-shake');
                setTimeout(() => {
                    document.body.classList.remove('screen-shake');
                }, 500);
            }
        }
        
        function doublePoints() {
            // Visual indicator for double points
            const indicator = document.createElement('div');
            indicator.style.position = 'fixed';
            indicator.style.top = '50%';
            indicator.style.left = '50%';
            indicator.style.transform = 'translate(-50%, -50%)';
            indicator.style.fontSize = '3rem';
            indicator.style.fontWeight = 'bold';
            indicator.style.color = '#ffd700';
            indicator.style.textShadow = '0 0 20px rgba(255, 215, 0, 0.8)';
            indicator.style.zIndex = '1000';
            indicator.textContent = '2X POINTS!';
            document.body.appendChild(indicator);
            
            setTimeout(() => {
                indicator.remove();
            }, 2000);
        }
        
        // Initialize bubbles
        function initBubbles() {
            const bubbleWrap = document.getElementById('bubbleWrap');
            const bubbleCount = window.innerWidth < 768 ? 48 : 96;
            
            for (let i = 0; i < bubbleCount; i++) {
                bubbleWrap.appendChild(createBubble());
            }
            
            // Initialize high score display
            updateStat('highScore', highScore);
        }
        
        // Reset all bubbles
        function resetBubbles() {
            const bubbleWrap = document.getElementById('bubbleWrap');
            bubbleWrap.innerHTML = '';
            popCount = 0;
            score = 0;
            combo = 0;
            updateStat('popCount', 0);
            updateStat('scoreCount', 0);
            updateCombo();
            initBubbles();
        }
        
        // Toggle sound
        function toggleSound() {
            soundEnabled = !soundEnabled;
            document.getElementById('soundStatus').textContent = soundEnabled ? 'ON' : 'OFF';
        }
        
        // Toggle settings panel
        function toggleSettings() {
            document.getElementById('settingsPanel').classList.toggle('open');
        }
        
        // Update bubble size
        function updateBubbleSize(size) {
            bubbleSize = parseInt(size);
            document.getElementById('sizeValue').textContent = size + 'px';
            
            const bubbles = document.querySelectorAll('.bubble');
            bubbles.forEach(bubble => {
                bubble.style.width = size + 'px';
                bubble.style.height = size + 'px';
            });
        }
        
        // Update volume
        function updateVolume(value) {
            volume = value / 100;
            document.getElementById('volumeValue').textContent = value + '%';
        }
        
        // Update special chance
        function updateSpecialChance(value) {
            specialChance = value / 100;
            document.getElementById('specialValue').textContent = value + '%';
        }
        
        // Toggle screen shake
        function toggleScreenShake(enabled) {
            screenShakeEnabled = enabled;
        }
        
        // Toggle auto regenerate
        function toggleAutoRegenerate(enabled) {
            autoRegenerate = enabled;
        }
        
        // Initialize on load
        window.addEventListener('load', () => {
            createStarfield();
            initBubbles();
        });
        
        // Handle window resize
        window.addEventListener('resize', () => {
            const bubbleWrap = document.getElementById('bubbleWrap');
            const currentBubbles = bubbleWrap.children.length;
            const targetBubbles = window.innerWidth < 768 ? 48 : 96;
            
            if (currentBubbles < targetBubbles) {
                for (let i = currentBubbles; i < targetBubbles; i++) {
                    bubbleWrap.appendChild(createBubble());
                }
            }
        });
    </script>
</body>
</html>

The pen URL is invalid.

The pen URL is invalid.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *