SOURCE

console 命令行工具 X clear

                    
>
console
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>红草坪塔防</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            background-color: #222;
            display: flex;
            flex-direction: column;
            align-items: center;
            padding: 10px;
            color: white;
            font-family: Microsoft YaHei;
        }
        #gameBox {
            position: relative;
            width: 800px;
            height: 500px;
            background-color: #992222;
            border: 4px solid #440000;
            overflow: hidden;
        }
        .grid {
            position: absolute;
            border: 1px solid rgba(255,255,255,0.15);
            width: 80px;
            height: 100px;
        }
        .plant {
            position: absolute;
            width:70px;
            height:90px;
            text-align:center;
            color:white;
            font-size:11px;
            display:flex;
            align-items:center;
            justify-content:center;
            border-radius:8px;
            background:rgba(30,120,30,0.7);
        }
        .zombie {
            position:absolute;
            width:70px;
            height:90px;
            color:white;
            font-size:11px;
            display:flex;
            align-items:center;
            justify-content:center;
            background:rgba(120,120,60,0.7);
            border-radius:6px;
        }
        .zombie.enrage{
            background:rgba(180,40,40,0.8);
        }
        .zombie.stuck{
            background:#4488ff;
        }
        .bullet {
            position:absolute;
            width:12px;
            height:12px;
            background-color:#ff2222;
            border-radius:50%;
        }
        #ui{
            margin:10px 0;
            display:flex;
            gap:6px;
            flex-wrap:wrap;
            justify-content:center;
        }
        button{
            padding:7px 10px;
            font-size:13px;
        }
        #sunText{
            font-size:20px;
            color:#ffdd33;
            margin:8px;
        }
    </style>
</head>
<body>
    <h2>红草坪塔防</h2>
    <div id="sunText">☀阳光:150</div>
    <div id="ui">
        <button id="btnWave">开始一波僵尸</button>
    </div>
    <div id="gameBox"></div>

<script>
const gameBox = document.getElementById("gameBox");
const GRID_W = 80;
const GRID_H = 100;
const ROWS = 5;
const COLS = 9;
let plants = [];
let zombies = [];
let bullets = [];
let sunCount =150;
let selectedPlant = null;

//绘制网格
for(let r=0;r<ROWS;r++){
    for(let c=0;c<COLS;c++){
        const g = document.createElement("div");
        g.className="grid";
        g.style.left = c*GRID_W +"px";
        g.style.top = r*GRID_H +"px";
        gameBox.appendChild(g);
        g.onclick = ()=>{
            if(!selectedPlant) return;
            const exist = plants.some(p=>p.col === c && p.row === r);
            if(exist) return;
            placePlant(selectedPlant,c,r);
            selectedPlant=null;
        }
    }
}

const plantData = {
    pea:{name:"独眼豌豆射手",cost:100},
    sunflower:{name:"向日葵",cost:75},
    nut:{name:"坚果墙",cost:50},
    chomper:{name:"大嘴花",cost:150},
    spike:{name:"地刺",cost:125}
}

const uiDiv = document.getElementById("ui");
for(const key in plantData){
    const p = plantData[key];
    const btn = document.createElement("button");
    btn.innerText = p.name+"("+p.cost+"☀)";
    btn.onclick = ()=>{
        if(sunCount >= p.cost){
            selectedPlant = key;
        }
    }
    uiDiv.appendChild(btn);
}

function placePlant(type,col,row){
    const pDiv = document.createElement("div");
    pDiv.className="plant";
    pDiv.innerText = plantData[type].name;
    pDiv.style.left = col*GRID_W +5 +"px";
    pDiv.style.top = row*GRID_H +5 +"px";
    gameBox.appendChild(pDiv);
    plants.push({
        type,col,row,dom:pDiv,hp:100,shootTimer:0
    })
}

document.getElementById("btnWave").onclick = ()=>{
    for(let i=0;i<4;i++){
        const zDiv = document.createElement("div");
        zDiv.className="zombie";
        let zType;
        if(i===3) zType="iron";
        else if(i===2) zType="cone";
        else zType="normal";
        let nameText = "普通僵尸";
        if(zType==="cone") nameText="路障僵尸";
        if(zType==="iron") nameText="血迹铁桶僵尸";
        zDiv.innerText = nameText;
        const r = Math.floor(Math.random()*ROWS);
        const zObj = {
            type:zType,
            row:r,
            x:720,
            dom:zDiv,
            hp:80,
            hitBullet:0,
            enraged:false,
            stuck:false,
            stuckTimer:0
        }
        zDiv.style.left = zObj.x +"px";
        zDiv.style.top = r*GRID_H +5 +"px";
        gameBox.appendChild(zDiv);
        zombies.push(zObj);
    }
}

function gameLoop(){
    plants.forEach(p=>{
        if(p.type === "pea"){
            p.shootTimer++;
            if(p.shootTimer>60){
                p.shootTimer=0;
                const bDiv = document.createElement("div");
                bDiv.className="bullet";
                const bulletX = p.col*GRID_W +70;
                const bulletY = p.row*GRID_H +45;
                bDiv.style.left = bulletX +"px";
                bDiv.style.top = bulletY +"px";
                gameBox.appendChild(bDiv);
                bullets.push({
                    x:bulletX,
                    y:bulletY,
                    row:p.row,
                    dom:bDiv
                })
            }
        }
    })

    bullets.forEach(b=>{
        b.x +=6;
        b.dom.style.left = b.x +"px";
        zombies.forEach(z=>{
            if(z.row === b.row && Math.abs(b.x - z.x)<30){
                b.dom.remove();
                b.hit = true;
                z.hitBullet++;
                if(z.type==="normal" && z.hitBullet>=5 && !z.enraged){
                    z.enraged=true;
                    z.dom.classList.add("enrage");
                }
            }
        })
    })
    bullets = bullets.filter(b=>!b.hit && b.x<800);

    zombies.forEach(z=>{
        if(z.stuck){
            z.stuckTimer--;
            if(z.stuckTimer<=0){
                z.stuck=false;
                z.dom.classList.remove("stuck");
            }
            return;
        }
        plants.forEach(p=>{
            if(p.type==="spike" && p.row===z.row && Math.abs(z.x - p.col*GRID_W)<60){
                if(Math.random()<0.21){
                    z.stuck=true;
                    z.stuckTimer=120;
                    z.dom.classList.add("stuck");
                }
            }
        })
        if(!z.enraged){
            z.x -=0.4;
        }else{
            z.x -=0.7;
        }
        z.dom.style.left = z.x +"px";
    })

    requestAnimationFrame(gameLoop);
}
gameLoop();
</script>
</body>
</html>