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.

Instagram Feed

This error message is only visible to WordPress admins

Error: No feed found.

Please go to the Instagram Feed settings page to create a feed.

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 *