ZOMBIE BASE DEFENSE — Visual Attacks!
by TurboMaker33398 lines14.4 KB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ZOMBIE BASE DEFENSE — Visual Attacks!</title>
<style>
* { box-sizing: border-box; font-family: Arial, sans-serif; }
body { max-width: 1000px; margin: 0 auto; padding: 20px; background: #1a0f0f; color: #fff; }
h1 { text-align: center; color: #ff3333; font-size: 42px; margin-bottom: 5px; text-shadow: 0 0 15px #ff000060; }
.subtitle { text-align: center; color: #ff8888; margin-bottom: 15px; font-size: 18px; }
.status-bar { display: flex; justify-content: space-around; background: #2b1515; padding: 12px; border-radius: 12px; margin-bottom: 15px; flex-wrap: wrap; gap: 10px; }
.stat { text-align: center; min-width: 100px; font-size: 15px; font-weight: bold; }
.stat span { display: block; color: #ffdd44; font-size: 22px; margin-top: 3px; }
/* === ZOMBIE BATTLE AREA === */
.battle-arena {
background: linear-gradient(90deg, #2a0f0f 0%, #1a2a1a 100%);
border: 3px solid #553333;
border-radius: 12px;
height: 180px;
margin: 15px 0;
position: relative;
overflow: hidden;
}
.base-wall {
position: absolute;
right: 20px;
top: 10%;
bottom: 10%;
width: 60px;
background: linear-gradient(180deg, #888, #555);
border: 3px solid #333;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
font-weight: bold;
color: #000;
}
.zombie {
position: absolute;
font-size: 28px;
transition: left 0.05s linear, opacity 0.3s;
filter: drop-shadow(0 0 4px #0f0);
}
.zombie.dead {
opacity: 0.2;
transform: scale(0.5);
filter: grayscale(1);
}
.explosion {
position: absolute;
font-size: 24px;
animation: boom 0.5s ease-out forwards;
pointer-events: none;
}
@keyframes boom {
0% { transform: scale(1); opacity: 1; }
100% { transform: scale(2); opacity: 0; }
}
.wave-announce {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 32px;
font-weight: bold;
color: #ff0000;
text-shadow: 0 0 10px #ff0000;
z-index: 10;
animation: pulse 0.5s ease-in-out infinite alternate;
}
@keyframes pulse {
from { opacity: 0.8; }
to { opacity: 1; }
}
.hp-bar { background: #332222; height: 30px; border-radius: 8px; margin: 10px 0; overflow: hidden; }
.hp-fill { height: 100%; background: linear-gradient(90deg, #ff2222, #ff6600); transition: width .3s; display: flex; align-items: center; justify-content: center; font-size: 14px; font-weight: bold; }
.event-box { background: #2b1010; padding: 15px; border-radius: 10px; margin: 15px 0; border-left: 5px solid #ff3333; min-height: 60px; font-size: 16px; }
.btn-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin: 15px 0; }
@media(max-width:700px) { .btn-grid { grid-template-columns: repeat(2,1fr); } }
button { padding: 12px 6px; font-size: 13px; font-weight: bold; border: none; border-radius: 10px; cursor: pointer; transition: transform .15s; }
button:hover { transform: scale(1.05); }
button:disabled { opacity: .4; cursor: not-allowed; transform: none; }
.farm { background: #28c76f; color: #000; }
.wall { background: #708090; color: #fff; }
.tower { background: #4facfe; color: #000; }
.turret { background: #ff5500; color: #fff; }
.trap { background: #ff9f1c; color: #000; }
.guard { background: #9d65c9; color: #fff; }
.hire { background: #3d8bff; color: #fff; }
.fortify { background: #ffd700; color: #000; }
.research { background: #ea3943; color: #fff; }
.log-box { background: #221111; padding: 12px; border-radius: 10px; height: 160px; overflow-y: auto; font-family: monospace; font-size: 12px; margin-top: 12px; }
.win { color: #00ff41; font-weight: bold; }
.lose { color: #ff4d4d; font-weight: bold; }
.danger { color: #ff0000; font-weight: bold; animation: blink .5s infinite alternate; }
@keyframes blink { from { opacity:1; } to { opacity:.5; } }
</style>
</head>
<body>
<h1>🧟 ZOMBIE BASE DEFENSE 🧟</h1>
<p class="subtitle">👀 SEE the zombies attack! Watch your defenses shoot them down!</p>
<div class="status-bar">
<div class="stat">💰 MONEY<br><span id="money">$100</span></div>
<div class="stat">👷 WORKERS<br><span id="workers">1</span></div>
<div class="stat">🌊 WAVE<br><span id="wave">0</span></div>
<div class="stat">🖱️ CLICKS<br><span id="clicks">0</span></div>
<div class="stat">⚔️ DEFENSE<br><span id="defense">0</span></div>
</div>
<!-- 🆕 BATTLE AREA — ZOMBIES APPEAR HERE! -->
<div class="battle-arena" id="battleArena">
<div class="base-wall" id="baseWall">BASE</div>
</div>
<div class="hp-bar">
<div class="hp-fill" id="hpbar" style="width:100%">WALL HP: 5 / 5</div>
</div>
<div class="event-box" id="event">
<strong>🏠 READY!</strong> Farm for money → Build defenses → Watch the zombies MARCH and get SHOT DOWN! Every 10 clicks = ZOMBIE WAVE ATTACK!
</div>
<div class="btn-grid">
<button class="farm" onclick="doFarm()">🌾 FARM<br>Earn $</button>
<button class="wall" onclick="doWall()">🧱 WALL<br>$80 +5HP</button>
<button class="tower" onclick="doTower()">🗼 TOWER<br>$400 K+1</button>
<button class="turret" onclick="doTurret()">🤖 TURRET<br>$800 K+5</button>
<button class="trap" onclick="doTrap()">🪓 TRAP<br>$250 K+2</button>
<button class="guard" onclick="doGuard()">👮 GUARD<br>$600 K+3</button>
<button class="hire" onclick="doHire()">🧑 WORKER<br>$100</button>
<button class="research" onclick="doResearch()">🧪 RESEARCH<br>+25%</button>
</div>
<div class="log-box" id="log">
<div>═══════════════ BATTLE LOG ═══════════════</div>
</div>
<script>
// === ZOMBIE DEFENSE — WITH VISUAL ATTACK ANIMATION ===
let money = 100;
let workers = 1;
let wallHP = 5;
let maxWallHP = 5;
let wave = 0;
let clicks = 0;
// DEFENSES
let towers = 0;
let turrets = 0;
let traps = 0;
let guards = 0;
let fortified = false;
let research = 1.00;
let gameOver = false;
let animationRunning = false;
// ELEMENTS
const eMoney = document.getElementById('money');
const eWorkers = document.getElementById('workers');
const eWave = document.getElementById('wave');
const eClicks = document.getElementById('clicks');
const eDefense = document.getElementById('defense');
const eHpbar = document.getElementById('hpbar');
const eEvent = document.getElementById('event');
const eLog = document.getElementById('log');
const arena = document.getElementById('battleArena');
function fmt(n) { return '$' + n.toLocaleString(); }
function defensePower() {
return Math.floor((towers*1 + turrets*5 + traps*2 + guards*3) * research);
}
function updateUI() {
eMoney.textContent = fmt(money);
eWorkers.textContent = workers;
eWave.textContent = wave;
eClicks.textContent = clicks;
eDefense.textContent = defensePower();
let pct = Math.max(0, (wallHP/maxWallHP)*100);
eHpbar.style.width = pct + '%';
eHpbar.textContent = `WALL HP: ${wallHP} / ${maxWallHP}`;
if(pct <= 25) eHpbar.style.background = 'linear-gradient(90deg, #ff0000, #ff4400)';
else if(pct <= 50) eHpbar.style.background = 'linear-gradient(90deg, #ff6600, #ffaa00)';
else eHpbar.style.background = 'linear-gradient(90deg, #22aa22, #44dd44)';
document.querySelectorAll('button').forEach(b => b.disabled = gameOver || animationRunning);
}
function log(msg, type='') {
const line = document.createElement('div');
line.className = type;
line.textContent = `Click ${clicks}: ${msg}`;
eLog.insertBefore(line, eLog.children[1]);
}
// 🆕 CLEAR AREA
function clearArena() {
document.querySelectorAll('.zombie, .explosion, .wave-announce').forEach(el => el.remove());
}
// 🆕 SHOW VISUAL ZOMBIE ATTACK ANIMATION
async function zombieAttack() {
animationRunning = true;
clearArena();
// ANNOUNCE WAVE
const announce = document.createElement('div');
announce.className = 'wave-announce';
announce.textContent = `🌊 WAVE ${wave} ATTACK!`;
arena.appendChild(announce);
await sleep(1500);
announce.remove();
// CALCULATE ZOMBIES
let baseZombies = 3 + Math.floor(wave * 1.5) + Math.floor(Math.pow(wave/5, 1.4));
let zombiesCount = Math.floor(baseZombies + Math.random()*(baseZombies*0.4));
let defense = defensePower();
let killed = Math.min(defense, zombiesCount);
let reaching = zombiesCount - killed;
eEvent.innerHTML = `🧟 WAVE ${wave}: ${zombiesCount} ZOMBIES MARCHING! ⚔️ Defense: ${defense}`;
updateUI();
// SPAWN ZOMBIES — APPEAR ONE BY ONE
let zombies = [];
for(let i=0; i<zombiesCount; i++) {
await sleep(100);
let zombie = document.createElement('div');
zombie.className = 'zombie';
zombie.textContent = '🧟';
zombie.style.left = '30px';
zombie.style.top = (15 + (i % 5) * 30) + 'px';
arena.appendChild(zombie);
zombies.push(zombie);
}
// MARCH ZOMBIES TOWARD WALL
for(let step=0; step<35; step++) {
zombies.forEach((z, idx) => {
if(!z.classList.contains('dead')) {
let currentLeft = parseFloat(z.style.left);
z.style.left = (currentLeft + 8) + 'px';
}
});
await sleep(80);
// SHOOT DOWN ZOMBIES AS THEY APPROACH
if(step === 15 && killed > 0) {
for(let i=0; i<killed; i++) {
if(zombies[i] && !zombies[i].classList.contains('dead')) {
zombies[i].classList.add('dead');
showExplosion(zombies[i].style.left, zombies[i].style.top);
}
}
log(`⚔️ Defenses KILLED ${killed} zombies mid-attack!`, 'win');
}
}
// REMOVE DEAD ZOMBIES
zombies.forEach(z => {
if(z.classList.contains('dead')) z.remove();
});
// ZOMBIES REACH WALL — DEAL DAMAGE
let dmg = reaching;
if(fortified) dmg = Math.floor(dmg / 2);
wallHP -= dmg;
if(reaching > 0) {
eEvent.innerHTML = `💥 ${reaching} ZOMBIES REACHED WALL! —${dmg} HP!`;
log(`💥 ${reaching} Zombies hit walls! -${dmg} HP!`, 'lose');
} else {
eEvent.innerHTML = `✅ ALL ${zombiesCount} ZOMBIES DESTROYED! Base Safe!`;
log(`✅ ALL ${zombiesCount} Zombies KILLED!`, 'win');
}
// CHECK WALLS BROKEN
if(wallHP <= 0) {
gameOver = true;
eEvent.innerHTML = `<span class="danger">💀 WALLS BROKEN! ZOMBIES GOT IN! SURVIVED ${wave} WAVES!</span>`;
log(`💀 BASE OVERRUN! Survived ${wave} WAVES!`, 'danger');
await sleep(3000);
// RESTART
money = 100; workers = 1; wallHP = 5; maxWallHP = 5; wave = 0; clicks = 0;
towers = 0; turrets = 0; traps = 0; guards = 0; fortified = false; research = 1.00; gameOver = false;
clearArena();
eEvent.innerHTML = '🔄 REBUILT! Build stronger defenses this time!';
log('🔄 NEW BASE — Try to survive longer!');
updateUI();
}
updateUI();
animationRunning = false;
clearArena();
}
// 🆕 EXPLOSION EFFECT
function showExplosion(left, top) {
let exp = document.createElement('div');
exp.className = 'explosion';
exp.textContent = '💥';
exp.style.left = left;
exp.style.top = top;
arena.appendChild(exp);
setTimeout(() => exp.remove(), 500);
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function nextClick() {
if(animationRunning) return;
clicks++;
if(clicks % 10 === 0) {
wave++;
zombieAttack(); // Visual attack — runs async
}
updateUI();
}
// === BUTTON ACTIONS ===
function doFarm() {
if(animationRunning || gameOver) return;
let earn = 15 * workers;
money += earn;
log(`🌾 FARM → +${fmt(earn)}`);
nextClick();
}
function doWall() {
if(money < 80) { eEvent.innerHTML = '🧱 Need $80 to build Wall!'; return; }
money -= 80;
wallHP += 5;
maxWallHP += 5;
log('🧱 BUILT WALL! +5 HP!');
updateUI();
}
function doTower() {
if(money < 400) { eEvent.innerHTML = '🗼 Need $400 to build Tower!'; return; }
money -= 400;
towers++;
log('🗼 TOWER BUILT! Kills +1 Zombie!');
updateUI();
}
function doTurret() {
if(money < 800) { eEvent.innerHTML = '🤖 Need $800 to build TURRET!'; return; }
money -= 800;
turrets++;
log('🤖 TURRET BUILT! Kills +5 ZOMBIES! 💥', 'win');
updateUI();
}
function doTrap() {
if(money < 250) { eEvent.innerHTML = '🪓 Need $250 to build Traps!'; return; }
money -= 250;
traps++;
log('🪓 TRAPS BUILT! Kills +2 Zombies!');
updateUI();
}
function doGuard() {
if(money < 600) { eEvent.innerHTML = '👮 Need $600 to Hire Guard!'; return; }
money -= 600;
guards++;
log('👮 GUARD HIRED! Kills +3 Zombies!');
updateUI();
}
function doHire() {
if(money < 100) { eEvent.innerHTML = '🧑 Need $100 to Hire Worker!'; return; }
money -= 100;
workers++;
log('🧑 WORKER HIRED! Earn More Money!');
updateUI();
}
function doResearch() {
if(money < 2000) { eEvent.innerHTML = '🧪 Need $2,000 to Research!'; return; }
money -= 2000;
research *= 1.25;
log(`🧪 RESEARCH! All Defenses +25%! (×${research.toFixed(2)})`, 'win');
updateUI();
}
updateUI();
</script>
</body>
</html>Game Source: ZOMBIE BASE DEFENSE — Visual Attacks!
Creator: TurboMaker33
Libraries: none
Complexity: complex (398 lines, 14.4 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-base-defense-visual-attacks-turbomaker33" to link back to the original. Then publish at arcadelab.ai/publish.