|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>Space Invaders</title> |
|
<style> |
|
body { |
|
margin: 0; |
|
display: flex; |
|
justify-content: center; |
|
align-items: center; |
|
height: 100vh; |
|
background-color: black; |
|
color: white; |
|
font-family: Arial, sans-serif; |
|
} |
|
|
|
.game { |
|
position: relative; |
|
width: 600px; |
|
height: 600px; |
|
background-color: #111; |
|
overflow: hidden; |
|
} |
|
|
|
.player { |
|
position: absolute; |
|
bottom: 20px; |
|
left: 50%; |
|
width: 40px; |
|
height: 40px; |
|
background-color: white; |
|
transform: translateX(-50%); |
|
} |
|
|
|
.invaders { |
|
position: absolute; |
|
top: 20px; |
|
left: 0; |
|
width: 100%; |
|
display: flex; |
|
flex-wrap: wrap; |
|
} |
|
|
|
.invader { |
|
width: 40px; |
|
height: 40px; |
|
background-color: red; |
|
margin: 5px; |
|
} |
|
|
|
.bullet { |
|
position: absolute; |
|
width: 5px; |
|
height: 20px; |
|
background-color: yellow; |
|
} |
|
|
|
.scoreboard { |
|
position: absolute; |
|
top: 10px; |
|
left: 10px; |
|
font-size: 20px; |
|
} |
|
|
|
.start-menu { |
|
position: absolute; |
|
top: 50%; |
|
left: 50%; |
|
transform: translate(-50%, -50%); |
|
text-align: center; |
|
} |
|
|
|
.start-menu button { |
|
margin: 10px; |
|
padding: 10px 20px; |
|
font-size: 16px; |
|
} |
|
|
|
.game-over-message { |
|
position: absolute; |
|
top: 50%; |
|
left: 50%; |
|
transform: translate(-50%, -50%); |
|
font-size: 24px; |
|
text-align: center; |
|
display: none; |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
<div class="game"> |
|
<div class="scoreboard">Score: 0</div> |
|
<div class="player"></div> |
|
<div class="invaders"></div> |
|
<div class="game-over-message">Game Over, <span id="username-display"></span>! Your score is: <span id="score-display"></span></div> |
|
<div class="start-menu"> |
|
<h2>Enter Your Name</h2> |
|
<input type="text" id="username" placeholder="Your name"> |
|
<h2>Select Difficulty</h2> |
|
<button data-speed="1">Slow</button> |
|
<button data-speed="2">Medium</button> |
|
<button data-speed="3">Fast</button> |
|
</div> |
|
</div> |
|
<script> |
|
document.addEventListener('DOMContentLoaded', () => { |
|
const game = document.querySelector('.game'); |
|
const player = document.querySelector('.player'); |
|
const invadersContainer = document.querySelector('.invaders'); |
|
const scoreboard = document.querySelector('.scoreboard'); |
|
const startMenu = document.querySelector('.start-menu'); |
|
const buttons = document.querySelectorAll('.start-menu button'); |
|
const usernameInput = document.getElementById('username'); |
|
const gameOverMessage = document.querySelector('.game-over-message'); |
|
const usernameDisplay = document.getElementById('username-display'); |
|
const scoreDisplay = document.getElementById('score-display'); |
|
|
|
const playerSpeed = 10; |
|
let playerPosition = 280; |
|
let score = 0; |
|
let invaderSpeed = 2; |
|
let invaderInterval; |
|
let username = ''; |
|
|
|
buttons.forEach(button => { |
|
button.addEventListener('click', (e) => { |
|
username = usernameInput.value.trim(); |
|
if (username === '') { |
|
alert('Please enter your name.'); |
|
return; |
|
} |
|
invaderSpeed = parseInt(e.target.getAttribute('data-speed')); |
|
startMenu.style.display = 'none'; |
|
startGame(); |
|
}); |
|
}); |
|
|
|
function startGame() { |
|
if (invaderSpeed === 1) { |
|
invaderSpeed = 8; |
|
} else if (invaderSpeed === 3) { |
|
invaderSpeed = 14; |
|
} |
|
createInvaders(); |
|
document.addEventListener('keydown', movePlayer); |
|
invaderInterval = setInterval(moveInvaders, 500); |
|
setInterval(createInvaders, 5000); |
|
} |
|
|
|
function createInvaders() { |
|
const invaderCount = 30; |
|
const invaderWidth = 50; |
|
const maxCols = Math.floor(game.offsetWidth / invaderWidth); |
|
|
|
for (let i = 0; i < invaderCount; i++) { |
|
const invader = document.createElement('div'); |
|
invader.classList.add('invader'); |
|
invader.style.position = 'absolute'; |
|
invader.style.left = (i % maxCols) * invaderWidth + 'px'; |
|
invader.style.top = Math.floor(i / maxCols) * 50 + 'px'; |
|
invadersContainer.appendChild(invader); |
|
} |
|
} |
|
|
|
|
|
function movePlayer(e) { |
|
switch (e.key) { |
|
case 'ArrowLeft': |
|
if (playerPosition > 0) { |
|
playerPosition -= playerSpeed; |
|
player.style.left = playerPosition + 'px'; |
|
} |
|
break; |
|
case 'ArrowRight': |
|
if (playerPosition < game.offsetWidth - player.offsetWidth) { |
|
playerPosition += playerSpeed; |
|
player.style.left = playerPosition + 'px'; |
|
} |
|
break; |
|
case ' ': |
|
shoot(); |
|
break; |
|
} |
|
} |
|
|
|
|
|
function shoot() { |
|
const bullet = document.createElement('div'); |
|
bullet.classList.add('bullet'); |
|
bullet.style.left = playerPosition + 17.5 + 'px'; |
|
bullet.style.bottom = '60px'; |
|
game.appendChild(bullet); |
|
moveBullet(bullet); |
|
} |
|
|
|
|
|
function moveBullet(bullet) { |
|
const bulletInterval = setInterval(() => { |
|
const bulletBottom = parseInt(bullet.style.bottom.replace('px', '')); |
|
if (bulletBottom >= game.offsetHeight) { |
|
clearInterval(bulletInterval); |
|
bullet.remove(); |
|
} else { |
|
bullet.style.bottom = bulletBottom + 5 + 'px'; |
|
} |
|
checkBulletCollision(bullet, bulletInterval); |
|
}, 20); |
|
} |
|
|
|
|
|
function checkBulletCollision(bullet, bulletInterval) { |
|
const bulletRect = bullet.getBoundingClientRect(); |
|
document.querySelectorAll('.invader').forEach(invader => { |
|
const invaderRect = invader.getBoundingClientRect(); |
|
if (bulletRect.top <= invaderRect.bottom && bulletRect.bottom >= invaderRect.top && |
|
bulletRect.left <= invaderRect.right && bulletRect.right >= invaderRect.left) { |
|
bullet.remove(); |
|
invader.remove(); |
|
clearInterval(bulletInterval); |
|
score++; |
|
scoreboard.textContent = `Score: ${score}`; |
|
} |
|
}); |
|
} |
|
|
|
|
|
function moveInvaders() { |
|
const invaders = Array.from(document.querySelectorAll('.invader')); |
|
invaders.forEach(invader => { |
|
const currentTop = parseInt(invader.style.top.replace('px', '')); |
|
invader.style.top = currentTop + invaderSpeed + 'px'; |
|
}); |
|
|
|
|
|
invaders.forEach(invader => { |
|
const invaderBottom = parseInt(invader.style.top.replace('px', '')) + invader.offsetHeight; |
|
if (invaderBottom >= game.offsetHeight) { |
|
gameOverMessage.style.display = 'block'; |
|
usernameDisplay.textContent = username; |
|
scoreDisplay.textContent = score; |
|
clearInterval(invaderInterval); |
|
} |
|
}); |
|
} |
|
}); |
|
</script> |
|
</body> |
|
</html> |
|
|