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

很多时候:

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


相关推荐
青山Coding1 小时前
Cesium应用(八):物体运动的实现思路
前端·cesium
用户41659673693551 小时前
Android WebView 加载 file:// 离线页面调试教程
android·前端
Asmewill1 小时前
curl命令学习笔记一
前端
我是一只快乐的小螃蟹1 小时前
1.2 ArrayList 源码解析
前端
星栈1 小时前
我用 Rust + Dioxus 做了个全栈跨平台笔记应用:再把新建、编辑和交付补上
前端·rust·前端框架
我是一只快乐的小螃蟹1 小时前
1.1 HashMap (JDK1.8) 源码解析
前端
金銀銅鐵3 小时前
[Python] 模 n 乘法的逆元计算器
python·数学·游戏
爱勇宝4 小时前
小红花成长新版:模板来了,鼓励也更容易开始
前端·后端·程序员
竹林8185 小时前
Solana前端开发:我在一个NFT铸造页面上被@solana/web3.js的Connection和Transaction签名坑了两天
前端
冬奇Lab5 小时前
每日一个开源项目(第144篇):ai-website-cloner-template - 一条命令、多 Agent 并行,把任意网站逆向成 Next.js 代码
前端·人工智能·开源