dodge_ball / index.html
Sunghokim's picture
Update index.html
e485332 verified
<script>
const gameArea = document.getElementById('gameArea');
const player = document.getElementById('player');
let score = 0;
let level = 1;
let isGameActive = true;
let playerX = 385;
let playerY = 285;
let playerSpeed = 5;
let enemies = [];
let balls = [];
let powerups = [];
let hasShield = false;
const keys = {};
class Enemy {
constructor(type) {
this.element = document.createElement('div');
this.element.className = `enemy ${type}`;
this.type = type;
this.x = Math.random() * 750;
this.y = type === 'bouncer' ? 550 : Math.random() * 550;
this.dx = (Math.random() - 0.5) * 4;
this.dy = type === 'bouncer' ? -10 : (Math.random() - 0.5) * 4;
gameArea.appendChild(this.element);
this.startShooting();
}
update() {
if (this.type === 'bouncer') {
this.dy += 0.5; // Gravity
if (this.y > 550) this.dy = -Math.abs(this.dy) * 0.8;
}
this.x += this.dx;
this.y += this.dy;
// Bounce off walls
if (this.x < 0 || this.x > 750) this.dx *= -1;
if (this.y < 0) this.dy = Math.abs(this.dy);
this.element.style.left = this.x + 'px';
this.element.style.top = this.y + 'px';
this.createTrail();
}
startShooting() {
setInterval(() => {
if (!isGameActive) return;
this.shoot();
}, 2000);
}
shoot() {
const types = ['fire-ball', 'ice-ball', 'thunder-ball'];
const type = types[Math.floor(Math.random() * types.length)];
const ball = this.createBall(type);
this.launchBall(ball);
}
createBall(type) {
const ball = document.createElement('div');
ball.className = `ball ${type}`;
ball.style.left = this.x + 'px';
ball.style.top = this.y + 'px';
gameArea.appendChild(ball);
return { element: ball, type };
}
launchBall(ball) {
const angle = Math.atan2(playerY - this.y, playerX - this.x);
const speed = ball.type === 'ice-ball' ? 7 :
ball.type === 'thunder-ball' ? 4 : 5;
balls.push({
...ball,
x: this.x,
y: this.y,
dx: Math.cos(angle) * speed,
dy: Math.sin(angle) * speed
});
}
createTrail() {
const trail = document.createElement('div');
trail.className = 'trail';
trail.style.width = this.element.offsetWidth + 'px';
trail.style.height = this.element.offsetHeight + 'px';
trail.style.left = this.x + 'px';
trail.style.top = this.y + 'px';
trail.style.background = this.type === 'bouncer' ?
'rgba(255,0,0,0.3)' : 'rgba(255,0,255,0.3)';
gameArea.appendChild(trail);
setTimeout(() => trail.remove(), 500);
}
}
function update() {
if (!isGameActive) return;
updatePlayer();
updateEnemies();
updateBalls();
updatePowerups();
checkCollisions();
updateScore();
requestAnimationFrame(update);
}
function updatePlayer() {
if (keys['ArrowLeft'] || keys['a']) playerX = Math.max(0, playerX - playerSpeed);
if (keys['ArrowRight'] || keys['d']) playerX = Math.min(770, playerX + playerSpeed);
if (keys['ArrowUp'] || keys['w']) playerY = Math.max(0, playerY - playerSpeed);
if (keys['ArrowDown'] || keys['s']) playerY = Math.min(570, playerY + playerSpeed);
player.style.left = playerX + 'px';
player.style.top = playerY + 'px';
}
function updateEnemies() {
enemies.forEach(enemy => enemy.update());
}
function updateBalls() {
balls.forEach((ball, index) => {
ball.x += ball.dx;
ball.y += ball.dy;
ball.element.style.left = ball.x + 'px';
ball.element.style.top = ball.y + 'px';
if (ball.x < -50 || ball.x > 850 || ball.y < -50 || ball.y > 650) {
ball.element.remove();
balls.splice(index, 1);
}
});
}
function updatePowerups() {
powerups.forEach(powerup => {
powerup.y += 2;
powerup.element.style.top = powerup.y + 'px';
if (powerup.y > 600) {
powerup.element.remove();
powerups = powerups.filter(p => p !== powerup);
}
});
}
function checkCollisions() {
const playerRect = player.getBoundingClientRect();
// Check collisions with enemies and balls
enemies.concat(balls).forEach(obj => {
const rect = obj.element.getBoundingClientRect();
if (isColliding(playerRect, rect)) {
if (hasShield) {
hasShield = false;
document.getElementById('shieldStatus').textContent = '❌';
} else {
gameOver();
}
}
});
}
function isColliding(rect1, rect2) {
return !(rect1.right < rect2.left ||
rect1.left > rect2.right ||
rect1.bottom < rect2.top ||
rect1.top > rect2.bottom);
}
function updateScore() {
score++;
document.getElementById('scoreValue').textContent = score;
if (score % 500 === 0) {
level++;
document.getElementById('levelValue').textContent = level;
enemies.push(new Enemy(Math.random() < 0.5 ? 'bouncer' : 'spinner'));
}
}
function gameOver() {
isGameActive = false;
document.getElementById('gameOver').style.display = 'flex';
document.getElementById('finalScore').textContent = score;
}
// Event Listeners
document.addEventListener('keydown', e => keys[e.key] = true);
document.addEventListener('keyup', e => keys[e.key] = false);
// Initialize game
enemies.push(new Enemy('bouncer'));
enemies.push(new Enemy('spinner'));
update();
</script>