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();