在 AI 编程工具大量出现之后,做一个小游戏原型已经不是从零写类、调碰撞检测的事情了。用 CodeUI 这类以对话为核心的 AI 编码界面,只需要把玩法描述清楚,工具就能生成一个可以打开的前端页面。这里以一个 AI 割草游戏为例,你可以在几分钟内得到一个可运行的 Canvas 游戏,并且整个过程消耗的 token 费用可能只有两毛钱左右。这篇文章围绕生成、运行、验证、排查和成本控制展开,适合想尝试 AI 编程但又不知道如何下手的前端初学者,也适合想了解 AI 生成代码边界的前端工程师。
割草游戏并不是真的“割草”,而是借用了“怪物像草一样成片倒下”的玩法体验。玩家控制角色在地图里移动,攻击范围内的敌人会被自动清除,敌人不断从边缘生成,玩家要在越来越密集的攻击中坚持更久。用 AI 辅助生成这样一个小游戏,最大的好处是省去了从零搭页面、写主循环、调碰撞的重复劳动,同时也能快速验证玩法的核心感觉。不过,AI 不是项目保姆,它擅长的是“把一个清晰任务变成代码”,而不是“替你把一团乱麻的需求理清楚”。
1. 先理解 CodeUI 的边界和割草游戏的最小技术形态
1.1 CodeUI 是编码助手,不是项目保姆
CodeUI 是一个面向编码场景的 AI 工具界面,核心交互方式是自然语言对话。你输入需求,它会返回代码片段、解释或修改建议;你可以针对某个文件继续追问,也可以把报错信息贴进去,让它协助定位。它可以把一个完整的单文件游戏生成出来,但它并不理解你的部署环境、美术资源、后续维护计划。所以使用它的正确姿势,是把它当作一个随叫随到的结对程序员,而不是把整个项目托付给它。
在实际项目中,CodeUI 更擅长处理以下几类任务:
- 生成一个结构完整的单文件页面;
- 修改某个函数的行为,比如攻击间隔、移动速度;
- 解释一段陌生代码的作用;
- 根据报错日志给出排查方向;
- 为已有代码补充注释或测试。
它不擅长的任务包括:
- 在没有约束的情况下生成一个可扩展的大型游戏架构;
- 自动处理资源加载、跨浏览器兼容、安全防护;
- 理解你心中模糊的“好玩”或“流畅”;
- 代替你做出技术选型决策。
因此,做 AI 割草游戏前,最好把需求拆成“第一版最小玩法”和“后续迭代”两个阶段。第一版只需要包含玩家移动、敌人移动、自动攻击、分数统计四个核心点。后续再逐步加入更丰富的敌人类型、音效、升级效果。
1.2 割草游戏需要哪些核心技术点
割草游戏本质上是“幸存者类”玩法:玩家在一个有限地图上移动,敌人不断增加,玩家依靠自动攻击在高压下生存。最小技术组成可以用一张表说明:
| 模块 | 作用 | 实现方式 |
|---|---|---|
| 游戏画布 | 所有角色和特效的绘制区域 | HTML 的<canvas>元素 |
| 玩家 | 键盘控制位置,自动攻击 | 保存 x、y、速度、攻击范围 |
| 敌人 | 从边缘生成并朝玩家移动 | 数组保存多个敌人对象,逐帧更新坐标 |
| 主循环 | 持续更新状态和重绘画布 | requestAnimationFrame |
| 碰撞检测 | 判断敌人是否攻击到玩家、子弹是否命中敌人 | 判断两点距离小于半径之和 |
| 计分与结束 | 击杀增加分数,碰撞后结束 | DOM 刷新分数,弹出结束画面 |
如果是零基础读者,可能会把“碰撞检测”想得很神秘。其实在 2D 小游戏里,最常用的是圆心距离判断:两个圆形物体如果中心距离小于两者半径之和,就认为发生了碰撞。这个方案实现简单,也足够覆盖大多数小游戏场景。
1.3 为什么用纯前端单文件实现
用 CodeUI 生成割草游戏时,推荐把目标设定为一个index.html文件,CSS 和 JavaScript 都写在里面。这样做的原因很实际:
- 浏览器双击就能打开,不需要安装 Node.js、配置 Webpack;
- AI 一次对话就能输出完整文件,避免了多文件之间的引用关系;
- 代码量小,容易审查,出现问题可以直接在控制台排查;
- 方便把 AI 生成的代码作为第一版原型,后续再拆模块迁移到正式工程。
学习阶段使用纯前端单文件没有问题。但如果目标是发布到线上,让玩家稳定游玩,就需要考虑模块化、资源压缩、异常监控、跨平台兼容等问题。这个差异在后面的章节会具体展开。
2. 环境准备:只需要浏览器和 CodeUI 工作区
2.1 准备工具
在开始生成代码之前,先把需要用到的工具准备好。不要把时间浪费在“生成完发现没法运行”这种问题上。
| 工具 | 作用 | 最低要求 |
|---|---|---|
| CodeUI 工作区 | 与 AI 对话并获取代码 | 能正常登录,选择可用的编码模型 |
| 现代浏览器 | 运行 HTML 文件、查看控制台 | Chrome 或 Edge 最新稳定版 |
| 本地目录 | 保存生成的 HTML 文件 | 一个普通文件夹即可 |
| 可选的本地静态服务 | 如果使用 file 协议遇到资源限制 | Python 或 Node.js 环境 |
CodeUI 的入口可能在不同版本中有所不同,常见的是 Web 端和桌面端。无论哪个版本,核心能力都是通过对话生成代码。如果登录后看不到模型选择,可以先使用工具默认模型;不同模型的能力和计费有差异,后续再根据需求调整。
2.2 写出第一版需求描述
很多人在第一次使用 AI 编程时,只写一句话:“帮我做一个割草游戏”。这句话信息量太少,生成的代码大概率不符合预期。更好的方式是把需求拆成可执行的特征清单。
下面是一个适合第一版生成的提示词示例:
请帮我生成一个完整的 HTML 文件,包含 CSS 和 JavaScript,实现一个 AI 割草游戏。要求: 1. 使用 Canvas 画布,游戏区域为 800x600。 2. 玩家用 WASD 移动,是蓝色圆形。 3. 敌人是红色圆形,从屏幕边缘随机生成,并向玩家移动。 4. 玩家会自动攻击:每 0.5 秒攻击一次,攻击范围内所有敌人受到伤害。 5. 敌人血量 3 点,被击中后闪烁,血量为 0 时消失并加分。 6. 左上角显示击杀数。 7. 当玩家碰到敌人时游戏结束,显示得分。 8. 代码保持在一个 index.html 文件中,注释清楚。这段提示词为什么有效?因为它把“游戏”拆成了视觉、输入、玩法、对象属性、结果反馈几个维度。CodeUI 不需要猜测“割草”到底是什么意思,只需要照着约束生成代码。
要注意,这里没有写“AI 割草游戏”里的 AI 二字,因为 AI 在这里指的是使用 AI 工具来制作,而不是游戏里具备 AI 行为。如果想让敌人具备更智能的移动避障,可以在后续迭代中补充描述。
2.3 检查工具输出格式和运行方式
CodeUI 可能返回一个完整的index.html,也可能只返回某段 JavaScript。第一次使用时要先确认输出格式。
如果把 AI 返回的内容保存为 HTML 文件后打开是空白页,最常见的原因是内容不完整。判断方法很简单:在文件里搜索<!DOCTYPE html>、<canvas>、<script>这几个标签。如果缺少任意一个,说明 AI 可能只生成了代码片段,需要继续追问让它补全为完整 HTML 文档。
保存文件时要注意编码。Windows 记事本默认可能保存为带 BOM 的编码,可能会导致脚本解析异常。建议使用 VS Code 等编辑器,并将文件编码设为 UTF-8。HTML 的<head>里最好保留<meta charset="UTF-8">,避免中文乱码。
3. 跑通第一版:生成、保存、运行、验证
3.1 第一次生成后的保存步骤
拿到 AI 输出后,按以下步骤保存并运行:
- 复制 AI 输出的完整 HTML 内容。
- 在本地创建一个新文件夹,比如
ai-mower-game。 - 在文件夹里新建
index.html,把内容粘贴进去。 - 保存后,双击
index.html,用浏览器打开。 - 如果浏览器没有正常显示,按 F12 打开控制台查看报错。
如果希望使用本地静态服务运行,可以在项目目录中打开终端,执行:
python -m http.server 8000然后访问http://localhost:8000。对于纯 Canvas 小游戏,file://协议通常也可用,但使用本地服务更接近生产环境,也能避免某些浏览器对本地文件的限制。
3.2 打开后应看到的画面
第一版正常运行后,浏览器中应该出现一个 800x600 的 Canvas 画布:
- 蓝色圆形代表玩家;
- 红色圆形代表敌人;
- 敌人随机从屏幕边缘出现并朝玩家移动;
- 玩家按 WASD 键移动;
- 玩家自动攻击范围内的敌人;
- 左上角显示击杀数;
- 玩家碰到敌人后,游戏结束并显示得分。
如果打开后画面不符合预期,不要直接修改代码。先按 F12 打开控制台,看有没有红色报错。AI 生成的代码即使整体思路正确,也可能因为某个变量名不一致、某个方法拼写错误导致白屏。
3.3 常见第一版失败现象
| 现象 | 可能原因 | 处理方案 |
|---|---|---|
| 页面完全空白 | HTML 不完整,或 JavaScript 运行时报错 | 打开控制台查看报错,让 CodeUI 补全文件 |
| 键盘操作无反应 | 事件监听没有绑定到window或document | 检查keydown事件代码,改用window.addEventListener('keydown', ...) |
| 敌人不生成 | 生成逻辑写在初始化函数里但没有调用 | 检查生成函数是否在gameLoop中定时执行 |
| 攻击不生效 | 攻击半径设置过小,或攻击计时器逻辑混乱 | 把攻击计时、范围判断打印到控制台 |
| 中文乱码 | 文件保存编码不是 UTF-8 | 重新保存为 UTF-8,并在 head 中加charset="UTF-8" |
这一阶段的目标是让游戏“可玩”,而不是“好玩”。只要玩家能移动、敌人能生成、攻击能击杀、碰撞能结束,第一版就算跑通了。
4. 关键代码拆解:AI 割草游戏的核心机制
AI 生成代码后,不应该直接当作黑盒使用。就算不写代码的人,也应该理解这几个核心机制,否则后续迭代和排查都会很被动。这一节给出核心代码片段,方便你在询问 CodeUI 时参考;实际生成代码可能略有不同,但思路是一致的。
4.1 游戏主循环
游戏本质上是一个不断刷新画面的循环。每次刷新时,计算时间差值dt,更新所有对象的位置,然后重新绘制画面。
let lastTime = 0; function gameLoop(timestamp) { const dt = (timestamp - lastTime) / 1000 || 0; lastTime = timestamp; update(dt); render(); requestAnimationFrame(gameLoop); } requestAnimationFrame(gameLoop);这里的dt是两帧之间的时间差,单位为秒。游戏中的移动速度应该乘以dt,这样无论浏览器帧率是 60 还是 30,角色移动速度都不会明显变化。这是小游戏开发中一个非常重要的习惯。
4.2 玩家移动与边界
玩家对象通常包含x、y、speed、radius等属性。键盘状态可以用一个对象保存。
const keys = {}; window.addEventListener('keydown', e => { keys[e.code] = true; }); window.addEventListener('keyup', e => { keys[e.code] = false; }); function updatePlayer(dt) { let dx = 0; let dy = 0; if (keys['KeyW']) dy -= 1; if (keys['KeyS']) dy += 1; if (keys['KeyA']) dx -= 1; if (keys['KeyD']) dx += 1; if (dx !== 0 || dy !== 0) { const len = Math.hypot(dx, dy); player.x += (dx / len) * player.speed * dt; player.y += (dy / len) * player.speed * dt; } player.x = Math.max(player.radius, Math.min(800 - player.radius, player.x)); player.y = Math.max(player.radius, Math.min(600 - player.radius, player.y)); }方向向量归一化的原因是:如果同时按 W 和 D,斜向移动速度不应该比单独按 W 更快。这个细节 AI 生成时不一定都会处理,读代码时要注意检查。
边界限制用Math.max和Math.min夹住坐标,确保玩家不会跑出画布。
4.3 自动攻击
自动攻击不是每帧都产生伤害,而是按照固定间隔触发。常见的实现方式是用一个计时器倒计时。
let attackTimer = 0; const attackInterval = 0.5; const attackRange = 150; function updateAttack(dt) { attackTimer -= dt; if (attackTimer > 0) return; attackTimer = attackInterval; enemies.forEach(enemy => { const dist = Math.hypot(enemy.x - player.x, enemy.y - player.y); if (dist < attackRange) { enemy.hp -= 1; enemy.hitFlash = 0.1; } }); }这段代码展示了“范围攻击”的核心:遍历所有敌人,计算每个敌人到玩家的距离,距离小于攻击半径时扣血。用距离判断而不是矩形判断,是因为圆形角色的攻击范围更自然。
攻击间隔attackInterval可以放在玩家对象上,方便后续做武器升级后的数值调整。
4.4 敌人生成、移动与碰撞检测
敌人对象需要有位置、速度、血量、半径属性。生成时可以从四个边缘随机取一个方向,并给一个朝向玩家的初始速度。
function spawnEnemy() { const side = Math.floor(Math.random() * 4); let x, y; if (side === 0) { x = -20; y = Math.random() * 600; } if (side === 1) { x = 820; y = Math.random() * 600; } if (side === 2) { x = Math.random() * 800; y = -20; } if (side === 3) { x = Math.random() * 800; y = 620; } enemies.push({ x, y, speed: 60 + Math.random() * 40, hp: 3, radius: 12, hitFlash: 0 }); }碰撞检测在update中完成。玩家碰到敌人后游戏结束:
let gameOver = false; function checkCollision() { for (const enemy of enemies) { const dist = Math.hypot(enemy.x - player.x, enemy.y - player.y); if (dist < enemy.radius + player.radius) { gameOver = true; break; } } }注意,这里判断的是“中心距离小于两个半径之和”,而不是小于玩家半径,否则敌人会嵌进玩家身体后才判定结束。两个圆形物体发生接触时,中心距离一定小于等于半径之和。
4.5 分数刷新与游戏结束
分数通常维护在变量里,每次击杀敌人时递增,同时更新 DOM。
let score = 0; function updateScore() { score++; document.getElementById('score').textContent = '击杀: ' + score; }游戏结束后,停止主循环或设置gameOver标志,然后在画布上绘制结束文字。
if (gameOver) { ctx.fillStyle = 'rgba(0, 0, 0, 0.6)'; ctx.fillRect(0, 0, 800, 600); ctx.fillStyle = '#fff'; ctx.font = '36px sans-serif'; ctx.textAlign = 'center'; ctx.fillText('游戏结束,得分: ' + score, 400, 300); return; }这段代码把结束界面直接画在 Canvas 上,省去了额外的 DOM 结构。对于原型来说够了,后续如果要加“重新开始”按钮,可以让 CodeUI 在结束画面中增加一个按钮和对应的事件处理。
5. 用 CodeUI 做第二轮迭代:从能玩到更好玩
第一版跑通后,会立刻感受到玩法上的单调。这时就是使用 CodeUI 做第二轮迭代的最佳时机。迭代的核心是“用自然语言描述问题,并且只改一个点”。
5.1 用自然语言描述问题
如果觉得敌人类型太少,可以这样对 CodeUI 说:
现在敌人太单调,请增加两种敌人: 1. 一种黄色圆形敌人,速度慢,血量为 6,移动速度 30。 2. 一种青色圆形敌人,速度快,血量只有 1,移动速度 120。 不要改变玩家移动和攻击逻辑。只需要修改敌人生成部分,让三种敌人都能随机出现。这段提示词里,最关键的不是“增加两种敌人”,而是最后一句“不要改变玩家移动和攻击逻辑”。因为 AI 默认会尽量满足你的描述,但有时它会顺手重构整个文件,导致你之前调的参数被重置。每次迭代都明确限定修改范围,能减少这类问题。
5.2 迭代提示词的分寸
迭代时一次只提一个核心需求。例如:
- 第一轮:增加敌人类型。
- 第二轮:增加攻击特效。
- 第三轮:增加经验值和升级。
- 第四轮:增加音效。
不要把“增加敌人类型、攻击特效、经验值、升级、音效、排行榜”一次性塞给 AI。需求太多时,AI 生成的代码会变得难以审查,任何一个逻辑出错,你都不知道是哪个需求导致的。每个需求都单独验证一遍,再进入下一个。
如果要同时改三个参数,可以直接明确写到提示词里:
把玩家的移动速度从 200 改为 250; 把攻击间隔从 0.5 秒改为 0.4 秒; 把攻击范围从 150 改为 180。这种数值型需求,AI 通常能准确处理。改完之后要用浏览器实际验证手感,不要只看代码。
5.3 控制迭代成本
AI 编程的“钱”主要体现在 token 消耗上。每次对话都会把之前的上下文一起发送给模型,对话越长,token 越多。成本控制的核心策略是:不让上下文无限制膨胀。
| 策略 | 做法 | 效果 |
|---|---|---|
| 分阶段对话 | 完成一个需求后,新开一个对话再继续 | 避免海量历史代码被反复计费 |
| 限定修改范围 | 明确说“只修改 xx 函数” | 减少 AI 重新生成无关代码 |
| 合并小需求 | “把移动速度调到 250,攻击间隔调到 0.4” | 减少请求次数 |
| 使用更小模型 | 如果工具支持,简单场景用低参数模型 | 单价更低,响应更快 |
| 及时结束 | 原型完成就停止对话 | 避免无意义的闲聊消耗 |
标题里“只花了两毛钱”是一个成本参考。实际费用取决于模型定价、上下文长度和生成代码量。以单文件 HTML 小游戏为例,输入提示词只占几十到几百 token,输出代码几百行,完整费用通常不高。使用前可以在 CodeUI 的用量页面查看具体消耗,以实际计费为准。
6. 运行验证和成本复盘
6.1 功能验收清单
无论 AI 生成代码多快,最终都要靠人工验收。下面这个清单可以直接复制使用:
- [ ] 页面打开后不报错,无白屏;
- [ ] WASD 可以控制玩家移动,玩家不会移出画布;
- [ ] 敌人从画布边缘随机生成,并向玩家移动;
- [ ] 玩家自动攻击,范围内敌人血量减少;
- [ ] 敌人血量归零后消失,击杀数增加;
- [ ] 玩家碰到敌人后显示结束画面和最终得分;
- [ ] 刷新页面可以重新开始;
- [ ] 浏览器控制台没有任何红色报错;
- [ ] 游戏长时间运行不出现明显卡顿。
前五项是功能验收,后三项是稳定性和体验验收。第一版如果全部通过,就可以进入迭代;如果某一项失败,先把这个问题修掉再继续。
6.2 如何估算 token 和成本
cost 估算在 AI 编程里是一个很实际的问题。尽管不同平台的计费方式不同,但总可以按三步来估算:
- 在 CodeUI 的用量页面查看本次对话的输入 token 和输出 token。
- 将输入 token 乘以模型输入单价,输出 token 乘以输出单价。
- 把总费用换算成人民币或美元。
如果工具没有直接显示 token,可以保守估计:一个汉字大约 1 到 2 个 token,一行代码大约 5 到 10 个 token。生成一个 300 行的 HTML 文件,输出 token 通常在 2000 到 4000 之间。相比聊天场景,编码场景的输出 token 更多,但仍然属于小量级消耗。
这里要强调一点:不同模型、不同时段的定价可能变化,不能把某个固定数字当成长期标准。更合理的做法是“小步快跑、及时复盘”,每次迭代后记录 token 消耗和费用,形成自己对成本的感知。
6.3 学习环境和生产环境的差异
用 CodeUI 做出来的单文件游戏,适合学习、演示、原型验证。如果要部署给真实用户,还需要考虑更多问题。
| 项目 | 学习环境 | 生产环境 |
|---|---|---|
| 代码组织 | 单 HTML 文件 | 模块化拆分,按需加载 |
| 资源加载 | 本地相对路径 | CDN、OSS、资源指纹 |
| 配置 | 写死在代码里 | 外置配置,环境区分 |
| 日志 | 浏览器 console | 日志上报、错误监控 |
| 性能 | 小对象数量可使用数组遍历 | 对象池、空间分区、帧率监控 |
| 安全 | 本地原型不用考虑 | 输入校验、防作弊、防注入 |
| 测试 | 手动验玩 | 单元测试、自动化浏览器测试 |
如果你的目标只是体验 AI 生成代码的能力,或者做一个课堂演示,单文件原型完全够用。如果你想发布到线上,建议把 Canvas 绘制逻辑和游戏逻辑拆成独立模块,再补充测试和监控。
7. 常见问题排查
7.1 浏览器控制台报错
AI 生成代码后出现报错非常正常。关键是学会看报错信息,而不是直接让 AI 重写整个文件。
Uncaught TypeError: Cannot read properties of null (reading 'getContext')这个报错说明获取 Canvas 上下文时,canvas元素为 null。可能原因:
- HTML 中
<canvas id="gameCanvas">没有写。 - JavaScript 在
<canvas>出现之前就执行了。 getElementById的 id 和 HTML 中的不一致。
检查顺序:先看 HTML 里有没有 canvas,再看 script 标签的位置,最后核对 id 名称。如果是执行顺序问题,可以把<script>移到</body>之前。
7.2 动画卡顿
游戏在敌人数量增多后变卡,通常是每帧执行的逻辑过重。常见原因包括:
- 每帧创建新的对象,导致垃圾回收频繁;
- 敌人数量无限增长,没有清理机制;
- 每帧遍历大量敌人做高成本计算。
解决办法:
- 敌人死亡后从数组移除,而不是仍然保留在数组中;
- 限制最大敌人数量;
- 碰撞检测可以先按区域粗略过滤,再精确计算;
- 如果使用粒子效果,控制粒子池大小。
先查看控制台的 Performance 面板,确认卡顿是 CPU 还是内存问题,再针对性优化。
7.3 攻击不生效或敌人不消失
如果玩家移动正常,但敌人不扣血、不消失,重点检查攻击逻辑:
- 攻击计时器是否在
update中执行; - 攻击范围是否设置得太小;
- 敌人血量是否是数字类型,而不是字符串;
- 扣血后是否重新渲染了敌人。
可以在代码中临时加入console.log(enemy.hp)来观察血量变化。如果一直没有扣血,说明攻击范围判断或计时器没有触发。
7.4 AI 生成代码与需求不符
出现这种情况,先不要急着怪 AI 能力不行。多数原因是需求描述不够具体。比如只写“增加攻击特效”,AI 可能只是加了一个简单的圆形光效。如果你希望“攻击时出现剑光,持续 0.2 秒后消失”,就要把这个约束写清楚。
| 现象 | 可能原因 | 检查方式 | 处理方案 |
|---|---|---|---|
| 保存后白屏 | 生成的 HTML 不完整 | 搜索 doctype、canvas、script | 让 AI 补全为完整文件 |
| 中文乱码 | 编码不是 UTF-8 | 用编辑器查看编码 | 保存为 UTF-8 并加 charset |
| 敌人数量暴涨 | 生成间隔太短或未限制 | 打印敌人数组长度 | 增加生成间隔和最大数量 |
| 攻击无效果 | 攻击计时器未运行 | 控制台输出 attackTimer | 检查 update 调用链 |
| 碰撞不结束 | 碰撞距离判断错误 | 输出玩家与敌人距离 | 改为半径之和判断 |
排查顺序建议:先确认输入是否正确,再看文件路径和命名,然后检查依赖和配置,最后才看代码本身。对于 AI 生成的小游戏,90% 的问题都出在“文件不完整”和“事件绑定缺失”上。
8. 最佳实践:把 CodeUI 当作结对程序员,而不是自动生成器
8.1 Prompt 写法清单
与 CodeUI 对话时,好的 prompt 应该具备五个要素:角色、任务、约束、输入输出、异常处理。
角色:你是前端开发工程师。 任务:生成一个 index.html 文件,实现一个画布小游戏。 约束:使用原生 JavaScript,不依赖外部库,不使用构建工具。 输入:玩家按 WASD 移动。 输出:左上角显示击杀数,玩家被敌人碰到后结束。 异常:敌人从边缘生成时,不要超出画布边界。这条 prompt 比“帮我写一个游戏”好得多,因为它让 AI 知道“做成什么样算完成”。如果你对某个功能有具体要求,就在 prompt 中继续追加。比如“玩家不能移动到画布外”“攻击范围圆形可视化显示”“敌人死亡后掉落经验星”等。
8.2 不要完全信任 AI 生成的代码
AI 生成代码的速度快,但不代表一定正确。每次生成后,至少要阅读以下几部分:
- 主循环是否正常启动;
- 玩家坐标是否被正确更新;
- 敌人数组是否能被清理;
- 碰撞检测是否使用了合理的半径;
- 结束状态是否阻止了后续更新。
一个实用做法是把“需求描述”和“验收清单”放在同一个文档里。AI 生成完代码后,你按清单逐项测试。这样既不会漏掉功能,也方便在下次迭代时回顾。
此外,不要直接在生产环境使用 AI 生成的关键逻辑。至少需要经过代码审查、单元测试和压力测试。AI 生成代码的价值是提高效率,而不是降低代码质量标准。
8.3 从割草游戏继续扩展的方向
把这个最小割草游戏跑通后,可以从以下方向继续练习:
- 增加武器升级系统:击杀敌人获得经验,经验可升级攻击范围、攻击间隔、移动速度;
- 增加多种敌人和 BOSS:为不同类型敌人设计不同行为,比如远程攻击、自爆、分裂;
- 增加技能选择:每次升级时提供三个随机技能,玩家选一个;
- 增加关卡设计:限定存活时间,时间到进入下一关;
- 增加音效和背景音乐:用 Web Audio API 生成简单的合成音效;
- 增加移动端支持:把 WASD 改成虚拟摇杆,适配触屏事件。
每扩展一个功能,都按“新开对话、写清 prompt、单测验收”的流程走一遍。这样能积累出属于自己的 AI 编程工作流,也能更清楚地知道每次迭代到底花掉了多少 token 和费用。
如果你从没有用 AI 生成过完整游戏,建议先把这个最小割草游戏跑通,再逐步增加需求。AI 生成代码的价值不在于一次性交付,而在于把无聊的样板代码省掉,让你把注意力放在玩法的设计和验证上。下一步可以试着让 CodeUI 增加一个 BOSS 技能,或者把你的角色改成碰撞体为矩形的模型。每改一次,记录一下 prompt 和 token 消耗,你会越来越清楚 AI 编程的边界在哪里。