Instant Zombie Survival Arcade
by TurboMaker33293 lines9.7 KB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Instant Zombie Survival Arcade</title>
<style>
* {
box-sizing: border-box;
user-select: none;
}
body {
margin: 0;
padding: 0;
background: #111;
color: #fff;
font-family: 'Courier New', Courier, monospace;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
overflow: hidden;
}
#game-container {
position: relative;
width: 800px;
height: 400px;
background: linear-gradient(to bottom, #1a0b2e, #11051c, #05010a);
border: 4px solid #333;
box-shadow: 0 0 20px rgba(255, 0, 0, 0.3);
overflow: hidden;
}
canvas {
display: block;
width: 100%;
height: 100%;
}
.ui-layer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 15px;
}
.hud-top {
display: flex;
justify-content: space-between;
font-size: 18px;
font-weight: bold;
text-shadow: 2px 2px #000;
}
#health-bar-container {
width: 150px;
height: 15px;
background: #441111;
border: 2px solid #ff3333;
margin-top: 5px;
}
#health-bar {
width: 100%;
height: 100%;
background: #ff3333;
transition: width 0.1s ease;
}
.score-color { color: #00ffcc; }
.wave-color { color: #ffcc00; }
.ammo-color { color: #ff9900; }
.screen {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(10, 5, 15, 0.9);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
backdrop-filter: blur(4px);
z-index: 10;
text-align: center;
}
.hidden {
display: none !important;
}
h1 {
font-size: 42px;
margin: 0 0 10px 0;
color: #ff3333;
text-shadow: 3px 3px #000, 0 0 10px rgba(255,51,51,0.5);
letter-spacing: 2px;
}
p {
font-size: 14px;
margin: 5px 0 20px 0;
color: #bbb;
}
button {
background: #ff3333;
color: white;
border: none;
padding: 12px 30px;
font-size: 18px;
font-family: inherit;
font-weight: bold;
cursor: pointer;
box-shadow: 0 4px #990000;
transition: background 0.1s;
pointer-events: auto;
}
button:hover {
background: #ff5555;
}
</style>
</head>
<body>
<div style="margin-bottom: 10px; color: #888; font-size: 12px;">
A / D : Move | SPACE / W : Jump | MOUSE : Aim & Left Click to Shoot
</div>
<div id="game-container">
<canvas id="gameCanvas" width="800" height="400"></canvas>
<div class="ui-layer">
<div class="hud-top">
<div>
<div>VITAL SIGNS</div>
<div id="health-bar-container"><div id="health-bar"></div></div>
</div>
<div>
<div>SCORE</div>
<div id="score-display" class="score-color">000000</div>
</div>
<div>
<div>WAVE</div>
<div id="wave-display" class="wave-color" style="text-align: right;">1</div>
</div>
<div>
<div>MUNITIONS</div>
<div id="ammo-display" class="ammo-color" style="text-align: right;">30 / ∞</div>
</div>
</div>
</div>
<!-- Game Over Screen -->
<div id="gameover-screen" class="screen hidden">
<h1>OUTPOST OVERRUN</h1>
<p id="final-stats">Game Over</p>
<button id="restart-btn">REDEPLOY</button>
</div>
</div>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const gameoverScreen = document.getElementById('gameover-screen');
const restartBtn = document.getElementById('restart-btn');
const healthBar = document.getElementById('health-bar');
const scoreDisplay = document.getElementById('score-display');
const waveDisplay = document.getElementById('wave-display');
const ammoDisplay = document.getElementById('ammo-display');
// Instantly start in playing mode
let gameState = 'PLAYING';
let score = 0;
let wave = 1;
let keys = {};
let mouse = { x: 0, y: 0, isDown: false };
let player;
let zombies = [];
let bullets = [];
let particles = [];
let drops = [];
const groundY = 340;
const gravity = 0.6;
let waveTimer = 0;
let zombiesSpawnedThisWave = 0;
let totalZombiesForWave = 5;
let spawnInterval = 120;
let audioCtx = null;
function initAudio() {
if (!audioCtx) {
audioCtx = new (window.AudioContext || window.webkitAudioContext)();
}
}
function playLaserSound(type) {
if (!audioCtx) return;
try {
const osc = audioCtx.createOscillator();
const gain = audioCtx.createGain();
osc.connect(gain);
gain.connect(audioCtx.destination);
if (type === 'shoot') {
osc.type = 'sawtooth';
osc.frequency.setValueAtTime(400, audioCtx.currentTime);
osc.frequency.exponentialRampToValueAtTime(80, audioCtx.currentTime + 0.15);
gain.gain.setValueAtTime(0.1, audioCtx.currentTime);
gain.gain.linearRampToValueAtTime(0, audioCtx.currentTime + 0.15);
osc.start(); osc.stop(audioCtx.currentTime + 0.15);
} else if (type === 'hit') {
osc.type = 'triangle';
osc.frequency.setValueAtTime(120, audioCtx.currentTime);
osc.frequency.linearRampToValueAtTime(30, audioCtx.currentTime + 0.1);
gain.gain.setValueAtTime(0.2, audioCtx.currentTime);
gain.gain.linearRampToValueAtTime(0, audioCtx.currentTime + 0.1);
osc.start(); osc.stop(audioCtx.currentTime + 0.1);
} else if (type === 'death') {
osc.type = 'sawtooth';
osc.frequency.setValueAtTime(100, audioCtx.currentTime);
osc.frequency.linearRampToValueAtTime(10, audioCtx.currentTime + 0.4);
gain.gain.setValueAtTime(0.3, audioCtx.currentTime);
gain.gain.linearRampToValueAtTime(0, audioCtx.currentTime + 0.4);
osc.start(); osc.stop(audioCtx.currentTime + 0.4);
}
} catch(e) {}
}
class Player {
constructor() {
this.x = 400;
this.y = groundY - 40;
this.width = 24;
this.height = 40;
this.vx = 0;
this.vy = 0;
this.speed = 4.5;
this.jumpForce = -12;
this.isGrounded = false;
this.maxHealth = 100;
this.health = 100;
this.facingRight = true;
this.ammoMax = 30;
this.ammo = 30;
this.isReloading = false;
this.reloadTimer = 0;
this.reloadTime = 60;
this.shootCooldown = 0;
this.weaponType = 'PISTOL';
this.weaponTimer = 0;
}
update() {
if (keys['ArrowLeft'] || keys['a'] || keys['A']) {
this.vx = -this.speed;
this.facingRight = false;
} else if (keys['ArrowRight'] || keys['d'] || keys['D']) {
this.vx = this.speed;
this.facingRight = true;
} else {
this.vx *= 0.7;
}
if ((keys['ArrowUp'] || keys['w'] || keys['W'] || keys[' ']) && this.isGrounded) {
this.vy = this.jumpForce;
this.isGrounded = false;
}
this.vy += gravity;
this.x += this.vx;
this.y += this.vy;
if (this.y >= groundY - this.height) {
this.y = groundY - this.height;
this.vy = 0;
this.isGrounded = true;
}
if (this.x < 0) this.x = 0;
if (this.x > canvas.width - this.width) this.x = canvas.width - this.width;
if (this.shootCooldown > 0) this.shootCooldown--;
if (this.weaponTimer > 0) {
this.weaponTimer--;
if (this.weaponTimer <= 0) {
this.weaponType = 'PISTOL';
this.ammoMax = 30;Game Source: Instant Zombie Survival Arcade
Creator: TurboMaker33
Libraries: none
Complexity: complex (293 lines, 9.7 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: instant-zombie-survival-arcade-turbomaker33" to link back to the original. Then publish at arcadelab.ai/publish.