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
  • 碰撞检测

很多时候:

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


相关推荐
+VX:Fegn08951 小时前
计算机毕业设计|基于springboot + vue蛋糕店管理系统(源码+数据库+文档)
前端·数据库·vue.js·spring boot·课程设计
Nicander3 小时前
我给 Excalidraw 做了一个本地工作区:DrawSpace
前端·开源
linux_cfan5 小时前
17 · 引擎适配器全景:HLS/DASH/Vimeo/Mux/Cast
前端·javascript·音视频
计算机魔术师5 小时前
烧掉2780亿美元还不够?OpenAI的资本豪赌让人头皮发麻
前端
IT_陈寒6 小时前
Java线程池用错参数,我的服务居然悄悄崩溃了
前端·人工智能·后端
卡布鲁6 小时前
React useMemo 与 useCallback 完全指南:原理、场景与避坑
前端·react.js
碳基修炼6 小时前
排查记:本地 devServer 是 http,浏览器却把 302 重定向升级成了 https
前端·http
步行cgn6 小时前
Spring p 命名空间注入详解
java·前端·spring
何何____7 小时前
Vue 生命周期详解
前端·javascript
江米小枣tonylua7 小时前
TypeScript 全面の拥抱 !Prisma 8 + Electron 升级实战
前端