91 行代码实现一个打飞机游戏(HTML5 Canvas 版)

很多人觉得做一个小游戏需要复杂的引擎,比如 UnityUnreal Engine

其实未必。

利用 HTML5 CanvasJavaScript ,只需要 91 行代码,就能写出一个可运行的「打飞机小游戏」。

今天带大家一步一步拆解这个极简实现。


一、最终效果

功能非常简单:

  • 方向键控制飞机移动
  • 自动发射子弹
  • 随机生成敌机
  • 子弹击中敌机消失

游戏结构如下:

复制代码
玩家飞机
   ↓
子弹系统
   ↓
敌机生成
   ↓
碰撞检测
   ↓
游戏循环

二、完整代码(约 91 行)

新建 index.html

html 复制代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Mini Plane Shooter</title>
<style>
canvas{background:#000;display:block;margin:auto}
</style>
</head>
<body>
<canvas id="game" width="400" height="600"></canvas>

<script>
const canvas = document.getElementById("game")
const ctx = canvas.getContext("2d")

let player = {x:180,y:520,w:40,h:40,speed:5}
let bullets=[]
let enemies=[]
let keys={}

document.addEventListener("keydown",e=>keys[e.key]=true)
document.addEventListener("keyup",e=>keys[e.key]=false)

function shoot(){
  bullets.push({x:player.x+18,y:player.y,w:4,h:10})
}

setInterval(()=>enemies.push({
  x:Math.random()*360,
  y:-40,
  w:40,
  h:40,
  speed:2+Math.random()*2
}),1000)

setInterval(shoot,300)

function movePlayer(){
  if(keys["ArrowLeft"]) player.x-=player.speed
  if(keys["ArrowRight"]) player.x+=player.speed
  if(keys["ArrowUp"]) player.y-=player.speed
  if(keys["ArrowDown"]) player.y+=player.speed
}

function updateBullets(){
  bullets.forEach(b=>b.y-=8)
  bullets=bullets.filter(b=>b.y>-20)
}

function updateEnemies(){
  enemies.forEach(e=>e.y+=e.speed)
  enemies=enemies.filter(e=>e.y<620)
}

function collide(a,b){
  return a.x<b.x+b.w &&
         a.x+a.w>b.x &&
         a.y<b.y+b.h &&
         a.y+a.h>b.y
}

function checkHits(){
  bullets.forEach((b,bi)=>{
    enemies.forEach((e,ei)=>{
      if(collide(b,e)){
        bullets.splice(bi,1)
        enemies.splice(ei,1)
      }
    })
  })
}

function drawRect(o,color){
  ctx.fillStyle=color
  ctx.fillRect(o.x,o.y,o.w,o.h)
}

function draw(){
  ctx.clearRect(0,0,400,600)
  drawRect(player,"cyan")
  bullets.forEach(b=>drawRect(b,"yellow"))
  enemies.forEach(e=>drawRect(e,"red"))
}

function gameLoop(){
  movePlayer()
  updateBullets()
  updateEnemies()
  checkHits()
  draw()
  requestAnimationFrame(gameLoop)
}

gameLoop()
</script>
</body>
</html>

打开浏览器即可运行。


三、核心原理拆解

整个游戏其实只有 5 个模块

1 玩家飞机

javascript 复制代码
let player = {x:180,y:520,w:40,h:40,speed:5}

控制移动:

javascript 复制代码
if(keys["ArrowLeft"]) player.x-=player.speed

2 子弹系统

子弹是一个数组:

javascript 复制代码
let bullets=[]

定时发射:

javascript 复制代码
setInterval(shoot,300)

子弹每一帧向上移动:

javascript 复制代码
bullets.forEach(b=>b.y-=8)

3 敌机系统

敌机会随机生成:

javascript 复制代码
setInterval(()=>enemies.push({
  x:Math.random()*360,
  y:-40,
  w:40,
  h:40,
  speed:2+Math.random()*2
}),1000)

4 碰撞检测

经典 AABB 碰撞检测

javascript 复制代码
a.x < b.x + b.w &&
a.x + a.w > b.x &&
a.y < b.y + b.h &&
a.y + a.h > b.y

只要矩形重叠就算碰撞。


5 游戏循环

核心循环使用:

javascript 复制代码
requestAnimationFrame(gameLoop)

每一帧执行:

复制代码
更新玩家
更新子弹
更新敌机
检测碰撞
重新渲染

四、为什么 91 行就能做游戏?

小游戏本质其实很简单:

模块 作用
输入系统 键盘控制
游戏对象 飞机 / 子弹 / 敌机
更新逻辑 每帧更新位置
碰撞检测 判断是否击中
渲染 Canvas 绘制

早期很多 HTML5 Demo 游戏 甚至只有 100 行左右代码


五、可以继续扩展什么?

如果继续扩展,可以增加:

  • 分数系统
  • 爆炸动画
  • 多种敌机
  • BOSS
  • 游戏结束界面
  • 音效

再多写 100 行,基本就能做出一个完整小游戏。


六、总结

只用 91 行代码,我们就实现了一个最简版「打飞机游戏」。

关键技术只有:

  • HTML5 Canvas
  • JavaScript
  • requestAnimationFrame
  • 碰撞检测

很多时候:

游戏并不复杂,复杂的是我们的想象。


相关推荐
wanhengidc1 小时前
什么是高性能计算服务器?
大数据·运维·服务器·游戏·智能手机
从文处安2 小时前
「前端何去何从」一直写 Vue ,为何要在 AI 时代去学 React「2」?
前端·react.js
掘金者阿豪2 小时前
深入解读OpenClaw配置文件:一个现代化AI网关的全景洞察
前端
葡萄城技术团队2 小时前
Playwright 官方推荐的 Fixture 模式,为什么大厂架构师却在偷偷弃用?
前端
newbe365242 小时前
ImgBin CLI 工具设计:HagiCode 图片资产管理方案
前端·后端
bluceli2 小时前
CSS Scroll Snap:打造丝滑滚动体验的利器
前端·css
www_stdio2 小时前
深入理解 React Fiber 与浏览器事件循环:从性能瓶颈到调度机制
前端·react.js·面试
工边页字2 小时前
LLM 系统设计核心:为什么必须压缩上下文?有哪些工程策略
前端·人工智能·后端
嚣张丶小麦兜2 小时前
react的理解
前端·react.js·前端框架