🎮ArcadeLab

人机枪战小游戏

by SparkOwl95
190 lines4.7 KB
▶ Play
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>人机枪战小游戏</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
canvas{background:#222;display:block;margin:0 auto;cursor:crosshair;}
body{background:#111}
</style>
</head>
<body>
<canvas id="gameCanvas"></canvas>

<script>
const canvas = document.getElementById("gameCanvas");
const ctx = canvas.getContext("2d");
canvas.width = 900;
canvas.height = 600;

// ========== 输入控制 ==========
const keys = {};
let mouse = {x:0,y:0,down:false};

document.addEventListener("keydown",e=>keys[e.key.toLowerCase()]=true);
document.addEventListener("keyup",e=>keys[e.key.toLowerCase()]=false);
canvas.addEventListener("mousemove",e=>{
    const rect=canvas.getBoundingClientRect();
    mouse.x=e.clientX-rect.left;
    mouse.y=e.clientY-rect.top;
});
canvas.addEventListener("mousedown",()=>mouse.down=true);
canvas.addEventListener("mouseup",()=>mouse.down=false);

// ========== 玩家 ==========
const player = {
    x: canvas.width/2,
    y: canvas.height/2,
    r:18,
    speed:4,
    hp:100,
    score:0
};

// 子弹数组
let bullets = [];
// 敌人AI数组
let enemies = [];
let lastShot = 0;
const shootCD = 180; //射击冷却ms

// 生成子弹
function spawnBullet(){
    const now = Date.now();
    if(now-lastShot < shootCD) return;
    lastShot = now;
    const angle = Math.atan2(mouse.y-player.y, mouse.x-player.x);
    bullets.push({
        x:player.x,
        y:player.y,
        vx:Math.cos(angle)*10,
        vy:Math.sin(angle)*10,
        r:5
    })
}

// 生成敌人AI
function spawnEnemy(){
    let x,y;
    const side = Math.floor(Math.random()*4);
    if(side===0){x=0;y=Math.random()*canvas.height}
    else if(side===1){x=canvas.width;y=Math.random()*canvas.height}
    else if(side===2){x=Math.random()*canvas.width;y=0}
    else {x=Math.random()*canvas.width;y=canvas.height}

    enemies.push({
        x:x,
        y:y,
        r:16,
        speed:1.6,
        hp:1
    })
}

// ========== 游戏循环 ==========
function loop(){
    // 清画布
    ctx.fillStyle="#222222";
    ctx.fillRect(0,0,canvas.width,canvas.height);

    // 玩家移动 WASD
    if(keys["w"]) player.y -= player.speed;
    if(keys["s"]) player.y += player.speed;
    if(keys["a"]) player.x -= player.speed;
    if(keys["d"]) player.x += player.speed;
    // 边界限制
    player.x = Math.max(player.r, Math.min(canvas.width-player.r, player.x));
    player.y = Math.max(player.r, Math.min(canvas.height-player.r, player.y));

    // 射击
    if(mouse.down) spawnBullet();

    // 更新子弹
    for(let i=bullets.length-1;i>=0;i--){
        const b=bullets[i];
        b.x += b.vx;
        b.y += b.vy;
        // 超出屏幕删除子弹
        if(b.x<0||b.x>canvas.width||b.y<0||b.y>canvas.height){
            bullets.splice(i,1);continue;
        }

        //子弹碰敌人
        for(let j=enemies.length-1;j>=0;j--){
            const e=enemies[j];
            const dx=b.x-e.x;
            const dy=b.y-e.y;
            const dist=Math.sqrt(dx*dx+dy*dy);
            if(dist < b.r+e.r){
                enemies.splice(j,1);
                bullets.splice(i,1);
                player.score +=10;
                break;
            }
        }
    }

    // 更新敌人AI:追踪玩家
    for(let i=enemies.length-1;i>=0;i--){
        const e=enemies[i];
        const dx=player.x - e.x;
        const dy=player.y - e.y;
        const angle=Math.atan2(dy,dx);
        e.x += Math.cos(angle)*e.speed;
        e.y += Math.sin(angle)*e.speed;

        //敌人撞到玩家
        const dist = Math.hypot(player.x-e.x, player.y-e.y);
        if(dist < player.r + e.r){
            player.hp -= 15;
            enemies.splice(i,1);
        }
    }

    // 绘制玩家
    ctx.beginPath();
    ctx.arc(player.x,player.y,player.r,0,Math.PI*2);
    ctx.fillStyle="#42A5F5";
    ctx.fill();

    //绘制敌人
    ctx.fillStyle="#ff4444";
    enemies.forEach(e=>{
        ctx.beginPath();
        ctx.arc(e.x,e.y,e.r,0,Math.PI*2);
        ctx.fill();
    })

    //绘制子弹
    ctx.fillStyle="#ffee44";
    bullets.forEach(b=>{
        ctx.beginPath();
        ctx.arc(b.x,b.y,b.r,0,Math.PI*2);
        ctx.fill();
    })

    // UI文字 分数血量
    ctx.fillStyle="#fff";
    ctx.font="22px Arial";
    ctx.fillText(`分数:${player.score}`,20,30);
    ctx.fillText(`血量:${player.hp}`,20,60);

    //游戏结束判断
    if(player.hp <=0){
        ctx.fillStyle="#ff3333";
        ctx.font="48px Arial";
        ctx.textAlign="center";
        ctx.fillText("游戏结束!",canvas.width/2,canvas.height/2);
    }

    requestAnimationFrame(loop);
}

// 定时生成敌人
setInterval(spawnEnemy,1200);
loop();
</script>
</body>
</html>

Game Source: 人机枪战小游戏

Creator: SparkOwl95

Libraries: none

Complexity: moderate (190 lines, 4.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: game-sparkowl95" to link back to the original. Then publish at arcadelab.ai/publish.