Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save EncodeTheCode/8dc88a7a11106e549dc99b91d9c94292 to your computer and use it in GitHub Desktop.
Save EncodeTheCode/8dc88a7a11106e549dc99b91d9c94292 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Jedi Lightsaber Swing Game</title>
<style>
body { margin: 0; overflow: hidden; }
canvas { background: #FFF; display: block; }
</style>
</head>
<body>
<canvas id="gameCanvas"></canvas>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const PLAYER_SPEED = 3;
const ENEMY_SPEED = 1;
const SPAWN_RADIUS = 250;
const SWING_RADIUS = 100;
const SWING_ANGLE = Math.PI / 4; // 45 degrees
const ENEMY_SPAWN_INTERVAL = 10000; // milliseconds
let gameOver = false;
class Player {
constructor(x, y, radius, color) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.angle = 0;
this.dx = 0;
this.dy = 0;
this.swingStep = 0;
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
ctx.fillStyle = this.color;
ctx.fill();
ctx.closePath();
}
update() {
this.x += this.dx;
this.y += this.dy;
this.x = Math.max(this.radius, Math.min(canvas.width - this.radius, this.x));
this.y = Math.max(this.radius, Math.min(canvas.height - this.radius, this.y));
}
swing() {
if (this.swingStep < 24) {
const stepAngle = SWING_ANGLE / 24;
const startAngle = this.angle - SWING_ANGLE / 8 + stepAngle * this.swingStep;
const endAngle = startAngle + stepAngle;
ctx.beginPath();
ctx.arc(this.x, this.y, SWING_RADIUS, startAngle, endAngle, false);
ctx.lineWidth = 55;
ctx.strokeStyle = 'blue';
ctx.stroke();
ctx.closePath();
this.swingStep++;
} else {
this.swingStep = 0;
swinging = false;
}
}
updateAngle(mouseX, mouseY) {
const dx = mouseX - this.x;
const dy = mouseY - this.y;
this.angle = Math.atan2(dy, dx);
}
hurtEnemies(enemies) {
const endAngle = this.angle + SWING_ANGLE / 8;
const startAngle = this.angle - SWING_ANGLE / 8;
enemies.forEach(enemy => {
const dx = enemy.x - this.x;
const dy = enemy.y - this.y;
const distance = Math.sqrt(dx * dx + dy * dy);
const angleToEnemy = Math.atan2(dy, dx);
if (distance < SWING_RADIUS && angleToEnemy > startAngle && angleToEnemy < endAngle) {
enemy.hurt();
}
});
}
}
class Enemy {
constructor(x, y, radius, color) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.health = 100;
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
ctx.fillStyle = this.color;
ctx.fill();
ctx.closePath();
}
update(player) {
const dx = player.x - this.x;
const dy = player.y - this.y;
const distance = Math.sqrt(dx * dx + dy * dy);
const moveX = (dx / distance) * ENEMY_SPEED;
const moveY = (dy / distance) * ENEMY_SPEED;
this.x += moveX;
this.y += moveY;
}
hurt() {
this.health -= 50;
}
}
const player = new Player(canvas.width / 2, canvas.height / 2, 20, 'green');
let enemies = [];
let swinging = false;
function spawnEnemy() {
const angle = Math.random() * Math.PI * 2;
const x = player.x + SPAWN_RADIUS * Math.cos(angle);
const y = player.y + SPAWN_RADIUS * Math.sin(angle);
enemies.push(new Enemy(x, y, 20, 'red'));
}
function animate() {
if (gameOver) return;
ctx.clearRect(0, 0, canvas.width, canvas.height);
player.update();
player.draw();
enemies = enemies.filter(enemy => enemy.health > 0); // Remove dead enemies
enemies.forEach(enemy => {
enemy.update(player);
enemy.draw();
const dx = player.x - enemy.x;
const dy = player.y - enemy.y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < player.radius + enemy.radius && enemy.health > 0) {
gameOver = true;
alert('Game Over!');
}
});
if (swinging) {
player.swing();
player.hurtEnemies(enemies);
}
requestAnimationFrame(animate);
}
canvas.addEventListener('mousemove', (event) => {
player.updateAngle(event.clientX, event.clientY);
});
canvas.addEventListener('click', () => {
if (!swinging) {
swinging = true;
player.swingStep = 0;
}
});
window.addEventListener('keydown', (event) => {
switch (event.key) {
case 'w': player.dy = -PLAYER_SPEED; break;
case 'a': player.dx = -PLAYER_SPEED; break;
case 's': player.dy = PLAYER_SPEED; break;
case 'd': player.dx = PLAYER_SPEED; break;
}
});
window.addEventListener('keyup', (event) => {
switch (event.key) {
case 'w':
case 's': player.dy = 0; break;
case 'a':
case 'd': player.dx = 0; break;
}
});
setInterval(spawnEnemy, ENEMY_SPAWN_INTERVAL);
animate();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment