| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Star Wars: Asteroid Evasion</title> |
| <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&family=Prompt:wght@300;500&display=swap" rel="stylesheet"> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
| <style> |
| * { |
| margin: 0; |
| padding: 0; |
| box-sizing: border-box; |
| } |
| |
| body { |
| font-family: 'Prompt', sans-serif; |
| background-color: #000; |
| color: #fff; |
| overflow: hidden; |
| height: 100vh; |
| perspective: 1000px; |
| } |
| |
| #game-container { |
| position: relative; |
| width: 100%; |
| height: 100%; |
| background-image: |
| radial-gradient(circle at center, rgba(0, 20, 80, 0.8) 0%, rgba(0, 0, 0, 1) 70%), |
| url('https://starshipsofa.com/wp-content/uploads/2013/07/starfield.jpg'); |
| overflow: hidden; |
| } |
| |
| .stars { |
| position: absolute; |
| width: 100%; |
| height: 100%; |
| background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 200 200"><circle cx="10" cy="10" r="1" fill="white"/><circle cx="50" cy="30" r="1" fill="white"/><circle cx="80" cy="10" r="1" fill="white"/><circle cx="130" cy="20" r="1" fill="white"/><circle cx="170" cy="5" r="1" fill="white"/><circle cx="30" cy="80" r="1" fill="white"/><circle cx="90" cy="60" r="1" fill="white"/><circle cx="150" cy="70" r="1" fill="white"/><circle cx="10" cy="120" r="1" fill="white"/><circle cx="70" cy="100" r="1" fill="white"/><circle cx="120" cy="130" r="1" fill="white"/><circle cx="180" cy="110" r="1" fill="white"/><circle cx="30" cy="170" r="1" fill="white"/><circle cx="80" cy="150" r="1" fill="white"/><circle cx="140" cy="180" r="1" fill="white"/><circle cx="190" cy="160" r="1" fill="white"/></svg>'); |
| background-repeat: repeat; |
| animation: starScroll 200s linear infinite; |
| } |
| |
| @keyframes starScroll { |
| from { background-position: 0 0; } |
| to { background-position: 200px 200px; } |
| } |
| |
| #intro-screen, #game-over-screen { |
| position: absolute; |
| top: 0; |
| left: 0; |
| width: 100%; |
| height: 100%; |
| display: flex; |
| flex-direction: column; |
| justify-content: center; |
| align-items: center; |
| z-index: 1000; |
| background-color: rgba(0, 0, 0, 0.8); |
| text-align: center; |
| } |
| |
| #game-screen { |
| display: none; |
| height: 100%; |
| } |
| |
| .title { |
| font-family: 'Orbitron', sans-serif; |
| color: #ffe81f; |
| text-shadow: 0 0 10px #ff6, 0 0 20px #ff6; |
| font-size: 4rem; |
| margin-bottom: 2rem; |
| letter-spacing: 0.5rem; |
| animation: pulse 2s infinite; |
| } |
| |
| @keyframes pulse { |
| 0% { transform: scale(1); } |
| 50% { transform: scale(1.05); } |
| 100% { transform: scale(1); } |
| } |
| |
| .scroll-text { |
| position: relative; |
| height: 60%; |
| width: 60%; |
| overflow: hidden; |
| color: #ffe81f; |
| font-family: 'Orbitron', sans-serif; |
| font-size: 1.5rem; |
| line-height: 1.5; |
| text-align: justify; |
| transform: perspective(300px) rotateX(20deg); |
| text-align: center; |
| } |
| |
| .scroll-content { |
| position: absolute; |
| top: 100%; |
| animation: scroll 40s linear forwards; |
| } |
| |
| @keyframes scroll { |
| 0% { top: 100%; } |
| 100% { top: -500%; } |
| } |
| |
| .btn { |
| background: linear-gradient(to right, #3a3a98, #1a1a4e); |
| color: #ffe81f; |
| border: 2px solid #ffe81f; |
| padding: 1rem 2rem; |
| font-family: 'Orbitron', sans-serif; |
| font-size: 1.2rem; |
| border-radius: 5px; |
| cursor: pointer; |
| transition: all 0.3s; |
| margin-top: 2rem; |
| box-shadow: 0 0 15px rgba(255, 232, 31, 0.5); |
| } |
| |
| .btn:hover { |
| background: linear-gradient(to right, #4e4eb8, #2a2a6e); |
| transform: scale(1.05); |
| box-shadow: 0 0 25px rgba(255, 232, 31, 0.8); |
| } |
| |
| #player { |
| position: absolute; |
| width: 60px; |
| height: 100px; |
| background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 150"><polygon points="50,0 0,100 20,100 50,30 80,100 100,100" fill="%23ffe81f"/><rect x="40" y="100" width="20" height="50" fill="%23ffe81f"/></svg>'); |
| background-repeat: no-repeat; |
| z-index: 10; |
| transition: transform 0.1s; |
| left: 50%; |
| bottom: 100px; |
| transform: translateX(-50%); |
| } |
| |
| .asteroid { |
| position: absolute; |
| width: 50px; |
| height: 50px; |
| background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="50" r="45" fill="%23666"/><path d="M30,30 Q40,20 50,30 Q60,20 70,30 Q75,40 70,50 Q75,60 70,70 Q60,75 50,70 Q40,75 30,70 Q25,60 30,50 Q25,40 30,30" fill="%23444"/></svg>'); |
| background-repeat: no-repeat; |
| z-index: 5; |
| } |
| |
| .powerup { |
| position: absolute; |
| width: 40px; |
| height: 40px; |
| background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="50" r="40" fill="%2300ff00"/><circle cx="50" cy="50" r="30" fill="%23ffffff"/><circle cx="50" cy="50" r="20" fill="%2300ff00"/><circle cx="50" cy="50" r="10" fill="%23ffffff"/></svg>'); |
| background-repeat: no-repeat; |
| z-index: 5; |
| animation: pulse 1s infinite; |
| } |
| |
| #hud { |
| position: absolute; |
| top: 20px; |
| left: 20px; |
| z-index: 20; |
| font-family: 'Orbitron', sans-serif; |
| color: #ffe81f; |
| display: flex; |
| gap: 30px; |
| } |
| |
| .hud-item { |
| background-color: rgba(0, 0, 0, 0.7); |
| padding: 10px 20px; |
| border: 1px solid #ffe81f; |
| border-radius: 5px; |
| display: flex; |
| align-items: center; |
| gap: 10px; |
| } |
| |
| .laser { |
| position: absolute; |
| width: 5px; |
| height: 30px; |
| background-color: red; |
| z-index: 6; |
| border-radius: 5px; |
| box-shadow: 0 0 10px red; |
| } |
| |
| .explosion { |
| position: absolute; |
| width: 80px; |
| height: 80px; |
| background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="50" r="40" fill="%23ff0"/><path d="M30,30 Q50,10 70,30 Q90,50 70,70 Q50,90 30,70 Q10,50 30,30" fill="%23f00"/><path d="M40,40 Q50,30 60,40 Q70,50 60,60 Q50,70 40,60 Q30,50 40,40" fill="%23ff0"/></svg>'); |
| background-repeat: no-repeat; |
| z-index: 15; |
| animation: explosion 0.5s forwards; |
| } |
| |
| @keyframes explosion { |
| 0% { transform: scale(0); opacity: 1; } |
| 100% { transform: scale(2); opacity: 0; } |
| } |
| |
| #score-display { |
| font-size: 2rem; |
| position: absolute; |
| top: 20px; |
| right: 20px; |
| background-color: rgba(0, 0, 0, 0.7); |
| padding: 10px 20px; |
| border: 1px solid #ffe81f; |
| border-radius: 5px; |
| font-family: 'Orbitron', sans-serif; |
| color: #ffe81f; |
| } |
| |
| #audio-toggle { |
| position: absolute; |
| bottom: 20px; |
| right: 20px; |
| z-index: 100; |
| background: rgba(0, 0, 0, 0.7); |
| border: 1px solid #ffe81f; |
| color: #ffe81f; |
| width: 50px; |
| height: 50px; |
| border-radius: 50%; |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| cursor: pointer; |
| font-size: 1.5rem; |
| } |
| |
| .instructions { |
| color: #ffe81f; |
| font-family: 'Prompt', sans-serif; |
| margin-top: 2rem; |
| max-width: 600px; |
| padding: 0 2rem; |
| } |
| |
| .instructions h2 { |
| margin-bottom: 1rem; |
| color: #00ff00; |
| } |
| |
| .controls { |
| display: flex; |
| gap: 20px; |
| margin-top: 1rem; |
| } |
| |
| .control-key { |
| background: rgba(255, 255, 255, 0.2); |
| border: 1px solid #ffe81f; |
| padding: 5px 10px; |
| border-radius: 5px; |
| font-family: 'Orbitron', sans-serif; |
| } |
| </style> |
| </head> |
| <body> |
| <div id="game-container"> |
| <div class="stars"></div> |
| |
| <div id="intro-screen"> |
| <h1 class="title">STAR WARS</h1> |
| <h2 class="title" style="font-size: 2rem;">ASTEROID EVASION</h2> |
| |
| <div class="scroll-text"> |
| <div class="scroll-content"> |
| <p>Episode IV</p> |
| <p>A NEW GAME</p> |
| <br> |
| <p>The galaxy is in turmoil as Rebel forces attempt to outrun the Imperial fleet through an asteroid field.</p> |
| <br> |
| <p>As a skilled pilot, your mission is to navigate the treacherous field, collecting power-ups to sustain your ship.</p> |
| <br> |
| <p>Beware of the asteroids that float menacingly through space - a single collision could mean the end of your journey...</p> |
| </div> |
| </div> |
| |
| <button class="btn" id="start-game">BEGIN MISSION</button> |
| |
| <div class="instructions"> |
| <h2>Mission Controls:</h2> |
| <p>Use WASD or arrow keys to navigate your ship through the asteroid field.</p> |
| <p>Collect power-ups to increase your score and survive longer.</p> |
| <p>Press SPACE to fire lasers and destroy incoming asteroids.</p> |
| |
| <div class="controls"> |
| <span class="control-key"><i class="fas fa-arrow-up"></i> / W</span> |
| <span class="control-key"><i class="fas fa-arrow-left"></i> / A</span> |
| <span class="control-key"><i class="fas fa-arrow-down"></i> / S</span> |
| <span class="control-key"><i class="fas fa-arrow-right"></i> / D</span> |
| <span class="control-key"><i class="fas fa-star"></i> SPACE</span> |
| </div> |
| </div> |
| </div> |
| |
| <div id="game-screen"> |
| <div id="hud"> |
| <div class="hud-item"> |
| <i class="fas fa-heart" style="color: red;"></i> |
| <span id="lives">3</span> |
| </div> |
| <div class="hud-item"> |
| <i class="fas fa-bolt" style="color: #00ff00;"></i> |
| <span id="energy">100%</span> |
| </div> |
| </div> |
| |
| <div id="score-display">SCORE: 0</div> |
| |
| <div id="player"></div> |
| </div> |
| |
| <div id="game-over-screen" style="display: none;"> |
| <h1 class="title">GAME OVER</h1> |
| <p style="font-size: 1.5rem; margin-bottom: 1rem;">Final Score: <span id="final-score">0</span></p> |
| <button class="btn" id="restart-game">RETRY MISSION</button> |
| </div> |
| |
| <div id="audio-toggle"> |
| <i class="fas fa-volume-up"></i> |
| </div> |
| |
| <audio id="theme-music" loop> |
| <source src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3" type="audio/mpeg"> |
| Your browser does not support the audio element. |
| </audio> |
| |
| <audio id="laser-sound"> |
| <source src="https://www.soundjay.com/buttons/sounds/button-09.mp3" type="audio/mpeg"> |
| </audio> |
| |
| <audio id="explosion-sound"> |
| <source src="https://www.soundjay.com/explosion-sounds/explosion-01.mp3" type="audio/mpeg"> |
| </audio> |
| |
| <audio id="powerup-sound"> |
| <source src="https://www.soundjay.com/buttons/sounds/button-21.mp3" type="audio/mpeg"> |
| </audio> |
| </div> |
|
|
| <script> |
| |
| let gameActive = false; |
| let score = 0; |
| let lives = 3; |
| let energy = 100; |
| let playerSpeed = 5; |
| let energyDrain = 0.1; |
| let asteroids = []; |
| let powerups = []; |
| let lasers = []; |
| let gameSpeed = 1; |
| let asteroidSpawnRate = 2500; |
| let powerupSpawnRate = 8000; |
| let lastAsteroidSpawn = 0; |
| let lastPowerupSpawn = 0; |
| let keys = {}; |
| let audioEnabled = true; |
| let difficultyIncreaseInterval; |
| |
| |
| const introScreen = document.getElementById('intro-screen'); |
| const gameScreen = document.getElementById('game-screen'); |
| const gameOverScreen = document.getElementById('game-over-screen'); |
| const startButton = document.getElementById('start-game'); |
| const restartButton = document.getElementById('restart-game'); |
| const player = document.getElementById('player'); |
| const livesDisplay = document.getElementById('lives'); |
| const energyDisplay = document.getElementById('energy'); |
| const scoreDisplay = document.getElementById('score-display'); |
| const finalScoreDisplay = document.getElementById('final-score'); |
| const themeMusic = document.getElementById('theme-music'); |
| const laserSound = document.getElementById('laser-sound'); |
| const explosionSound = document.getElementById('explosion-sound'); |
| const powerupSound = document.getElementById('powerup-sound'); |
| const audioToggle = document.getElementById('audio-toggle'); |
| const gameContainer = document.getElementById('game-container'); |
| |
| |
| const PLAYER_WIDTH = 60; |
| const PLAYER_HEIGHT = 100; |
| const GAME_WIDTH = window.innerWidth; |
| const GAME_HEIGHT = window.innerHeight; |
| |
| |
| function initGame() { |
| |
| score = 0; |
| lives = 3; |
| energy = 100; |
| gameSpeed = 1; |
| asteroidSpawnRate = 2500; |
| |
| |
| asteroids.forEach(asteroid => asteroid.element.remove()); |
| powerups.forEach(powerup => powerup.element.remove()); |
| lasers.forEach(laser => laser.element.remove()); |
| |
| asteroids = []; |
| powerups = []; |
| lasers = []; |
| |
| |
| updateHUD(); |
| |
| |
| player.style.left = '50%'; |
| player.style.bottom = '100px'; |
| player.style.transform = 'translateX(-50%)'; |
| |
| |
| introScreen.style.display = 'none'; |
| gameOverScreen.style.display = 'none'; |
| gameScreen.style.display = 'block'; |
| |
| |
| gameActive = true; |
| startGameLoop(); |
| |
| |
| if (difficultyIncreaseInterval) clearInterval(difficultyIncreaseInterval); |
| difficultyIncreaseInterval = setInterval(increaseDifficulty, 10000); |
| |
| |
| if (audioEnabled) { |
| themeMusic.currentTime = 0; |
| themeMusic.play(); |
| } |
| |
| |
| gameScreen.focus(); |
| } |
| |
| |
| function gameLoop(timestamp) { |
| if (!gameActive) return; |
| |
| |
| movePlayer(); |
| |
| |
| if (timestamp - lastAsteroidSpawn > asteroidSpawnRate) { |
| spawnAsteroid(); |
| lastAsteroidSpawn = timestamp; |
| } |
| |
| |
| if (timestamp - lastPowerupSpawn > powerupSpawnRate) { |
| spawnPowerup(); |
| lastPowerupSpawn = timestamp; |
| } |
| |
| |
| updateAsteroids(); |
| |
| |
| updatePowerups(); |
| |
| |
| updateLasers(); |
| |
| |
| checkCollisions(); |
| |
| |
| energy -= energyDrain; |
| if (energy <= 0) { |
| energy = 0; |
| loseLife(); |
| } |
| |
| |
| updateHUD(); |
| |
| |
| requestAnimationFrame(gameLoop); |
| } |
| |
| function startGameLoop() { |
| requestAnimationFrame(gameLoop); |
| } |
| |
| |
| function movePlayer() { |
| const playerRect = player.getBoundingClientRect(); |
| const gameRect = gameContainer.getBoundingClientRect(); |
| let moveX = 0; |
| let moveY = 0; |
| |
| |
| if ((keys['ArrowLeft'] || keys['a'] || keys['A']) && playerRect.left > gameRect.left) { |
| moveX = -playerSpeed; |
| } |
| if ((keys['ArrowRight'] || keys['d'] || keys['D']) && playerRect.right < gameRect.right) { |
| moveX = playerSpeed; |
| } |
| |
| |
| if ((keys['ArrowUp'] || keys['w'] || keys['W']) && playerRect.top > gameRect.top) { |
| moveY = -playerSpeed; |
| } |
| if ((keys['ArrowDown'] || keys['s'] || keys['S']) && playerRect.bottom < gameRect.bottom) { |
| moveY = playerSpeed; |
| } |
| |
| |
| const currentLeft = parseFloat(player.style.left) || (GAME_WIDTH / 2 - PLAYER_WIDTH / 2); |
| const currentBottom = parseFloat(player.style.bottom) || 100; |
| |
| player.style.left = `${currentLeft + moveX}px`; |
| player.style.bottom = `${currentBottom + moveY}px`; |
| |
| |
| if (moveX !== 0) { |
| player.style.transform = `translateX(0) rotate(${moveX * 2}deg)`; |
| } else { |
| player.style.transform = 'translateX(0) rotate(0deg)'; |
| } |
| } |
| |
| |
| function spawnAsteroid() { |
| const asteroid = document.createElement('div'); |
| asteroid.className = 'asteroid'; |
| asteroid.style.width = `${Math.random() * 50 + 30}px`; |
| asteroid.style.height = asteroid.style.width; |
| |
| const x = Math.random() * (GAME_WIDTH - 100) + 50; |
| const speed = Math.random() * 3 + 2 * gameSpeed; |
| |
| asteroid.style.left = `${x}px`; |
| asteroid.style.top = '-100px'; |
| |
| gameScreen.appendChild(asteroid); |
| |
| asteroids.push({ |
| element: asteroid, |
| x: x, |
| y: -100, |
| speed: speed, |
| width: parseInt(asteroid.style.width), |
| height: parseInt(asteroid.style.height) |
| }); |
| } |
| |
| |
| function spawnPowerup() { |
| const powerup = document.createElement('div'); |
| powerup.className = 'powerup'; |
| |
| const x = Math.random() * (GAME_WIDTH - 50) + 25; |
| const speed = Math.random() * 2 + 1 * gameSpeed; |
| |
| powerup.style.left = `${x}px`; |
| powerup.style.top = '-50px'; |
| |
| gameScreen.appendChild(powerup); |
| |
| powerups.push({ |
| element: powerup, |
| x: x, |
| y: -50, |
| speed: speed, |
| width: 40, |
| height: 40 |
| }); |
| } |
| |
| |
| function updateAsteroids() { |
| const playerRect = player.getBoundingClientRect(); |
| |
| for (let i = asteroids.length - 1; i >= 0; i--) { |
| const asteroid = asteroids[i]; |
| asteroid.y += asteroid.speed; |
| asteroid.element.style.top = `${asteroid.y}px`; |
| |
| |
| if (asteroid.y > GAME_HEIGHT) { |
| asteroid.element.remove(); |
| asteroids.splice(i, 1); |
| score += 5; |
| } |
| } |
| } |
| |
| |
| function updatePowerups() { |
| for (let i = powerups.length - 1; i >= 0; i--) { |
| const powerup = powerups[i]; |
| powerup.y += powerup.speed; |
| powerup.element.style.top = `${powerup.y}px`; |
| |
| |
| if (powerup.y > GAME_HEIGHT) { |
| powerup.element.remove(); |
| powerups.splice(i, 1); |
| } |
| } |
| } |
| |
| |
| function fireLaser() { |
| if (energy < 5) return; |
| |
| energy -= 5; |
| |
| const laser = document.createElement('div'); |
| laser.className = 'laser'; |
| |
| const playerRect = player.getBoundingClientRect(); |
| const x = playerRect.left + playerRect.width / 2 - 2.5; |
| const y = playerRect.top; |
| |
| laser.style.left = `${x}px`; |
| laser.style.top = `${y}px`; |
| |
| gameScreen.appendChild(laser); |
| |
| lasers.push({ |
| element: laser, |
| x: x, |
| y: y, |
| speed: 10 * gameSpeed, |
| width: 5, |
| height: 30 |
| }); |
| |
| if (audioEnabled) { |
| laserSound.currentTime = 0; |
| laserSound.play(); |
| } |
| } |
| |
| |
| function updateLasers() { |
| for (let i = lasers.length - 1; i >= 0; i--) { |
| const laser = lasers[i]; |
| laser.y -= laser.speed; |
| laser.element.style.top = `${laser.y}px`; |
| |
| |
| if (laser.y + laser.height < 0) { |
| laser.element.remove(); |
| lasers.splice(i, 1); |
| } |
| } |
| } |
| |
| |
| function checkCollisions() { |
| const playerRect = player.getBoundingClientRect(); |
| |
| |
| for (let i = lasers.length - 1; i >= 0; i--) { |
| const laser = lasers[i]; |
| const laserRect = laser.element.getBoundingClientRect(); |
| |
| for (let j = asteroids.length - 1; j >= 0; j--) { |
| const asteroid = asteroids[j]; |
| const asteroidRect = asteroid.element.getBoundingClientRect(); |
| |
| if (isColliding(laserRect, asteroidRect)) { |
| |
| createExplosion(asteroid.x + asteroid.width / 2, asteroid.y + asteroid.height / 2); |
| |
| |
| laser.element.remove(); |
| lasers.splice(i, 1); |
| asteroid.element.remove(); |
| asteroids.splice(j, 1); |
| |
| |
| score += 20; |
| |
| |
| if (audioEnabled) { |
| explosionSound.currentTime = 0; |
| explosionSound.play(); |
| } |
| |
| |
| break; |
| } |
| } |
| } |
| |
| |
| for (let i = asteroids.length - 1; i >= 0; i--) { |
| const asteroid = asteroids[i]; |
| const asteroidRect = asteroid.element.getBoundingClientRect(); |
| |
| if (isColliding(playerRect, asteroidRect)) { |
| |
| createExplosion( |
| asteroid.x + asteroid.width / 2, |
| asteroid.y + asteroid.height / 2 |
| ); |
| |
| |
| asteroid.element.remove(); |
| asteroids.splice(i, 1); |
| |
| |
| loseLife(); |
| |
| |
| if (audioEnabled) { |
| explosionSound.currentTime = 0; |
| explosionSound.play(); |
| } |
| |
| |
| player.style.opacity = '0.5'; |
| setTimeout(() => { |
| player.style.opacity = '1'; |
| }, 1000); |
| } |
| } |
| |
| |
| for (let i = powerups.length - 1; i >= 0; i--) { |
| const powerup = powerups[i]; |
| const powerupRect = powerup.element.getBoundingClientRect(); |
| |
| if (isColliding(playerRect, powerupRect)) { |
| |
| powerup.element.remove(); |
| powerups.splice(i, 1); |
| |
| |
| energy = Math.min(100, energy + 20); |
| score += 10; |
| |
| |
| if (audioEnabled) { |
| powerupSound.currentTime = 0; |
| powerupSound.play(); |
| } |
| } |
| } |
| } |
| |
| |
| function isColliding(rect1, rect2) { |
| return !( |
| rect1.right < rect2.left || |
| rect1.left > rect2.right || |
| rect1.bottom < rect2.top || |
| rect1.top > rect2.bottom |
| ); |
| } |
| |
| |
| function createExplosion(x, y) { |
| const explosion = document.createElement('div'); |
| explosion.className = 'explosion'; |
| explosion.style.left = `${x - 40}px`; |
| explosion.style.top = `${y - 40}px`; |
| |
| gameScreen.appendChild(explosion); |
| |
| setTimeout(() => { |
| explosion.remove(); |
| }, 500); |
| } |
| |
| |
| function loseLife() { |
| lives--; |
| |
| if (lives <= 0) { |
| gameOver(); |
| return; |
| } |
| |
| |
| energy = 100; |
| } |
| |
| |
| function gameOver() { |
| gameActive = false; |
| clearInterval(difficultyIncreaseInterval); |
| |
| |
| themeMusic.pause(); |
| |
| |
| gameScreen.style.display = 'none'; |
| gameOverScreen.style.display = 'flex'; |
| finalScoreDisplay.textContent = score; |
| } |
| |
| |
| function updateHUD() { |
| livesDisplay.textContent = lives; |
| energyDisplay.textContent = `${Math.max(0, Math.floor(energy))}%`; |
| scoreDisplay.textContent = `SCORE: ${score}`; |
| } |
| |
| |
| function increaseDifficulty() { |
| gameSpeed += 0.1; |
| asteroidSpawnRate = Math.max(500, asteroidSpawnRate - 100); |
| |
| |
| gameScreen.style.boxShadow = 'inset 0 0 50px rgba(255, 0, 0, 0.5)'; |
| setTimeout(() => { |
| gameScreen.style.boxShadow = 'none'; |
| }, 500); |
| } |
| |
| |
| startButton.addEventListener('click', initGame); |
| restartButton.addEventListener('click', initGame); |
| |
| audioToggle.addEventListener('click', () => { |
| audioEnabled = !audioEnabled; |
| if (audioEnabled) { |
| audioToggle.innerHTML = '<i class="fas fa-volume-up"></i>'; |
| if (gameActive) themeMusic.play(); |
| } else { |
| audioToggle.innerHTML = '<i class="fas fa-volume-mute"></i>'; |
| themeMusic.pause(); |
| } |
| }); |
| |
| window.addEventListener('keydown', (e) => { |
| keys[e.key] = true; |
| |
| |
| if (gameActive && (e.key === ' ' || e.key === 'Spacebar')) { |
| fireLaser(); |
| } |
| }); |
| |
| window.addEventListener('keyup', (e) => { |
| keys[e.key] = false; |
| }); |
| |
| |
| window.addEventListener('keydown', (e) => { |
| if (e.key === ' ' && e.target === document.body) { |
| e.preventDefault(); |
| } |
| }); |
| </script> |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <a href="https://enzostvs-deepsite.hf.space" style="color: #fff;" target="_blank" >DeepSite</a> <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;"></p></body> |
| </html> |