简易枪战小游戏
by CyberRanger21172 lines4.0 KB
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>简易枪战小游戏</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{background:#111;display:flex;justify-content:center;align-items:center;height:100vh;overflow:hidden}
canvas{border:2px solid #444;background:#1a1a1a}
</style>
</head>
<body>
<canvas id="game"></canvas>
<script>
const canvas = document.getElementById('game');
const ctx = canvas.getContext('2d');
canvas.width = 800;
canvas.height = 600;
//玩家
const player = {
x: canvas.width/2,
y: canvas.height/2,
r: 18,
speed: 4,
angle: 0,
hp: 100
};
const keys = {};
let mouse = {x:0,y:0};
let bullets = [];
let enemies = [];
let score = 0;
let spawnTimer = 0;
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',shoot);
function shoot(){
bullets.push({
x:player.x+Math.cos(player.angle)*22,
y:player.y+Math.sin(player.angle)*22,
vx:Math.cos(player.angle)*10,
vy:Math.sin(player.angle)*10,
r:4
})
}
function spawnEnemy(){
let side = Math.floor(Math.random()*4);
let ex,ey;
if(side===0){ex=Math.random()*canvas.width;ey=-30}
else if(side===1){ex=canvas.width+30;ey=Math.random()*canvas.height}
else if(side===2){ex=Math.random()*canvas.width;ey=canvas.height+30}
else {ex=-30;ey=Math.random()*canvas.height}
enemies.push({x:ex,y:ey,r:16,speed:1.6,hp:2})
}
function loop(){
ctx.fillStyle='#1a1a1a';
ctx.fillRect(0,0,canvas.width,canvas.height);
//玩家朝向鼠标
player.angle=Math.atan2(mouse.y-player.y,mouse.x-player.x);
//移动
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));
//生成敌人
spawnTimer++;
if(spawnTimer>90){
spawnEnemy();
spawnTimer=0;
}
//更新子弹
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);
}
}
//更新敌人
for(let i=enemies.length-1;i>=0;i--){
const e=enemies[i];
const ang=Math.atan2(player.y-e.y,player.x-e.x);
e.x+=Math.cos(ang)*e.speed;
e.y+=Math.sin(ang)*e.speed;
//敌人撞到玩家
const distP=Math.hypot(e.x-player.x,e.y-player.y);
if(distP<e.r+player.r){
player.hp-=1;
enemies.splice(i,1);
continue;
}
//子弹击中敌人
for(let j=bullets.length-1;j>=0;j--){
const b=bullets[j];
const dist=Math.hypot(b.x-e.x,b.y-e.y);
if(dist<e.r+b.r){
e.hp--;
bullets.splice(j,1);
if(e.hp<=0){
enemies.splice(i,1);
score+=10;
}
break;
}
}
}
//绘制子弹
ctx.fillStyle='#fff';
bullets.forEach(b=>{
ctx.beginPath();
ctx.arc(b.x,b.y,b.r,0,Math.PI*2);
ctx.fill();
})
//绘制敌人
ctx.fillStyle='#f44336';
enemies.forEach(e=>{
ctx.beginPath();
ctx.arc(e.x,e.y,e.r,0,Math.PI*2);
ctx.fill();
})
//绘制玩家
ctx.save();
ctx.translate(player.x,player.y);
ctx.rotate(player.angle);
ctx.fillStyle='#2196F3';
ctx.beginPath();
ctx.arc(0,0,player.r,0,Math.PI*2);
ctx.fill();
ctx.fillRect(10,-4,22,8);
ctx.restore();
//文字UI
ctx.fillStyle='#fff';
ctx.font='20px Arial';
ctx.fillText(`分数:${score}`,15,30);
ctx.fillText(`血量:${player.hp}`,15,58);
if(player.hp<=0){
ctx.fillStyle="#ff3333";
ctx.font="40px Arial";
ctx.textAlign="center";
ctx.fillText("游戏结束!刷新重新开始",canvas.width/2,canvas.height/2);
return;
}
requestAnimationFrame(loop);
}
loop();
</script>
</body>
</html>Game Source: 简易枪战小游戏
Creator: CyberRanger21
Libraries: none
Complexity: moderate (172 lines, 4.0 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-cyberranger21" to link back to the original. Then publish at arcadelab.ai/publish.