🛬 我让 AI 帮我写了一个打飞机游戏,结果 Canvas 把我整不会了

写在前面:今天老师带我们体验了一把"Vibe Coding"------就是让 AI 帮我们写代码,我们负责" vibe "(氛围感/方向感)。项目是用 HTML5 Canvas 做一个打飞机游戏,再加一个 ECharts 数据可视化报表。听起来很酷对吧?但当我看到 Canvas 那一堆 API 的时候,我整个人都不好了:这哪是画画,这是在写数学题啊!


一、Canvas:网页上的"神笔马良"

1.1 什么是 Canvas?

老师说:

"Canvas 2d/3d 数据可视化 / 网页游戏 / 酷炫页面。画布,JS API 想怎么画就怎么画。"

<canvas> 是 HTML5 新增的标签,本质上就是一个画布。你可以用 JavaScript 在上面画矩形、画圆、画线、画图片,甚至做 3D 效果。

以前网页上的动画靠 Flash(还记得 4399 小游戏吗?),现在 Flash 凉凉了,Canvas + JavaScript 成了网页游戏和数据可视化的主流方案。

老师还提到:太老旧的浏览器不支持 Canvas 标签。不过都 2026 年了,还在用 IE 的人......建议直接换电脑。

1.2 Canvas 基础:先拿到"画笔"

html 复制代码
<canvas id="myCanvas" width="600" height="400" 
    style="border: 1px solid #333;">
    你的浏览器不支持 Canvas(旧 IE 会显示这段文字)
</canvas>
javascript 复制代码
// 画布元素
const canvas = document.querySelector('#myCanvas');
// 绘制的上下文对象
const ctx = canvas.getContext('2d');

getContext('2d') 就是拿到 2D 画笔。 如果你想玩 3D,就用 getContext('webgl'),能激发 GPU 的显存能力。

老师提到:现在 AI 游戏爆发,Three.js 和物理大模型特别火。不过我们今天先从 2D 开始------毕竟走路还没学会,就别想着飞了。

1.3 绘制基本图形

javascript 复制代码
// 填充矩形
ctx.fillStyle = '#4299e1'; // 填充颜色
ctx.fillRect(20, 20, 100, 80); // 左上角 x, y, 宽, 高

// 边框矩形
ctx.strokeStyle = '#f56565'; // 边框颜色
ctx.lineWidth = 4;
ctx.strokeRect(150, 20, 100, 80);

// 清除矩形区域
ctx.clearRect(50, 50, 40, 30);

Canvas 的坐标系是这样的:

  • 左上角是 (0, 0)
  • X 轴向右增加,Y 轴向下增加。
  • fillRect(x, y, width, height):画一个填充矩形。
  • strokeRect(x, y, width, height):画一个边框矩形。
  • clearRect(x, y, width, height):清除一个矩形区域。

这就像你在一张纸上画画:

  • fillStyle 是选择马克笔的颜色。
  • fillRect 是用马克笔画一个实心方块。
  • strokeRect 是用铅笔画一个空心方框。
  • clearRect 是用橡皮擦擦掉一块。

二、动画的秘密:先擦掉,再重画

2.1 按帧动画:电影的原理

老师讲了动画的核心原理:

"按帧动画:clear 擦掉之前的,画上新的。显卡帧 1s 60 次。"

电影是怎么动起来的?一秒钟放 24 张静态图片,你的眼睛就以为它在动。 游戏更夸张------显卡每秒刷新 60 次(甚至 120 次、144 次),每次刷新都是一张新画面。

Canvas 动画的本质就是:

  1. 擦掉上一帧clearRect)。
  2. 画上新的一帧fillRectdrawImage 等)。
  3. 重复 60 次/秒

2.2 requestAnimationFrame:浏览器的"动画导演"

javascript 复制代码
let x = 20;
const y = 20;
const width = 100;
const height = 80;
const speed = 3;

function animate() {
    // 1. 擦掉整个画布
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    
    // 2. 画新的矩形
    ctx.fillStyle = '#4299e1';
    ctx.fillRect(x, y, width, height);
    
    // 3. 更新位置
    x += speed;
    if (x > canvas.width) {
        x = -width; // 超出右边界,从左边重新出现
    }
    
    // 4. 请求下一帧
    requestAnimationFrame(animate);
}

