// ========== PARTICLES ANIMATION ========== const particlesContainer = document.getElementById('particles'); function createParticle() { const particle = document.createElement('div'); particle.className = 'particle'; particle.style.left = Math.random() * 100 + '%'; particle.style.top = Math.random() * 100 + '%'; const size = 3 + Math.random() * 4; particle.style.width = size + 'px'; particle.style.height = size + 'px'; const duration = 3 + Math.random() * 5; const delay = Math.random() * 2; const moveX = (Math.random() - 0.5) * 200; const animationName = `float-${Date.now()}-${Math.random()}`; const keyframes = ` @keyframes ${animationName} { 0% { transform: translateY(0) translateX(0); opacity: 0; } 10% { opacity: 1; } 90% { opacity: 1; } 100% { transform: translateY(-100vh) translateX(${moveX}px); opacity: 0; } } `; const style = document.createElement('style'); style.innerHTML = keyframes; document.head.appendChild(style); particle.style.animation = `${animationName} ${duration}s ${delay}s ease-in-out forwards`; particlesContainer.appendChild(particle); setTimeout(() => { particle.remove(); style.remove(); }, (duration + delay) * 1000); } setInterval(createParticle, 300); for (let i = 0; i < 25; i++) { setTimeout(createParticle, i * 100); } // ========== LEADERBOARD DATA MANAGEMENT ========== // Get leaderboard data from localStorage function getLeaderboardData() { const data = localStorage.getItem('leaderboard2048'); return data ? JSON.parse(data) : []; } // Save leaderboard data to localStorage function saveLeaderboardData(data) { localStorage.setItem('leaderboard2048', JSON.stringify(data)); } // Get current logged-in user function getCurrentUser() { return localStorage.getItem('currentUser') || null; } // Add or update score for a player function addScore(playerName, score) { let leaderboard = getLeaderboardData(); // Find if player already exists const existingIndex = leaderboard.findIndex(p => p.name === playerName); if (existingIndex >= 0) { // Update only if new score is higher if (score > leaderboard[existingIndex].score) { leaderboard[existingIndex].score = score; leaderboard[existingIndex].level = Math.floor(score / 100); leaderboard[existingIndex].date = new Date().toISOString(); } } else { // Add new player leaderboard.push({ name: playerName, score: score, level: Math.floor(score / 100), date: new Date().toISOString() }); } saveLeaderboardData(leaderboard); } // ========== RENDER LEADERBOARD ========== function renderLeaderboard() { let leaderboardData = getLeaderboardData(); const currentUser = getCurrentUser(); const list = document.getElementById('leaderboardList'); const emptyState = document.getElementById('emptyState'); // Sort by score (highest first) leaderboardData.sort((a, b) => b.score - a.score); // Update stats const totalPlayers = leaderboardData.length; const topScore = leaderboardData.length > 0 ? leaderboardData[0].score : 0; document.getElementById('totalPlayers').textContent = totalPlayers; document.getElementById('topScore').textContent = topScore.toLocaleString(); // Find current user's rank let userRank = '--'; if (currentUser) { const userIndex = leaderboardData.findIndex(p => p.name === currentUser); if (userIndex >= 0) { userRank = userIndex + 1; } } document.getElementById('yourRank').textContent = userRank; // Check if there's data if (leaderboardData.length === 0) { list.style.display = 'none'; if (emptyState) emptyState.style.display = 'block'; return; } list.style.display = 'flex'; if (emptyState) emptyState.style.display = 'none'; // Render top 10 players const top10 = leaderboardData.slice(0, 10); list.innerHTML = top10.map((player, index) => { const rank = index + 1; let rankClass = 'rank-other'; if (rank === 1) rankClass = 'rank-1'; else if (rank === 2) rankClass = 'rank-2'; else if (rank === 3) rankClass = 'rank-3'; const isCurrentUser = currentUser && player.name === currentUser; const yourRankClass = isCurrentUser ? 'your-rank' : ''; return `
  • ${rank}
    ${escapeHtml(player.name)}
    Level ${player.level || Math.floor(player.score / 100)}
    ${player.score.toLocaleString()}
    Points
  • `; }).join(''); } // Escape HTML to prevent XSS function escapeHtml(text) { const map = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }; return text.replace(/[&<>"']/g, m => map[m]); } // ========== SAMPLE DATA (FOR TESTING) ========== function initSampleData() { const existingData = getLeaderboardData(); // Only add sample data if leaderboard is empty if (existingData.length === 0) { const sampleData = [ { name: "CyberKing", score: 9850, level: 98, date: new Date().toISOString() }, { name: "NeonMaster", score: 8200, level: 82, date: new Date().toISOString() }, { name: "PixelHunter", score: 6950, level: 69, date: new Date().toISOString() }, { name: "StarGazer", score: 5420, level: 54, date: new Date().toISOString() }, { name: "CodeNinja", score: 4890, level: 48, date: new Date().toISOString() }, { name: "ByteWarrior", score: 4320, level: 43, date: new Date().toISOString() }, { name: "DataDragon", score: 3850, level: 38, date: new Date().toISOString() }, { name: "SyntaxSage", score: 3120, level: 31, date: new Date().toISOString() }, { name: "LogicLord", score: 2780, level: 27, date: new Date().toISOString() }, { name: "BugSlayer", score: 2340, level: 23, date: new Date().toISOString() } ]; saveLeaderboardData(sampleData); console.log('Sample data initialized'); } } // ========== CLEAR LEADERBOARD (FOR TESTING) ========== function clearLeaderboard() { if (confirm('Are you sure you want to clear all leaderboard data?')) { localStorage.removeItem('leaderboard2048'); renderLeaderboard(); console.log('Leaderboard cleared'); } } // ========== REFRESH LEADERBOARD ========== function refreshLeaderboard() { renderLeaderboard(); console.log('Leaderboard refreshed'); } // ========== INITIALIZE ON PAGE LOAD ========== window.addEventListener('DOMContentLoaded', function() { renderLeaderboard(); console.log('Leaderboard initialized'); console.log('Available functions:'); console.log('- addScore(name, score) - Add/update a score'); console.log('- clearLeaderboard() - Clear all data'); console.log('- refreshLeaderboard() - Refresh display'); }); // ========== EXPOSE FUNCTIONS TO WINDOW (FOR EXTERNAL USE) ========== window.leaderboard = { addScore: addScore, getLeaderboardData: getLeaderboardData, clearLeaderboard: clearLeaderboard, refreshLeaderboard: refreshLeaderboard, initSampleData: initSampleData };