space / index.html
FriedsU's picture
Add 2 files
888ef33 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Galaxy Defender</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
body {
overflow: hidden;
background-color: #000;
font-family: 'Arial', sans-serif;
margin: 0;
padding: 0;
}
#game-container {
position: relative;
width: 800px;
height: 600px;
margin: 20px auto;
background: linear-gradient(to bottom, #000033 0%, #000000 100%);
overflow: hidden;
}
#player {
position: absolute;
width: 50px;
height: 50px;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50"><path d="M25 5 L5 25 L15 25 L15 45 L35 45 L35 25 L45 25 Z" fill="%2300FFFF" stroke="%23FFFFFF" stroke-width="2"/></svg>');
z-index: 10;
}
.enemy {
position: absolute;
width: 40px;
height: 40px;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><path d="M20 5 L5 20 L15 20 L15 35 L25 35 L25 20 L35 20 Z" fill="%23FF0000" stroke="%23FFFFFF" stroke-width="2"/></svg>');
z-index: 5;
}
.bullet {
position: absolute;
width: 5px;
height: 15px;
background-color: #FFFF00;
border-radius: 2px;
z-index: 8;
}
.explosion {
position: absolute;
width: 50px;
height: 50px;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50"><circle cx="25" cy="25" r="20" fill="%23FF9900"/><circle cx="25" cy="25" r="15" fill="%23FF3300"/><circle cx="25" cy="25" r="10" fill="%23FFFF00"/></svg>');
z-index: 15;
animation: explode 0.5s forwards;
}
.powerup {
position: absolute;
width: 30px;
height: 30px;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"><circle cx="15" cy="15" r="12" fill="%2300FF00" stroke="%23FFFFFF" stroke-width="2"/></svg>');
z-index: 7;
animation: pulse 1s infinite alternate;
}
.star {
position: absolute;
background-color: white;
border-radius: 50%;
z-index: 1;
}
#score-display {
position: absolute;
top: 10px;
left: 10px;
font-size: 20px;
color: white;
text-shadow: 0 0 5px #00FFFF;
z-index: 20;
}
#health-display {
position: absolute;
top: 10px;
right: 10px;
font-size: 20px;
color: white;
text-shadow: 0 0 5px #FF0000;
z-index: 20;
}
#level-complete {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: rgba(0, 0, 0, 0.8);
color: #00FF00;
padding: 30px;
border-radius: 15px;
text-align: center;
display: none;
z-index: 100;
font-size: 24px;
border: 2px solid #00FF00;
box-shadow: 0 0 20px #00FF00;
}
#game-over {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: rgba(0, 0, 0, 0.8);
color: #FF0000;
padding: 30px;
border-radius: 15px;
text-align: center;
display: none;
z-index: 100;
font-size: 24px;
border: 2px solid #FF0000;
box-shadow: 0 0 20px #FF0000;
}
#restart-btn {
background: linear-gradient(to bottom, #FF3300 0%, #990000 100%);
color: white;
border: none;
padding: 10px 20px;
margin-top: 20px;
border-radius: 5px;
cursor: pointer;
font-size: 18px;
text-shadow: 0 0 5px #000;
}
#restart-btn:hover {
background: linear-gradient(to bottom, #FF5500 0%, #BB0000 100%);
}
@keyframes explode {
0% { transform: scale(0.5); opacity: 1; }
100% { transform: scale(2); opacity: 0; }
}
@keyframes pulse {
0% { transform: scale(1); }
100% { transform: scale(1.2); }
}
#boss {
position: absolute;
width: 80px;
height: 80px;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 80"><path d="M40 10 L10 40 L30 40 L30 70 L50 70 L50 40 L70 40 Z" fill="%23FF00FF" stroke="%23FFFFFF" stroke-width="3"/></svg>');
z-index: 6;
}
</style>
</head>
<body class="flex flex-col items-center justify-center min-h-screen bg-black">
<h1 class="text-4xl font-bold mb-4 text-blue-400 text-center" style="text-shadow: 0 0 10px #00FFFF;">GALAXY DEFENDER</h1>
<div id="game-container">
<div id="player"></div>
<div id="score-display">SCORE: 0</div>
<div id="health-display">HEALTH: 100%</div>
<div id="level-complete">
<h2 class="text-3xl font-bold mb-4">LEVEL COMPLETE!</h2>
<p id="final-score">Your score: 0</p>
<button id="restart-btn">Play Again</button>
</div>
<div id="game-over">
<h2 class="text-3xl font-bold mb-4">GAME OVER</h2>
<p id="game-over-score">Your score: 0</p>
<button id="restart-btn">Try Again</button>
</div>
</div>
<div class="mt-4 text-gray-400 text-center">
<p>Arrow keys to move | Space to shoot | Collect green power-ups</p>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
// Game elements
const gameContainer = document.getElementById('game-container');
const player = document.getElementById('player');
const scoreDisplay = document.getElementById('score-display');
const healthDisplay = document.getElementById('health-display');
const levelCompleteScreen = document.getElementById('level-complete');
const gameOverScreen = document.getElementById('game-over');
const finalScoreDisplay = document.getElementById('final-score');
const gameOverScoreDisplay = document.getElementById('game-over-score');
const restartBtns = document.querySelectorAll('#restart-btn');
// Game state
let score = 0;
let health = 100;
let gameRunning = true;
let levelComplete = false;
let playerX = 375;
let playerY = 500;
let playerSpeed = 8;
let bullets = [];
let enemies = [];
let explosions = [];
let powerups = [];
let stars = [];
let keys = {};
let lastShotTime = 0;
let shotDelay = 300; // ms
let enemySpawnTimer = 0;
let enemySpawnDelay = 1000; // ms
let powerupSpawnTimer = 0;
let powerupSpawnDelay = 8000; // ms
let bossActive = false;
let bossHealth = 10;
// Game dimensions
const gameWidth = gameContainer.offsetWidth;
const gameHeight = gameContainer.offsetHeight;
const playerWidth = 50;
const playerHeight = 50;
// Initialize player position
player.style.left = `${playerX}px`;
player.style.top = `${playerY}px`;
// Create background stars
function createStars() {
for (let i = 0; i < 100; i++) {
const star = document.createElement('div');
star.className = 'star';
const size = Math.random() * 3;
const x = Math.random() * gameWidth;
const y = Math.random() * gameHeight;
const opacity = Math.random();
star.style.width = `${size}px`;
star.style.height = `${size}px`;
star.style.left = `${x}px`;
star.style.top = `${y}px`;
star.style.opacity = opacity;
gameContainer.appendChild(star);
stars.push({
element: star,
x: x,
y: y,
speed: 0.5 + Math.random() * 2
});
}
}
// Event listeners for keyboard
document.addEventListener('keydown', (e) => {
keys[e.key] = true;
// Space to shoot
if (e.key === ' ' && gameRunning && !levelComplete) {
const now = Date.now();
if (now - lastShotTime > shotDelay) {
shoot();
lastShotTime = now;
}
}
});
document.addEventListener('keyup', (e) => {
keys[e.key] = false;
});
restartBtns.forEach(btn => {
btn.addEventListener('click', restartGame);
});
// Create initial game elements
function initGame() {
createStars();
spawnEnemyWave(5);
}
// Create a bullet
function shoot() {
const bullet = document.createElement('div');
bullet.className = 'bullet';
bullet.style.left = `${playerX + playerWidth / 2 - 2}px`;
bullet.style.top = `${playerY - 15}px`;
gameContainer.appendChild(bullet);
bullets.push({
element: bullet,
x: playerX + playerWidth / 2 - 2,
y: playerY - 15,
speed: 10
});
}
// Spawn a wave of enemies
function spawnEnemyWave(count) {
for (let i = 0; i < count; i++) {
setTimeout(() => {
if (!gameRunning || levelComplete) return;
const enemy = document.createElement('div');
enemy.className = 'enemy';
const x = Math.random() * (gameWidth - 40);
const y = -40;
enemy.style.left = `${x}px`;
enemy.style.top = `${y}px`;
gameContainer.appendChild(enemy);
enemies.push({
element: enemy,
x: x,
y: y,
speed: 2 + Math.random() * 2,
health: 1
});
}, i * 500);
}
}
// Spawn a boss enemy
function spawnBoss() {
if (bossActive) return;
bossActive = true;
const boss = document.createElement('div');
boss.id = 'boss';
const x = gameWidth / 2 - 40;
const y = -80;
boss.style.left = `${x}px`;
boss.style.top = `${y}px`;
gameContainer.appendChild(boss);
enemies.push({
element: boss,
x: x,
y: y,
speed: 1.5,
health: bossHealth,
isBoss: true
});
}
// Spawn a powerup
function spawnPowerup() {
const powerup = document.createElement('div');
powerup.className = 'powerup';
const x = Math.random() * (gameWidth - 30);
const y = -30;
powerup.style.left = `${x}px`;
powerup.style.top = `${y}px`;
gameContainer.appendChild(powerup);
powerups.push({
element: powerup,
x: x,
y: y,
speed: 3
});
}
// Create explosion effect
function createExplosion(x, y) {
const explosion = document.createElement('div');
explosion.className = 'explosion';
explosion.style.left = `${x - 25}px`;
explosion.style.top = `${y - 25}px`;
gameContainer.appendChild(explosion);
explosions.push({
element: explosion,
time: 0
});
// Remove explosion after animation
setTimeout(() => {
gameContainer.removeChild(explosion);
}, 500);
}
// Game loop
function gameLoop() {
if (!gameRunning) return;
// Handle player movement
handleMovement();
// Update bullets
updateBullets();
// Update enemies
updateEnemies();
// Update powerups
updatePowerups();
// Update stars (parallax background)
updateStars();
// Spawn new enemies periodically
enemySpawnTimer += 16; // ~60fps
if (enemySpawnTimer >= enemySpawnDelay) {
if (enemies.length < 10) {
spawnEnemyWave(3);
}
enemySpawnTimer = 0;
// Spawn boss after certain score
if (score >= 500 && !bossActive) {
spawnBoss();
}
}
// Spawn powerups periodically
powerupSpawnTimer += 16;
if (powerupSpawnTimer >= powerupSpawnDelay) {
spawnPowerup();
powerupSpawnTimer = 0;
}
// Check for level completion (after boss is defeated)
if (bossActive && enemies.length === 0) {
levelComplete = true;
showLevelComplete();
}
requestAnimationFrame(gameLoop);
}
// Handle player movement based on keyboard input
function handleMovement() {
if (keys['ArrowLeft'] || keys['a']) {
playerX = Math.max(0, playerX - playerSpeed);
}
if (keys['ArrowRight'] || keys['d']) {
playerX = Math.min(gameWidth - playerWidth, playerX + playerSpeed);
}
if (keys['ArrowUp'] || keys['w']) {
playerY = Math.max(0, playerY - playerSpeed);
}
if (keys['ArrowDown'] || keys['s']) {
playerY = Math.min(gameHeight - playerHeight, playerY + playerSpeed);
}
player.style.left = `${playerX}px`;
player.style.top = `${playerY}px`;
}
// Update all active bullets
function updateBullets() {
for (let i = bullets.length - 1; i >= 0; i--) {
const bullet = bullets[i];
bullet.y -= bullet.speed;
bullet.element.style.top = `${bullet.y}px`;
// Remove bullets that go off screen
if (bullet.y < -15) {
gameContainer.removeChild(bullet.element);
bullets.splice(i, 1);
}
}
}
// Update all active enemies
function updateEnemies() {
for (let i = enemies.length - 1; i >= 0; i--) {
const enemy = enemies[i];
enemy.y += enemy.speed;
enemy.element.style.top = `${enemy.y}px`;
// Remove enemies that go off screen
if (enemy.y > gameHeight) {
gameContainer.removeChild(enemy.element);
enemies.splice(i, 1);
}
// Check for bullet collisions
for (let j = bullets.length - 1; j >= 0; j--) {
const bullet = bullets[j];
if (checkCollision(bullet, enemy)) {
// Hit enemy
enemy.health--;
// Remove bullet
gameContainer.removeChild(bullet.element);
bullets.splice(j, 1);
// Create explosion if enemy is destroyed
if (enemy.health <= 0) {
createExplosion(enemy.x + 20, enemy.y + 20);
gameContainer.removeChild(enemy.element);
enemies.splice(i, 1);
// Add score
const points = enemy.isBoss ? 200 : 50;
score += points;
scoreDisplay.textContent = `SCORE: ${score}`;
// Check if boss was defeated
if (enemy.isBoss) {
bossActive = false;
}
}
break;
}
}
// Check for player collision
if (checkCollision({x: playerX, y: playerY, width: playerWidth, height: playerHeight}, enemy)) {
createExplosion(enemy.x + 20, enemy.y + 20);
gameContainer.removeChild(enemy.element);
enemies.splice(i, 1);
// Reduce player health
health -= enemy.isBoss ? 30 : 10;
health = Math.max(0, health);
healthDisplay.textContent = `HEALTH: ${health}%`;
if (health <= 0) {
gameOver();
}
}
}
}
// Update all active 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 powerups that go off screen
if (powerup.y > gameHeight) {
gameContainer.removeChild(powerup.element);
powerups.splice(i, 1);
}
// Check for player collision
if (checkCollision({x: playerX, y: playerY, width: playerWidth, height: playerHeight}, powerup)) {
gameContainer.removeChild(powerup.element);
powerups.splice(i, 1);
// Apply powerup effect
health = Math.min(100, health + 20);
healthDisplay.textContent = `HEALTH: ${health}%`;
// Temporary speed boost
const originalSpeed = playerSpeed;
playerSpeed = 12;
setTimeout(() => {
playerSpeed = originalSpeed;
}, 5000);
}
}
}
// Update background stars
function updateStars() {
for (let i = 0; i < stars.length; i++) {
const star = stars[i];
star.y += star.speed;
if (star.y > gameHeight) {
star.y = 0;
star.x = Math.random() * gameWidth;
}
star.element.style.top = `${star.y}px`;
}
}
// Check collision between two objects
function checkCollision(obj1, obj2) {
const obj1Width = obj1.width || 40;
const obj1Height = obj1.height || 40;
const obj2Width = obj2.width || 40;
const obj2Height = obj2.height || 40;
return (
obj1.x < obj2.x + obj2Width &&
obj1.x + obj1Width > obj2.x &&
obj1.y < obj2.y + obj2Height &&
obj1.y + obj1Height > obj2.y
);
}
// Show level complete screen
function showLevelComplete() {
gameRunning = false;
finalScoreDisplay.textContent = `Your score: ${score}`;
levelCompleteScreen.style.display = 'block';
}
// Game over function
function gameOver() {
gameRunning = false;
gameOverScoreDisplay.textContent = `Your score: ${score}`;
gameOverScreen.style.display = 'block';
// Create explosion at player position
createExplosion(playerX + 25, playerY + 25);
player.style.display = 'none';
}
// Restart game function
function restartGame() {
// Reset game state
score = 0;
health = 100;
gameRunning = true;
levelComplete = false;
bossActive = false;
playerX = 375;
playerY = 500;
playerSpeed = 8;
// Reset displays
scoreDisplay.textContent = `SCORE: 0`;
healthDisplay.textContent = `HEALTH: 100%`;
player.style.display = 'block';
player.style.left = `${playerX}px`;
player.style.top = `${playerY}px`;
// Hide screens
levelCompleteScreen.style.display = 'none';
gameOverScreen.style.display = 'none';
// Clear all game elements
bullets.forEach(bullet => {
gameContainer.removeChild(bullet.element);
});
enemies.forEach(enemy => {
gameContainer.removeChild(enemy.element);
});
powerups.forEach(powerup => {
gameContainer.removeChild(powerup.element);
});
stars.forEach(star => {
gameContainer.removeChild(star.element);
});
// Clear arrays
bullets = [];
enemies = [];
powerups = [];
stars = [];
// Create new game elements
initGame();
// Start game
requestAnimationFrame(gameLoop);
}
// Start the game
initGame();
gameLoop();
});
</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 <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=FriedsU/space" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>