animate();

这段代码让一个蓝色矩形从左边往右边移动,超出边界后从左边重新出现。

requestAnimationFrame 是浏览器提供的"动画导演" ,它会根据屏幕的刷新率(通常是 60Hz)来调度动画,比 setInterval 更流畅、更省电。

老师特别强调:不能用 setInterval

"时间可能和显示设备的刷帧率不在一个频道上。requestAnimationFrame 是等于刷帧率,体验更协调。"

这就像你跳舞:

  • setInterval:你按自己的节奏跳,不管音乐是什么节拍------容易踩错拍。
  • requestAnimationFrame:你跟着音乐的节拍跳------丝滑流畅,完美同步。

2.3 加上交互,就是游戏

老师一句话点出了游戏的本质:

"帧动画不停地画,就有了动画。加上交互,就是游戏了。"

打飞机游戏的核心逻辑:

  1. 玩家飞机:根据键盘/鼠标位置绘制,可以发射子弹。
  2. 敌机:从上方随机位置出现,向下移动。
  3. 子弹:从玩家飞机发射,向上移动。
  4. 碰撞检测:子弹碰到敌机 → 敌机爆炸消失 + 得分。
  5. 敌机碰到玩家 → 游戏结束。

每一帧都重复:清屏 → 画玩家 → 画敌机 → 画子弹 → 检测碰撞 → 更新分数。


三、Vibe Coding:让 AI 写游戏,我负责" vibe "

3.1 什么是 Vibe Coding?

老师带我们体验了真正的 Vibe Coding:

"可以和 AI 头脑风暴:产品游戏功能列表,选择其中的一些,做第一个阶段的开发。MVP 最小可行性方案。"

流程是这样的:

  1. 和 AI 头脑风暴:列出游戏功能清单(玩家飞机、敌机、子弹、爆炸效果、分数、关卡......)。
  2. 确定 MVP:选最核心的功能,先做第一个可玩的版本。
  3. 确定技术路线:用 Canvas 2D?还是用游戏引擎?
  4. 让 AI 生成代码:描述清楚需求,AI 帮你写。

Vibe Coding 的核心不是"自己写代码",而是"描述清楚需求,让 AI 帮你实现"。 你是导演,AI 是演员。

3.2 工程初始化:Vite + Git

老师说:

"工程初始化:vite, git。帮我们安装必要的依赖,.env。"

用 Vite 初始化项目:

bash 复制代码
npm create vite@latest plane-game --template vanilla

然后:

  • git init 初始化版本控制。
  • 配置 .env 文件(如果有 API Key 的话)。
  • 安装必要的依赖(如果有的话)。

3.3 AI 生成游戏代码

和 AI 对话的大致过程:

:"帮我写一个 Canvas 打飞机游戏,玩家用鼠标控制飞机移动,点击发射子弹,敌机从上方随机出现,子弹击中敌机得分。"

AI:"好的,以下是完整的游戏代码......"

然后 AI 会生成一堆代码:

  • index.html:Canvas 画布。
  • main.js:游戏主循环、事件监听、碰撞检测。
  • player.js:玩家飞机类。
  • enemy.js:敌机类。
  • bullet.js:子弹类。

你不需要从零写,只需要理解代码、调试 bug、调整参数


四、ECharts 数据可视化:让数据"说话"

4.1 什么是 ECharts?

老师提到:

"ECharts 报表。"

ECharts 是百度开源的数据可视化库,用 Canvas 底层绘制各种图表:折线图、柱状图、饼图、雷达图、地图......

和 Canvas 手动画图相比,ECharts 的优势是:

  • 开箱即用:一行代码初始化,配置项驱动。
  • 交互丰富:鼠标悬停显示数据、缩放、拖拽。
  • 响应式:自动适配不同屏幕尺寸。

4.2 ECharts 的基本用法

javascript 复制代码
// 引入 ECharts
import * as echarts from 'echarts';

// 初始化图表
const chart = echarts.init(document.getElementById('chart'));

// 配置项
const option = {
    title: { text: '月度销售额' },
    xAxis: { data: ['1月', '2月', '3月', '4月', '5月'] },
    yAxis: {},
    series: [{
        type: 'bar',
        data: [120, 200, 150, 80, 70]
    }]
};

