<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Galaxy Survivor</title>
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
background: #080b18;
color: white;
font-family: Arial, sans-serif;
overflow: hidden;
}
canvas {
display: block;
margin: auto;
background: linear-gradient(#111936, #070914);
border: 3px solid #3949ab;
box-shadow: 0 0 30px #3949ab;
}
#menu {
position: fixed;
inset: 0;
background: rgba(5, 7, 20, 0.95);
display: flex;
justify-content: center;
align-items: center;
z-index: 10;
}
.panel {
text-align: center;
background: #111936;
padding: 40px;
border-radius: 20px;
border: 2px solid #536dfe;
box-shadow: 0 0 40px #536dfe;
width: 450px;
}
h1 {
font-size: 48px;
margin: 0 0 10px;
color: #7c4dff;
text-shadow: 0 0 20px #7c4dff;
}
button {
background: #536dfe;
color: white;
border: none;
padding: 15px 35px;
margin-top: 20px;
border-radius: 10px;
font-size: 20px;
cursor: pointer;
}
button:hover {
background: #7c4dff;
transform: scale(1.05);
}
#hud {
position: fixed;
top: 15px;
left: 15px;
z-index: 5;
font-size: 18px;
line-height: 1.6;
background: rgba(0,0,0,.45);
padding: 12px;
border-radius: 10px;
}
.bar {
width: 220px;
height: 18px;
background: #333;
border-radius: 10px;
overflow: hidden;
margin-top: 5px;
}
#healthBar {
height: 100%;
background: #00e676;
width: 100%;
}
#xpBar {
height: 100%;
background: #2979ff;
width: 0%;
}
#gameOver {
display: none;
position: fixed;
inset: 0;
background: rgba(0,0,0,.9);
z-index: 20;
justify-content: center;
align-items: center;
text-align: center;
}
#gameOver h2 {
font-size: 60px;
color: #ff1744;
}
.mobileControls {
display: none;
}
@media (max-width: 700px) {
canvas {
width: 100%;
height: auto;
}
.mobileControls {
display: block;
position: fixed;
bottom: 20px;
left: 20px;
z-index: 8;
}
.mobileControls button {
width: 60px;
height: 60px;
padding: 0;
margin: 3px;
font-size: 20px;
}
}
</style>
</head>
<body>
<div id="menu">
<div class="panel">
<h1>GALAXY SURVIVOR</h1>
<p>Überlebe so lange wie möglich!</p>
<p>
<b>WASD / Pfeiltasten</b> = Bewegen<br>
<b>Leertaste</b> = Schießen
</p>
<button onclick="startGame()">SPIEL STARTEN</button>
</div>
</div>
<div id="hud">
❤️ Leben:
<div class="bar">
<div id="healthBar"></div>
</div>
⭐ XP:
<div class="bar">
<div id="xpBar"></div>
</div>
<div>
Level: <span id="level">1</span>
</div>
<div>
Punkte: <span id="score">0</span>
</div>
<div>
Münzen: <span id="coins">0</span>
</div>
<div>
Gegner: <span id="enemyCount">0</span>
</div>
</div>
<canvas id="game" width="1000" height="650"></canvas>
<div class="mobileControls">
<button ontouchstart="keys.w=true" ontouchend="keys.w=false">▲</button><br>
<button ontouchstart="keys.a=true" ontouchend="keys.a=false">◀</button>
<button ontouchstart="keys.s=true" ontouchend="keys.s=false">▼</button>
<button ontouchstart="keys.d=true" ontouchend="keys.d=false">▶</button>
</div>
<div id="gameOver">
<div>
<h2>GAME OVER</h2>
<p>
Punkte: <span id="finalScore">0</span>
</p>
<p>
Level: <span id="finalLevel">1</span>
</p>
<p>
Münzen: <span id="finalCoins">0</span>
</p>
<button onclick="startGame()">NOCHMAL SPIELEN</button>
</div>
</div>
<script>
const canvas = document.getElementById("game");
const ctx = canvas.getContext("2d");
const WIDTH = canvas.width;
const HEIGHT = canvas.height;
let gameRunning = false;
let score = 0;
let coins = 0;
let level = 1;
let xp = 0;
let enemyTimer = 0;
let coinTimer = 0;
let keys = {
w: false,
a: false,
s: false,
d: false,
space: false
};
const player = {
x: WIDTH / 2,
y: HEIGHT / 2,
width: 35,
height: 35,
speed: 5,
health: 100,
maxHealth: 100,
shootCooldown: 0,
damage: 25
};
let bullets = [];
let enemies = [];
let particles = [];
let coinsObjects = [];
let stars = [];
/* =========================
STERNE
========================= */
for (let i = 0; i < 150; i++) {
stars.push({
x: Math.random() * WIDTH,
y: Math.random() * HEIGHT,
size: Math.random() * 2 + 1,
speed: Math.random() * 0.5 + 0.1
});
}
/* =========================
TASTATUR
========================= */
document.addEventListener("keydown", function(event) {
if (event.key === "w" || event.key === "W" || event.key === "ArrowUp") {
keys.w = true;
}
if (event.key === "a" || event.key === "A" || event.key === "ArrowLeft") {
keys.a = true;
}
if (event.key === "s" || event.key === "S" || event.key === "ArrowDown") {
keys.s = true;
}
if (event.key === "d" || event.key === "D" || event.key === "ArrowRight") {
keys.d = true;
}
if (event.code === "Space") {
keys.space = true;
}
});
document.addEventListener("keyup", function(event) {
if (event.key === "w" || event.key === "W" || event.key === "ArrowUp") {
keys.w = false;
}
if (event.key === "a" || event.key === "A" || event.key === "ArrowLeft") {
keys.a = false;
}
if (event.key === "s" || event.key === "S" || event.key === "ArrowDown") {
keys.s = false;
}
if (event.key === "d" || event.key === "D" || event.key === "ArrowRight") {
keys.d = false;
}
if (event.code === "Space") {
keys.space = false;
}
});
/* =========================
SPIEL STARTEN
========================= */
function startGame() {
document.getElementById("menu").style.display = "none";
document.getElementById("gameOver").style.display = "none";
score = 0;
coins = 0;
level = 1;
xp = 0;
player.x = WIDTH / 2;
player.y = HEIGHT / 2;
player.health = 100;
player.maxHealth = 100;
player.damage = 25;
player.speed = 5;
bullets = [];
enemies = [];
particles = [];
coinsObjects = [];
gameRunning = true;
updateHUD();
gameLoop();
}
/* =========================
SPIELER BEWEGUNG
========================= */
function updatePlayer() {
if (keys.w) {
player.y -= player.speed;
}
if (keys.s) {
player.y += player.speed;
}
if (keys.a) {
player.x -= player.speed;
}
if (keys.d) {
player.x += player.speed;
}
// Grenzen
if (player.x < player.width / 2) {
player.x = player.width / 2;
}
if (player.x > WIDTH - player.width / 2) {
player.x = WIDTH - player.width / 2;
}
if (player.y < player.height / 2) {
player.y = player.height / 2;
}
if (player.y > HEIGHT - player.height / 2) {
player.y = HEIGHT - player.height / 2;
}
}
/* =========================
SCHIESSEN
========================= */
function shoot() {
if (player.shootCooldown > 0) {
return;
}
bullets.push({
x: player.x,
y: player.y - 20,
radius: 5,
speed: 10,
damage: player.damage
});
player.shootCooldown = 12;
}
function updateBullets() {
if (player.shootCooldown > 0) {
player.shootCooldown--;
}
if (keys.space) {
shoot();
}
for (let i = bullets.length - 1; i >= 0; i--) {
let bullet = bullets[i];
bullet.y -= bullet.speed;
if (bullet.y < -20) {
bullets.splice(i, 1);
}
}
}
/* =========================
GEGNER ERSTELLEN
========================= */
function spawnEnemy() {
let side = Math.floor(Math.random() * 4);
let x;
let y;
if (side === 0) {
x = Math.random() * WIDTH;
y = -40;
}
if (side === 1) {
x = WIDTH + 40;
y = Math.random() * HEIGHT;
}
if (side === 2) {
x = Math.random() * WIDTH;
y = HEIGHT + 40;
}
if (side === 3) {
x = -40;
y = Math.random() * HEIGHT;
}
let enemyType = Math.random();
let enemy;
if (enemyType < 0.15) {
enemy = {
x,
y,
radius: 28,
speed: 1.2 + level * 0.03,
health: 120 + level * 10,
maxHealth: 120 + level * 10,
damage: 20,
color: "#ff1744",
points: 50
};
} else {
enemy = {
x,
y,
radius: 20,
speed: 1.5 + level * 0.05,
health: 50 + level * 5,
maxHealth: 50 + level * 5,
damage: 10,
color: "#ff9100",
points: 20
};
}
enemies.push(enemy);
}
/* =========================
GEGNER UPDATE
========================= */
function updateEnemies() {
enemyTimer++;
let spawnSpeed = Math.max(20, 70 - level * 3);
if (enemyTimer > spawnSpeed) {
spawnEnemy();
enemyTimer = 0;
}
for (let enemy of enemies) {
let dx = player.x - enemy.x;
let dy = player.y - enemy.y;
let distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
enemy.x += dx / distance * enemy.speed;
enemy.y += dy / distance * enemy.speed;
}
// Spieler treffen
if (distance < enemy.radius + 18) {
player.health -= enemy.damage * 0.02;
createExplosion(
player.x,
player.y,
"#ff1744",
2
);
}
}
}
/* =========================
KUGELN UND GEGNER
========================= */
function checkBulletCollisions() {
for (let i = bullets.length - 1; i >= 0; i--) {
let bullet = bullets[i];
for (let j = enemies.length - 1; j >= 0; j--) {
let enemy = enemies[j];
let dx = bullet.x - enemy.x;
let dy = bullet.y - enemy.y;
let distance = Math.sqrt(dx * dx + dy * dy);
if (distance < enemy.radius + bullet.radius) {
enemy.health -= bullet.damage;
bullets.splice(i, 1);
createExplosion(
bullet.x,
bullet.y,
"#00e5ff",
5
);
if (enemy.health <= 0) {
score += enemy.points;
xp += 10;
createExplosion(
enemy.x,
enemy.y,
enemy.color,
20
);
if (Math.random() < 0.35) {
coinsObjects.push({
x: enemy.x,
y: enemy.y,
radius: 10
});
}
enemies.splice(j, 1);
checkLevelUp();
}
break;
}
}
}
}
/* =========================
LEVEL UP
========================= */
function checkLevelUp() {
let neededXP = level * 100;
if (xp >= neededXP) {
xp -= neededXP;
level++;
player.maxHealth += 10;
player.health = player.maxHealth;
player.damage += 5;
player.speed += 0.2;
createExplosion(
player.x,
player.y,
"#7c4dff",
50
);
}
}
/* =========================
MÜNZEN
========================= */
function updateCoins() {
for (let i = coinsObjects.length - 1; i >= 0; i--) {
let coin = coinsObjects[i];
let dx = player.x - coin.x;
let dy = player.y - coin.y;
let distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 35) {
coins++;
score += 10;
coinsObjects.splice(i, 1);
}
}
}
/* =========================
PARTIKEL
========================= */
function createExplosion(x, y, color, amount) {
for (let i = 0; i < amount; i++) {
particles.push({
x,
y,
vx: (Math.random() - 0.5) * 8,
vy: (Math.random() - 0.5) * 8,
life: 30 + Math.random() * 30,
color,
size: Math.random() * 5 + 2
});
}
}
function updateParticles() {
for (let i = particles.length - 1; i >= 0; i--) {
let particle = particles[i];
particle.x += particle.vx;
particle.y += particle.vy;
particle.vx *= 0.97;
particle.vy *= 0.97;
particle.life--;
if (particle.life <= 0) {
particles.splice(i, 1);
}
}
}
/* =========================
STERNE UPDATE
========================= */
function updateStars() {
for (let star of stars) {
star.y += star.speed;
if (star.y > HEIGHT) {
star.y = 0;
star.x = Math.random() * WIDTH;
}
}
}
/* =========================
ZEICHNEN
========================= */
function drawBackground() {
ctx.fillStyle = "#080b18";
ctx.fillRect(
0,
0,
WIDTH,
HEIGHT
);
for (let star of stars) {
ctx.fillStyle = "white";
ctx.globalAlpha = 0.3 + Math.random() * 0.5;
ctx.fillRect(
star.x,
star.y,
star.size,
star.size
);
}
ctx.globalAlpha = 1;
}
/* =========================
SPIELER ZEICHNEN
========================= */
function drawPlayer() {
ctx.save();
ctx.translate(
player.x,
player.y
);
// Glow
ctx.shadowColor = "#00e5ff";
ctx.shadowBlur = 20;
ctx.fillStyle = "#00e5ff";
ctx.beginPath();
ctx.moveTo(0, -25);
ctx.lineTo(20, 20);
ctx.lineTo(0, 12);
ctx.lineTo(-20, 20);
ctx.closePath();
ctx.fill();
ctx.restore();
}
/* =========================
KUGELN ZEICHNEN
========================= */
function drawBullets() {
for (let bullet of bullets) {
ctx.shadowColor = "#00e5ff";
ctx.shadowBlur = 15;
ctx.fillStyle = "#00e5ff";
ctx.beginPath();
ctx.arc(
bullet.x,
bullet.y,
bullet.radius,
0,
Math.PI * 2
);
ctx.fill();
ctx.shadowBlur = 0;
}
}
/* =========================
GEGNER ZEICHNEN
========================= */
function drawEnemies() {
for (let enemy of enemies) {
ctx.shadowColor = enemy.color;
ctx.shadowBlur = 15;
ctx.fillStyle = enemy.color;
ctx.beginPath();
ctx.arc(
enemy.x,
enemy.y,
enemy.radius,
0,
Math.PI * 2
);
ctx.fill();
ctx.shadowBlur = 0;
// Lebensbalken
let barWidth = enemy.radius * 2;
let healthWidth =
barWidth *
(enemy.health / enemy.maxHealth);
ctx.fillStyle = "#333";
ctx.fillRect(
enemy.x - enemy.radius,
enemy.y - enemy.radius - 10,
barWidth,
5
);
ctx.fillStyle = "#00e676";
ctx.fillRect(
enemy.x - enemy.radius,
enemy.y - enemy.radius - 10,
healthWidth,
5
);
}
}
/* =========================
MÜNZEN ZEICHNEN
========================= */
function drawCoins() {
for (let coin of coinsObjects) {
ctx.shadowColor = "#ffd600";
ctx.shadowBlur = 15;
ctx.fillStyle = "#ffd600";
ctx.beginPath();
ctx.arc(
coin.x,
coin.y,
coin.radius,
0,
Math.PI * 2
);
ctx.fill();
ctx.shadowBlur = 0;
ctx.fillStyle = "#8d6e00";
ctx.font = "bold 12px Arial";
ctx.textAlign = "center";
ctx.fillText(
"$",
coin.x,
coin.y + 4
);
}
}
/* =========================
PARTIKEL ZEICHNEN
========================= */
function drawParticles() {
for (let particle of particles) {
ctx.globalAlpha =
particle.life / 60;
ctx.fillStyle =
particle.color;
ctx.beginPath();
ctx.arc(
particle.x,
particle.y,
particle.size,
0,
Math.PI * 2
);
ctx.fill();
}
ctx.globalAlpha = 1;
}
/* =========================
HUD
========================= */
function updateHUD() {
document.getElementById("score").textContent =
score;
document.getElementById("coins").textContent =
coins;
document.getElementById("level").textContent =
level;
document.getElementById("enemyCount").textContent =
enemies.length;
let healthPercent =
Math.max(
0,
player.health / player.maxHealth * 100
);
document.getElementById("healthBar").style.width =
healthPercent + "%";
let neededXP =
level * 100;
let xpPercent =
Math.min(
100,
xp / neededXP * 100
);
document.getElementById("xpBar").style.width =
xpPercent + "%";
}
/* =========================
GAME OVER
========================= */
function gameOver() {
gameRunning = false;
document.getElementById("finalScore").textContent =
score;
document.getElementById("finalLevel").textContent =
level;
document.getElementById("finalCoins").textContent =
coins;
document.getElementById("gameOver").style.display =
"flex";
}
/* =========================
SPIEL LOOP
========================= */
function gameLoop() {
if (!gameRunning) {
return;
}
// Updates
updatePlayer();
updateBullets();
updateEnemies();
checkBulletCollisions();
updateCoins();
updateParticles();
updateStars();
updateHUD();
// Zeichnen
drawBackground();
drawCoins();
drawBullets();
drawEnemies();
drawPlayer();
drawParticles();
// Game Over
if (player.health <= 0) {
gameOver();
return;
}
requestAnimationFrame(gameLoop);
}
/* =========================
DEBUG / INFO
========================= */
console.log(
"Galaxy Survivor gestartet!"
);
console.log(
"Steuerung: WASD / Pfeiltasten + Leertaste"
);
</script>
</body>
</html>
To embed this project on your website, copy the following code and paste it into your website's HTML: