asteroid / index.html
LuciferDS's picture
Add 2 files
838c27a verified
<!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>
// Game variables
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;
// DOM elements
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');
// Game constants
const PLAYER_WIDTH = 60;
const PLAYER_HEIGHT = 100;
const GAME_WIDTH = window.innerWidth;
const GAME_HEIGHT = window.innerHeight;
// Initialize game
function initGame() {
// Reset variables
score = 0;
lives = 3;
energy = 100;
gameSpeed = 1;
asteroidSpawnRate = 2500;
// Clear any existing game elements
asteroids.forEach(asteroid => asteroid.element.remove());
powerups.forEach(powerup => powerup.element.remove());
lasers.forEach(laser => laser.element.remove());
asteroids = [];
powerups = [];
lasers = [];
// Update displays
updateHUD();
// Position player
player.style.left = '50%';
player.style.bottom = '100px';
player.style.transform = 'translateX(-50%)';
// Show game screen
introScreen.style.display = 'none';
gameOverScreen.style.display = 'none';
gameScreen.style.display = 'block';
// Start game loop
gameActive = true;
startGameLoop();
// Start difficulty increase
if (difficultyIncreaseInterval) clearInterval(difficultyIncreaseInterval);
difficultyIncreaseInterval = setInterval(increaseDifficulty, 10000);
// Play theme music if audio is enabled
if (audioEnabled) {
themeMusic.currentTime = 0;
themeMusic.play();
}
// Focus the game screen for keyboard input
gameScreen.focus();
}
// Game loop
function gameLoop(timestamp) {
if (!gameActive) return;
// Movement
movePlayer();
// Spawn asteroids
if (timestamp - lastAsteroidSpawn > asteroidSpawnRate) {
spawnAsteroid();
lastAsteroidSpawn = timestamp;
}
// Spawn powerups
if (timestamp - lastPowerupSpawn > powerupSpawnRate) {
spawnPowerup();
lastPowerupSpawn = timestamp;
}
// Update asteroids
updateAsteroids();
// Update powerups
updatePowerups();
// Update lasers
updateLasers();
// Check collisions
checkCollisions();
// Drain energy
energy -= energyDrain;
if (energy <= 0) {
energy = 0;
loseLife();
}
// Update HUD
updateHUD();
// Continue loop
requestAnimationFrame(gameLoop);
}
function startGameLoop() {
requestAnimationFrame(gameLoop);
}
// Player movement
function movePlayer() {
const playerRect = player.getBoundingClientRect();
const gameRect = gameContainer.getBoundingClientRect();
let moveX = 0;
let moveY = 0;
// Horizontal movement
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;
}
// Vertical movement
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;
}
// Apply movement
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`;
// Tilt effect when moving
if (moveX !== 0) {
player.style.transform = `translateX(0) rotate(${moveX * 2}deg)`;
} else {
player.style.transform = 'translateX(0) rotate(0deg)';
}
}
// Spawn asteroid
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)
});
}
// Spawn powerup
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
});
}
// Update asteroids
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`;
// Remove if out of bounds
if (asteroid.y > GAME_HEIGHT) {
asteroid.element.remove();
asteroids.splice(i, 1);
score += 5;
}
}
}
// Update powerups
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`;
// Remove if out of bounds
if (powerup.y > GAME_HEIGHT) {
powerup.element.remove();
powerups.splice(i, 1);
}
}
}
// Fire laser
function fireLaser() {
if (energy < 5) return; // Need at least 5 energy to fire
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();
}
}
// Update lasers
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`;
// Remove if out of bounds
if (laser.y + laser.height < 0) {
laser.element.remove();
lasers.splice(i, 1);
}
}
}
// Check collisions
function checkCollisions() {
const playerRect = player.getBoundingClientRect();
// Check laser-asteroid collisions
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)) {
// Create explosion
createExplosion(asteroid.x + asteroid.width / 2, asteroid.y + asteroid.height / 2);
// Remove both objects
laser.element.remove();
lasers.splice(i, 1);
asteroid.element.remove();
asteroids.splice(j, 1);
// Increase score
score += 20;
// Play explosion sound
if (audioEnabled) {
explosionSound.currentTime = 0;
explosionSound.play();
}
// Break outer loop if laser is destroyed
break;
}
}
}
// Check player-asteroid collisions
for (let i = asteroids.length - 1; i >= 0; i--) {
const asteroid = asteroids[i];
const asteroidRect = asteroid.element.getBoundingClientRect();
if (isColliding(playerRect, asteroidRect)) {
// Create explosion
createExplosion(
asteroid.x + asteroid.width / 2,
asteroid.y + asteroid.height / 2
);
// Remove asteroid
asteroid.element.remove();
asteroids.splice(i, 1);
// Lose life
loseLife();
// Play explosion sound
if (audioEnabled) {
explosionSound.currentTime = 0;
explosionSound.play();
}
// Short invincibility
player.style.opacity = '0.5';
setTimeout(() => {
player.style.opacity = '1';
}, 1000);
}
}
// Check player-powerup collisions
for (let i = powerups.length - 1; i >= 0; i--) {
const powerup = powerups[i];
const powerupRect = powerup.element.getBoundingClientRect();
if (isColliding(playerRect, powerupRect)) {
// Remove powerup
powerup.element.remove();
powerups.splice(i, 1);
// Increase energy
energy = Math.min(100, energy + 20);
score += 10;
// Play powerup sound
if (audioEnabled) {
powerupSound.currentTime = 0;
powerupSound.play();
}
}
}
}
// Collision detection
function isColliding(rect1, rect2) {
return !(
rect1.right < rect2.left ||
rect1.left > rect2.right ||
rect1.bottom < rect2.top ||
rect1.top > rect2.bottom
);
}
// Create explosion
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);
}
// Lose life
function loseLife() {
lives--;
if (lives <= 0) {
gameOver();
return;
}
// Reset energy
energy = 100;
}
// Game over
function gameOver() {
gameActive = false;
clearInterval(difficultyIncreaseInterval);
// Stop theme music
themeMusic.pause();
// Show game over screen
gameScreen.style.display = 'none';
gameOverScreen.style.display = 'flex';
finalScoreDisplay.textContent = score;
}
// Update HUD
function updateHUD() {
livesDisplay.textContent = lives;
energyDisplay.textContent = `${Math.max(0, Math.floor(energy))}%`;
scoreDisplay.textContent = `SCORE: ${score}`;
}
// Increase difficulty
function increaseDifficulty() {
gameSpeed += 0.1;
asteroidSpawnRate = Math.max(500, asteroidSpawnRate - 100);
// Flash screen to indicate increased difficulty
gameScreen.style.boxShadow = 'inset 0 0 50px rgba(255, 0, 0, 0.5)';
setTimeout(() => {
gameScreen.style.boxShadow = 'none';
}, 500);
}
// Event listeners
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;
// Space to fire laser
if (gameActive && (e.key === ' ' || e.key === 'Spacebar')) {
fireLaser();
}
});
window.addEventListener('keyup', (e) => {
keys[e.key] = false;
});
// Prevent space from scrolling page
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>