// 渲染图表
chart.setOption(option);

ECharts 和 Canvas 的关系 :ECharts 底层用 Canvas(或 SVG)绘制,但你不需要直接操作 Canvas API,只需要配置 option 对象。

这就像:

  • 手动 Canvas:你自己买菜、切菜、炒菜------自由度高,但麻烦。
  • ECharts:你去餐厅点菜,告诉服务员要什么,厨师帮你做------省心省力。

五、Canvas 游戏 vs ECharts:同一个底层,不同玩法

对比项 Canvas 游戏 ECharts 报表
核心逻辑 按帧动画 + 交互 数据驱动 + 配置
刷新频率 60fps 实时渲染 数据变化时更新
交互方式 键盘/鼠标实时响应 鼠标悬停、点击、缩放
代码量 较多(手动管理状态) 较少(配置项驱动)
适用场景 游戏、复杂动画 数据可视化、报表

两者底层都是 Canvas,但上层玩法完全不同。 游戏需要手动管理每一帧的状态,ECharts 只需要配置数据和样式。


六、总结:Canvas 是前端人的"魔法画布"

知识点 说明
<canvas> HTML5 画布标签
getContext('2d') 获取 2D 绘制上下文
fillRect/strokeRect/clearRect 绘制/清除矩形
fillStyle/strokeStyle 填充/边框颜色
requestAnimationFrame 浏览器动画调度函数
按帧动画 clear → 画新 → 更新 → 循环
Vibe Coding 描述需求,让 AI 生成代码
ECharts 数据可视化库,配置项驱动

Canvas 是前端人的"魔法画布"------你可以在上面画任何东西,从简单的几何图形,到复杂的游戏,再到炫酷的数据可视化。

但 Canvas 也是一把双刃剑:自由度高,但代码量大;性能好,但调试麻烦。对于数据可视化,ECharts 这样的库能帮你省去大量重复工作。


写在最后

今天最大的收获,是理解了 Canvas 动画的核心原理:先擦掉,再重画,循环 60 次/秒。 以前看游戏代码觉得高深莫测,现在发现底层逻辑其实很简单。

用 Vibe Coding 让 AI 写游戏,我负责理解代码、调试 bug、调整参数------这种方式效率真的高。AI 不是替代程序员,而是让程序员从重复劳动中解放出来,专注于更有价值的部分。

下次面试官问你:"Canvas 动画的原理是什么?"

你可以淡定地说:

"Canvas 动画的核心是按帧渲染。每一帧先 clearRect 清除画布,然后重新绘制所有元素,更新位置状态,最后用 requestAnimationFrame 请求下一帧。requestAnimationFrame 会同步屏幕刷新率(通常 60fps),比 setInterval 更流畅。加上键盘/鼠标交互,就是完整的游戏了。"

然后看着面试官满意的表情,心里默念:这波,又稳了。


本文所有代码示例均来自课堂学习资料,真实可运行。

相关推荐
梯度不陡1 小时前
AI 到底能不能从零写软件?ProgramBench 和 RepoZero 给出了两种答案
前端·javascript·面试
冬奇Lab1 小时前
每日一个开源项目(第137篇):Penpot - 真正开源的设计协作工具,SVG 原生格式消灭设计-开发鸿沟
前端·开源·设计
nuIl2 小时前
实现一个 Coding Agent(7):Skills
前端·agent·cursor
nuIl2 小时前
实现一个 Coding Agent(8):会话持久化与多会话
前端·agent·cursor
jt君424263 小时前
React Native JSI 深入剖析 — 第 5 部分中文技术整理:用 HostObject 把 C++ 类暴露给 JavaScript
前端·react native
胡萝卜术3 小时前
滑动窗口最大值:从暴力到单调队列,层层优化全解析
前端·javascript·面试
fluffyox3 小时前
Notion 的公式栏里,藏着一台虚拟机——逆向 + 用 600 行 JS 复刻它的编译器与栈式 VM
前端
kyriewen4 小时前
2026 年了,这 6 个 npm 包可以卸载了——浏览器原生 API 已经能替代
前端·javascript·npm
铁皮饭盒5 小时前
bun直接tsx,优雅!
javascript·后端