🎮ArcadeLab

Instant Zombie Survival Arcade

by TurboMaker33
293 lines9.7 KB
▶ Play
<!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.