Zombie Survival
by AtomicBolt46244 lines5.2 KB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Zombie Survival</title>
<style>
* { box-sizing: border-box; }
body {
margin: 0;
background: #101820;
color: white;
font-family: Arial;
text-align: center;
}
h1 { color: #5cff72; }
canvas {
background: #26352d;
border: 4px solid #5cff72;
max-width: 95vw;
}
button {
padding: 12px 25px;
background: #5cff72;
border: none;
border-radius: 8px;
font-size: 18px;
font-weight: bold;
cursor: pointer;
}
p { color: #ddd; }
</style>
</head>
<body>
<h1>🧟 ZOMBIE SURVIVAL</h1>
<p>WASD or arrow keys to move | SPACE to shoot</p>
<h3>Score: <span id="score">0</span> |
Health: <span id="health">100</span></h3>
<canvas id="game" width="800" height="500"></canvas>
<p><button onclick="restart()">RESTART GAME</button></p>
<script>
const canvas = document.getElementById("game");
const ctx = canvas.getContext("2d");
let keys = {};
let player, zombies, bullets, score, health, gameOver;
let spawnTimer;
function restart() {
player = {x:400, y:250, size:24, speed:4};
zombies = [];
bullets = [];
score = 0;
health = 100;
gameOver = false;
spawnTimer = 0;
updateHUD();
}
document.addEventListener("keydown", e => {
keys[e.key.toLowerCase()] = true;
if(e.code === "Space") e.preventDefault();
});
document.addEventListener("keyup", e => {
keys[e.key.toLowerCase()] = false;
});
function shoot() {
bullets.push({
x:player.x,
y:player.y,
dx:0,
dy:-7,
life:70
});
}
let shooting = false;
document.addEventListener("keydown", e => {
if(e.code === "Space" && !shooting && !gameOver) {
shoot();
shooting = true;
}
});
document.addEventListener("keyup", e => {
if(e.code === "Space") shooting = false;
});
function updateHUD() {
document.getElementById("score").textContent = score;
document.getElementById("health").textContent = health;
}
function update() {
if(gameOver) return;
if(keys["w"] || keys["arrowup"]) player.y -= player.speed;
if(keys["s"] || keys["arrowdown"]) player.y += player.speed;
if(keys["a"] || keys["arrowleft"]) player.x -= player.speed;
if(keys["d"] || keys["arrowright"]) player.x += player.speed;
player.x = Math.max(15, Math.min(785, player.x));
player.y = Math.max(15, Math.min(485, player.y));
spawnTimer++;
if(spawnTimer > Math.max(20, 90-score)) {
let side = Math.floor(Math.random()*4);
let x = side===0 ? 0 : side===1 ? 800 : Math.random()*800;
let y = side===2 ? 0 : side===3 ? 500 : Math.random()*500;
zombies.push({x,y,size:25,speed:1+score*0.015});
spawnTimer = 0;
}
zombies.forEach(z => {
let dx = player.x-z.x;
let dy = player.y-z.y;
let d = Math.hypot(dx,dy) || 1;
z.x += dx/d*z.speed;
z.y += dy/d*z.speed;
if(d < 30 && !z.hitCooldown) {
health -= 10;
z.hitCooldown = 45;
updateHUD();
}
if(z.hitCooldown) z.hitCooldown--;
});
bullets.forEach(b => {
b.x += b.dx;
b.y += b.dy;
b.life--;
});
bullets = bullets.filter(b => b.life>0);
bullets.forEach(b => {
zombies.forEach(z => {
if(Math.hypot(b.x-z.x,b.y-z.y)<25 && !z.dead) {
z.dead = true;
b.life = 0;
score += 10;
updateHUD();
}
});
});
zombies = zombies.filter(z => !z.dead);
if(health <= 0) {
health = 0;
gameOver = true;
updateHUD();
}
}
function draw() {
ctx.clearRect(0,0,800,500);
// Background grid
ctx.strokeStyle = "#34483b";
for(let x=0;x<800;x+=50) {
ctx.beginPath();
ctx.moveTo(x,0);
ctx.lineTo(x,500);
ctx.stroke();
}
for(let y=0;y<500;y+=50) {
ctx.beginPath();
ctx.moveTo(0,y);
ctx.lineTo(800,y);
ctx.stroke();
}
// Player
ctx.fillStyle = "#38aaff";
ctx.fillRect(player.x-12,player.y-12,24,24);
ctx.fillStyle = "white";
ctx.fillRect(player.x-5,player.y-5,4,4);
ctx.fillRect(player.x+3,player.y-5,4,4);
// Zombies
zombies.forEach(z => {
ctx.fillStyle = "#7cff48";
ctx.beginPath();
ctx.arc(z.x,z.y,13,0,Math.PI*2);
ctx.fill();
ctx.fillStyle = "black";
ctx.fillRect(z.x-7,z.y-4,4,4);
ctx.fillRect(z.x+3,z.y-4,4,4);
});
// Bullets
bullets.forEach(b => {
ctx.fillStyle = "yellow";
ctx.beginPath();
ctx.arc(b.x,b.y,5,0,Math.PI*2);
ctx.fill();
});
if(gameOver) {
ctx.fillStyle = "rgba(0,0,0,0.8)";
ctx.fillRect(0,0,800,500);
ctx.fillStyle = "red";
ctx.font = "bold 55px Arial";
ctx.textAlign = "center";
ctx.fillText("GAME OVER",400,220);
ctx.fillStyle = "white";
ctx.font = "25px Arial";
ctx.fillText("Final Score: "+score,400,270);
ctx.fillText("Press RESTART to play again",400,320);
}
}
function loop() {
update();
draw();
requestAnimationFrame(loop);
}
restart();
loop();
</script>
</body>
</html>Game Source: Zombie Survival
Creator: AtomicBolt46
Libraries: none
Complexity: complex (244 lines, 5.2 KB)
The full source code is displayed above on this page.
Remix Instructions
To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: zombie-survival-atomicbolt46" to link back to the original. Then publish at arcadelab.ai/publish.