// Game State const game = { personalScore: parseInt(localStorage.getItem('personalScore')) || 0, globalScore: parseInt(localStorage.getItem('globalCookieScore')) || 0, destroyerHunger: parseInt(localStorage.getItem('destroyerHunger')) || 50, currentSkin: localStorage.getItem('currentSkin') || 'default', unlockedSkins: JSON.parse(localStorage.getItem('unlockedSkins')) || ['default'], playerCountry: localStorage.getItem('playerCountry') || null, countryScores: JSON.parse(localStorage.getItem('countryScores')) || {}, orbitAngle: 0, orbitSpeed: 3, // degrees per frame multiplier: 1, specialEffectUnlocked: false, lastTime: 0 }; // Country Data with Emoji Flags const countries = [ { code: 'US', name: 'United States', flag: '🇺🇸' }, { code: 'CN', name: 'China', flag: '🇨🇳' }, { code: 'JP', name: 'Japan', flag: '🇯🇵' }, { code: 'DE', name: 'Germany', flag: '🇩🇪' }, { code: 'GB', name: 'United Kingdom', flag: '🇬🇧' }, { code: 'FR', name: 'France', flag: '🇫🇷' }, { code: 'IN', name: 'India', flag: '🇮🇳' }, { code: 'BR', name: 'Brazil', flag: '🇧🇷' }, { code: 'RU', name: 'Russia', flag: '🇷🇺' }, { code: 'KR', name: 'South Korea', flag: '🇰🇷' }, { code: 'CA', name: 'Canada', flag: '🇨🇦' }, { code: 'AU', name: 'Australia', flag: '🇦🇺' }, { code: 'IT', name: 'Italy', flag: '🇮🇹' }, { code: 'ES', name: 'Spain', flag: '🇪🇸' }, { code: 'MX', name: 'Mexico', flag: '🇲🇽' }, { code: 'NL', name: 'Netherlands', flag: '🇳🇱' } ]; // DOM Elements const elements = { personalScore: document.getElementById('personalScore'), globalScore: document.getElementById('globalScore'), destroyerHunger: document.getElementById('destroyerHunger'), hungerPercent: document.getElementById('hungerPercent'), cookieBtn: document.getElementById('cookieBtn'), cookieVisual: document.getElementById('cookieVisual'), orbitIndicator: document.getElementById('orbitIndicator'), multiplierBadge: document.getElementById('multiplierBadge'), multiplierText: document.getElementById('multiplierText'), feedDestroyerBtn: document.getElementById('feedDestroyerBtn'), warningOverlay: document.getElementById('warningOverlay'), resetModal: document.getElementById('resetModal'), dismissReset: document.getElementById('dismissReset'), floatingText: document.getElementById('floatingText'), particles: document.getElementById('particles'), skinsGrid: document.getElementById('skinsGrid'), countryModal: document.getElementById('countryModal'), countryGrid: document.getElementById('countryGrid'), playerCountry: document.getElementById('playerCountry'), leaderboardList: document.getElementById('leaderboardList') }; // Skin Definitions const skins = { default: { class: 'cookie-skin-default', name: 'Classic' }, chocolate: { class: 'cookie-skin-chocolate', name: 'Chocolate' }, golden: { class: 'cookie-skin-golden', name: 'Golden' }, galaxy: { class: 'cookie-skin-galaxy', name: 'Galaxy' }, radioactive: { class: 'cookie-skin-radioactive', name: 'Radioactive' }, cosmic: { class: 'cookie-skin-cosmic', name: 'Cosmic' }, void: { class: 'cookie-skin-void', name: 'Void' } }; // Initialize Game function init() { if (!game.playerCountry) { showCountrySelection(); } else { elements.playerCountry.textContent = getCountryFlag(game.playerCountry); updateMultiplier(); applySkin(game.currentSkin); updateUI(); startOrbitLoop(); startDestroyerLoop(); setupEventListeners(); checkSkinsAvailability(); updateLeaderboard(); if (game.destroyerHunger <= 0) { showResetModal(); } } } // Country Selection function showCountrySelection() { elements.countryModal.classList.remove('hidden'); elements.countryGrid.innerHTML = countries.map(c => ` `).join(''); document.querySelectorAll('.country-btn').forEach(btn => { btn.addEventListener('click', () => { selectCountry(btn.dataset.code); }); }); } function selectCountry(code) { game.playerCountry = code; localStorage.setItem('playerCountry', code); // Initialize country score if not exists if (!game.countryScores[code]) { game.countryScores[code] = 0; localStorage.setItem('countryScores', JSON.stringify(game.countryScores)); } elements.countryModal.classList.add('hidden'); elements.playerCountry.textContent = getCountryFlag(code); updateMultiplier(); applySkin(game.currentSkin); updateUI(); startOrbitLoop(); startDestroyerLoop(); setupEventListeners(); checkSkinsAvailability(); updateLeaderboard(); } function getCountryFlag(code) { const country = countries.find(c => c.code === code); return country ? country.flag : '🌍'; } // Orbit/Timing Mechanic Loop function startOrbitLoop() { function animate(currentTime) { // Update orbit angle game.orbitAngle += game.orbitSpeed; if (game.orbitAngle >= 360) game.orbitAngle = 0; // Calculate position (120px radius from center) const radius = 120; const centerX = 144; // half of 288 (w-72) const centerY = 144; const angleRad = (game.orbitAngle * Math.PI) / 180; const x = centerX + radius * Math.cos(angleRad); const y = centerY + radius * Math.sin(angleRad); elements.orbitIndicator.style.left = x + 'px'; elements.orbitIndicator.style.top = y + 'px'; // Visual cue when approaching top (perfect zone) // Top is at angle 270 degrees (or -90) const distanceFromTop = Math.abs(((game.orbitAngle + 90) % 360)); const normalizedDist = distanceFromTop > 180 ? 360 - distanceFromTop : distanceFromTop; if (normalizedDist < 20) { elements.orbitIndicator.style.backgroundColor = '#4ade80'; // Green elements.orbitIndicator.style.transform = 'translate(-50%, -50%) scale(1.3)'; } else if (normalizedDist < 45) { elements.orbitIndicator.style.backgroundColor = '#60a5fa'; // Blue elements.orbitIndicator.style.transform = 'translate(-50%, -50%) scale(1.1)'; } else { elements.orbitIndicator.style.backgroundColor = '#ffffff'; // White elements.orbitIndicator.style.transform = 'translate(-50%, -50%) scale(1)'; } requestAnimationFrame(animate); } requestAnimationFrame(animate); } // Calculate timing bonus based on orbit position function getTimingBonus() { // Top is at 270 degrees (or -90), which is where the perfect zone is const distanceFromTop = Math.abs(((game.orbitAngle + 90) % 360)); const normalizedDist = distanceFromTop > 180 ? 360 - distanceFromTop : distanceFromTop; if (normalizedDist <= 10) { return { multiplier: 5, text: 'PERFECT!', color: '#4ade80', class: 'timing-perfect' }; } else if (normalizedDist <= 25) { return { multiplier: 3, text: 'GREAT!', color: '#60a5fa', class: 'timing-great' }; } else if (normalizedDist <= 45) { return { multiplier: 2, text: 'GOOD', color: '#fbbf24', class: 'timing-good' }; } else { return { multiplier: 1, text: 'MISS', color: '#f87171', class: '' }; } } // Click Handler function handleCookieClick(e) { e.preventDefault(); const timing = getTimingBonus(); const baseGain = game.multiplier; const totalGain = baseGain * timing.multiplier; // Update personal score game.personalScore += totalGain; // Update global score game.globalScore += totalGain; // Update country score if (game.playerCountry) { game.countryScores[game.playerCountry] = (game.countryScores[game.playerCountry] || 0) + totalGain; } // Save all localStorage.setItem('personalScore', game.personalScore); localStorage.setItem('globalCookieScore', game.globalScore); localStorage.setItem('countryScores', JSON.stringify(game.countryScores)); // Visual feedback showFloatingText(totalGain, timing.text, timing.color); createParticles(timing.multiplier); // Apply timing glow to cookie elements.cookieVisual.className = elements.cookieVisual.className.replace(/timing-\w+/g, ''); if (timing.class) { elements.cookieVisual.classList.add(timing.class); setTimeout(() => { elements.cookieVisual.classList.remove(timing.class); }, 300); } // Cookie animation elements.cookieBtn.style.transform = 'scale(0.95)'; setTimeout(() => { elements.cookieBtn.style.transform = 'scale(1)'; }, 100); // Special effects for 1M+ if (game.specialEffectUnlocked) { createSpecialEffect(); } updateMultiplier(); updateUI(); checkSkinsAvailability(); updateLeaderboard(); // Haptic feedback if available if (navigator.vibrate) { navigator.vibrate(timing.multiplier > 1 ? [20, 30, 20] : 10); } } // Show floating text function showFloatingText(amount, label, color) { const rect = elements.cookieBtn.getBoundingClientRect(); const containerRect = document.getElementById('cookieContainer').getBoundingClientRect(); const el = document.createElement('div'); el.className = 'floating-text'; el.style.left = '50%'; el.style.top = '40%'; el.style.transform = 'translate(-50%, -50%)'; el.style.color = color; el.style.fontSize = label === 'PERFECT!' ? '1.5rem' : '1.2rem'; el.innerHTML = `
${label}
+${amount}
`; document.getElementById('cookieContainer').appendChild(el); setTimeout(() => el.remove(), 1000); } // Create particles function createParticles(intensity) { const count = intensity * 4; const colors = ['#fbbf24', '#f59e0b', '#d97706', '#ffffff', '#4ade80', '#60a5fa']; for (let i = 0; i < count; i++) { const particle = document.createElement('div'); particle.className = 'particle'; particle.style.left = '50%'; particle.style.top = '50%'; particle.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)]; const angle = (Math.PI * 2 * i) / count; const velocity = 60 + Math.random() * 60; const tx = Math.cos(angle) * velocity; const ty = Math.sin(angle) * velocity; particle.style.setProperty('--tx', tx + 'px'); particle.style.setProperty('--ty', ty + 'px'); elements.particles.appendChild(particle); setTimeout(() => particle.remove(), 1000); } } // Special effect for 1M+ function createSpecialEffect() { // Rainbow flash elements.cookieVisual.style.filter = 'hue-rotate(0deg)'; let rotation = 0; const rainbowInterval = setInterval(() => { rotation += 30; elements.cookieVisual.style.filter = `hue-rotate(${rotation}deg)`; if (rotation >= 360) { clearInterval(rainbowInterval); elements.cookieVisual.style.filter = ''; } }, 50); // Screen shake document.body.classList.add('animate-shake'); setTimeout(() => document.body.classList.remove('animate-shake'), 500); // Extra particles createParticles(10); // Shockwave ring const ring = document.createElement('div'); ring.style.cssText = ` position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 100%; height: 100%; border-radius: 50%; border: 6px solid rgba(255,255,255,0.9); animation: particle-float 0.8s ease-out forwards; pointer-events: none; z-index: 5; `; ring.style.setProperty('--tx', '0px'); ring.style.setProperty('--ty', '0px'); elements.particles.appendChild(ring); setTimeout(() => ring.remove(), 800); } // Update multiplier based on milestones function updateMultiplier() { let baseMult = 1; let bonusText = 'x1'; // 1000 = +1 extra (total 2) // 10000 = +1 extra (total 3) // 1000000 = +3 extra (total 6) + special effect if (game.personalScore >= 1000000) { baseMult = 6; bonusText = 'x6 (LEGENDARY)'; game.specialEffectUnlocked = true; } else if (game.personalScore >= 10000) { baseMult = 3; bonusText = 'x3 (MASTER)'; game.specialEffectUnlocked = false; } else if (game.personalScore >= 1000) { baseMult = 2; bonusText = 'x2 (APPRENTICE)'; game.specialEffectUnlocked = false; } game.multiplier = baseMult; elements.multiplierText.textContent = bonusText; if (baseMult > 1) { elements.multiplierBadge.classList.remove('opacity-0'); elements.multiplierBadge.classList.add('animate-pulse'); } } // Feed Destroyer function feedDestroyer() { if (game.personalScore >= 10) { game.personalScore -= 10; game.destroyerHunger = Math.min(100, game.destroyerHunger + 5); localStorage.setItem('personalScore', game.personalScore); localStorage.setItem('destroyerHunger', game.destroyerHunger); updateUI(); // Visual feedback elements.feedDestroyerBtn.classList.add('animate-pulse'); setTimeout(() => elements.feedDestroyerBtn.classList.remove('animate-pulse'), 500); if (navigator.vibrate) navigator.vibrate([10, 20]); } else { elements.feedDestroyerBtn.classList.add('animate-shake'); setTimeout(() => elements.feedDestroyerBtn.classList.remove('animate-shake'), 500); } } // Destroyer Loop function startDestroyerLoop() { setInterval(() => { game.destroyerHunger -= 1; if (game.destroyerHunger <= 0) { game.destroyerHunger = 0; triggerGlobalReset(); } localStorage.setItem('destroyerHunger', game.destroyerHunger); updateUI(); // Warning when low if (game.destroyerHunger <= 20) { elements.warningOverlay.classList.remove('opacity-0'); if (game.destroyerHunger <= 10) { elements.warningOverlay.classList.add('animate-pulse'); } } else { elements.warningOverlay.classList.add('opacity-0'); elements.warningOverlay.classList.remove('animate-pulse'); } }, 5000); } // Global Reset function triggerGlobalReset() { game.globalScore = 0; game.countryScores = {}; localStorage.setItem('globalCookieScore', 0); localStorage.setItem('countryScores', JSON.stringify({})); game.destroyerHunger = 50; localStorage.setItem('destroyerHunger', 50); showResetModal(); updateUI(); updateLeaderboard(); } function showResetModal() { elements.resetModal.classList.remove('hidden'); if (navigator.vibrate) navigator.vibrate([100, 50, 100, 50, 200]); } // Leaderboard Management function updateLeaderboard() { // Simulate other countries having scores for atmosphere const simulatedScores = { ...game.countryScores }; // Add simulated data for countries not played yet countries.forEach(c => { if (!simulatedScores[c.code]) { // Random score between 0 and personal score * 0.8 for realism simulatedScores[c.code] = Math.floor(Math.random() * game.personalScore * 0.8); } }); // Sort by score const sorted = Object.entries(simulatedScores) .map(([code, score]) => ({ code, flag: getCountryFlag(code), name: countries.find(c => c.code === code)?.name || code, score, isPlayer: code === game.playerCountry })) .sort((a, b) => b.score - a.score) .slice(0, 5); // Top 5 elements.leaderboardList.innerHTML = sorted.map((item, index) => `
#${index + 1} ${item.flag} ${item.name} ${item.isPlayer ? '(You)' : ''}
${item.score.toLocaleString()}
`).join(''); } // Skin Management function applySkin(skinName) { const skin = skins[skinName]; if (!skin) return; // Remove all skin classes Object.values(skins).forEach(s => { elements.cookieVisual.classList.remove(s.class); }); // Add new skin class elements.cookieVisual.classList.add(skin.class); game.currentSkin = skinName; localStorage.setItem('currentSkin', skinName); // Update UI selection document.querySelectorAll('.skin-btn').forEach(btn => { btn.classList.remove('ring-4', 'ring-amber-400', 'scale-110'); if (btn.dataset.skin === skinName) { btn.classList.add('ring-4', 'ring-amber-400', 'scale-110'); } }); } function unlockSkin(skinName, cost) { if (game.personalScore >= cost && !game.unlockedSkins.includes(skinName)) { game.personalScore -= cost; game.unlockedSkins.push(skinName); localStorage.setItem('personalScore', game.personalScore); localStorage.setItem('unlockedSkins', JSON.stringify(game.unlockedSkins)); applySkin(skinName); updateUI(); checkSkinsAvailability(); // Celebration createParticles(5); } } function checkSkinsAvailability() { document.querySelectorAll('.skin-btn').forEach(btn => { const skin = btn.dataset.skin; const cost = parseInt(btn.dataset.cost) || 0; if (game.unlockedSkins.includes(skin)) { btn.classList.remove('locked', 'opacity-50', 'border-gray-600'); btn.classList.add('unlocked', 'border-amber-500'); const lockOverlay = btn.querySelector('.absolute.inset-0.bg-black\\/60'); if (lockOverlay) lockOverlay.remove(); if (skin === game.currentSkin) { btn.classList.add('ring-4', 'ring-amber-400', 'scale-110'); } } else { // Check if affordable if (game.personalScore >= cost) { btn.classList.add('border-amber-500', 'cursor-pointer'); btn.classList.remove('border-gray-600', 'opacity-50'); btn.classList.add('opacity-80'); } } }); } // Event Listeners function setupEventListeners() { // Cookie click elements.cookieBtn.addEventListener('click', handleCookieClick); elements.cookieBtn.addEventListener('touchstart', (e) => { e.preventDefault(); handleCookieClick(e); }, { passive: false }); // Feed destroyer elements.feedDestroyerBtn.addEventListener('click', feedDestroyer); // Dismiss reset modal elements.dismissReset.addEventListener('click', () => { elements.resetModal.classList.add('hidden'); }); // Skin selection document.querySelectorAll('.skin-btn').forEach(btn => { btn.addEventListener('click', () => { const skin = btn.dataset.skin; const cost = parseInt(btn.dataset.cost) || 0; if (game.unlockedSkins.includes(skin)) { applySkin(skin); } else if (game.personalScore >= cost) { unlockSkin(skin, cost); } else { btn.classList.add('animate-shake'); setTimeout(() => btn.classList.remove('animate-shake'), 500); } }); }); } // UI Updates function updateUI() { elements.personalScore.textContent = game.personalScore.toLocaleString(); elements.globalScore.textContent = game.globalScore.toLocaleString(); elements.destroyerHunger.style.width = game.destroyerHunger + '%'; elements.hungerPercent.textContent = game.destroyerHunger + '%'; // Color code hunger bar if (game.destroyerHunger > 50) { elements.destroyerHunger.className = 'h-full bg-gradient-to-r from-green-600 to-green-500 transition-all duration-500'; } else if (game.destroyerHunger > 25) { elements.destroyerHunger.className = 'h-full bg-gradient-to-r from-yellow-600 to-yellow-500 transition-all duration-500'; } else { elements.destroyerHunger.className = 'h-full bg-gradient-to-r from-red-600 to-red-500 transition-all duration-500 animate-pulse'; } // Update feed button state if (game.personalScore < 10) { elements.feedDestroyerBtn.classList.add('opacity-50', 'cursor-not-allowed'); } else { elements.feedDestroyerBtn.classList.remove('opacity-50', 'cursor-not-allowed'); } } // Start game init(); // Simulate other countries contributing (atmosphere) setInterval(() => { if (Math.random() > 0.6 && game.globalScore > 0) { // Random country adds cookies const randomCountry = countries[Math.floor(Math.random() * countries.length)].code; const gain = Math.floor(Math.random() * 10) + 1; game.globalScore += gain; game.countryScores[randomCountry] = (game.countryScores[randomCountry] || 0) + gain; localStorage.setItem('globalCookieScore', game.globalScore); localStorage.setItem('countryScores', JSON.stringify(game.countryScores)); elements.globalScore.textContent = game.globalScore.toLocaleString(); updateLeaderboard(); } }, 5000);