const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); canvas.style.display = "block"; canvas.width = window.innerWidth; canvas.height = window.innerHeight; let audio = new Audio('./zap.wav'); audio.preload = 'auto'; let audioLoaded = false; audio.addEventListener('canplaythrough', function() { audioLoaded = true; }); audio.addEventListener('error', function() { console.error('Error loading audio file'); }); const createTargets = () => { let targets = []; for(let i = 0; i < 10; i++) { let shape = getRandomShape(); let radius = Math.random() * 50 + 20; let x = Math.random() * (canvas.width - 2 * radius - 120) + radius + 60; let y = Math.random() * (canvas.height - 2 * radius - 120) + radius + 60; let vx = (Math.random() - 0.5) * 10; let vy = (Math.random() - 0.5) * 10; targets.push({x, y, vx, vy, radius, shape}); } return targets; } const getRandomShape = () => { const shapes = ['circle', 'pentagon', 'triangle', 'square']; const randomIndex = Math.floor(Math.random() * shapes.length); return shapes[randomIndex]; } let score = 0; const drawScore = () => { ctx.font = '20px Arial'; ctx.fillStyle = 'white'; ctx.fillText('Score: ' + score, 10, 30); }; let level = 1; const drawLevel = () => { ctx.font = '20px Arial'; ctx.fillStyle = 'white'; ctx.fillText('Level: ' + level, 10, 60); } let showHelp = false; const drawHelp = () => { if(showHelp) { ctx.font = '20px Arial'; ctx.fillStyle = 'white'; ctx.fillText('Click to shoot. Press R to respawn targets. Press H to toggle help text.', 10, 50); } } const drawLine = (line) => { if (line && Date.now() - line.time < 500) { ctx.beginPath(); ctx.moveTo(line.startX, line.startY); ctx.lineTo(line.endX, line.endY); ctx.strokeStyle = 'red'; ctx.lineWidth = 4; ctx.stroke(); } }; const colors = ['#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#FF00FF', '#00FFFF']; const drawTargets = (targets) => { for (let target of targets) { target.x += target.vx; target.y += target.vy; if (target.x - target.radius < 0 || target.x + target.radius > canvas.width) { target.vx = -target.vx; } if (target.y - target.radius < 0 || target.y + target.radius > canvas.height) { target.vy = -target.vy; } ctx.beginPath(); if (target.shape === 'circle') { ctx.arc(target.x, target.y, target.radius, 0, Math.PI * 2); } else if (target.shape === 'pentagon') { ctx.moveTo(target.x + target.radius * Math.cos(0), target.y + target.radius * Math.sin(0)); for (let i = 1; i <= 5; i++) { ctx.lineTo(target.x + target.radius * Math.cos(i * (Math.PI * 2) / 5), target.y + target.radius * Math.sin(i * (Math.PI * 2) / 5)); } } else if (target.shape === 'triangle') { ctx.moveTo(target.x + target.radius * Math.cos(0), target.y + target.radius * Math.sin(0)); for (let i = 1; i <= 3; i++) { ctx.lineTo(target.x + target.radius * Math.cos(i * (Math.PI * 2) / 3), target.y + target.radius * Math.sin(i * (Math.PI * 2) / 3)); } } else if (target.shape === 'square') { ctx.rect(target.x - target.radius, target.y - target.radius, target.radius * 2, target.radius * 2); } const randomColor = colors[Math.floor(Math.random() * colors.length)]; ctx.fillStyle = randomColor; ctx.fill(); } }; const gameLoop = () => { ctx.clearRect(0, 0, canvas.width, canvas.height); drawScore(); drawLevel(); drawHelp(); drawLine(line); drawTargets(targets); requestAnimationFrame(gameLoop); if (targets.length === 0) { level++; targets = createTargets(); } }; let line = null; const handleInteraction = (e) => { const rect = canvas.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; if (audioLoaded) { audio.play().catch((error) => { console.error('Error playing audio:', error); }); } line = { startX: 0, startY: canvas.height, endX: x, endY: y, time: Date.now() }; targets = targets.filter((target) => { const dx = target.x - x; const dy = target.y - y; if (dx * dx + dy * dy <= target.radius * target.radius) { score++; return false; } return true; }); }; canvas.addEventListener('click', handleInteraction); canvas.addEventListener('touchstart', function(e) { // Prevent the window from scrolling e.preventDefault(); // A touch event can have multiple touches so we just get the first one e.clientX = e.touches[0].clientX; e.clientY = e.touches[0].clientY; handleInteraction(e); }, { passive: false }); window.addEventListener('resize', () => { canvas.width = window.innerWidth; canvas.height = window.innerHeight; }); window.addEventListener('keydown', (e) => { if (e.key === 'r' || e.key === 'R') { targets = createTargets(); } }); window.addEventListener('keydown', (e) => { if (e.key === 'h' || e.key === 'H') { showHelp = !showHelp; } else if (e.key === 'r' || e.key === 'R') { targets = createTargets(); } }); let targets = createTargets(); gameLoop();