1. 为什么我决定用 AI 来搓一个游戏 Demo
先说结论:我用两个小时的碎片时间,借助 AI 编程助手,从零做出了一个能跑、能玩、有完整循环的小游戏 Demo,名字叫《霓虹地窖》。它不是那种点一下就没的玩具,而是包含了角色移动、敌人 AI、战斗判定、掉落系统和简单关卡递进的完整原型。这篇文章我会把整个制作流程、踩过的坑、以及每一步为什么这么选,全部摊开讲清楚。
你可能会问,两小时做游戏,是不是标题党?说实话,如果放在三年前,我也不会信。但现在的 AI 编程工具,尤其是大模型驱动的代码生成和补全,已经能把“写样板代码”这件事压缩到几乎为零。真正花时间的,反而是你想清楚要做什么、以及调试那些 AI 写错的逻辑。所以这篇文章适合三类人看:一是想快速验证游戏创意的独立开发者,二是对 AI 辅助编程好奇但没实操过的程序员,三是想了解“AI 到底能不能干活”的产品经理和测试同学。
《霓虹地窖》的核心玩法很简单:你控制一个发光的方块,在一个赛博朋克风格的地窖里移动,躲避并击杀不断刷新的敌人,每清完一波就往下走一层。听起来像《吸血鬼幸存者》的极简版,对吧?没错,我就是故意选这种结构简单、但系统完整的类型,因为它最适合用来展示 AI 辅助开发的全流程。
我用的工具链很朴素:一个 AI 编程助手(我用的是支持长上下文和代码生成的大模型),一个轻量级游戏引擎(我选了 Pygame,因为它的 API 足够简单,AI 训练数据里也足够多),以及一个普通的代码编辑器。没有用 Unity 或 Unreal,原因后面会细说。
2. 整体设计思路与工具选型拆解
2.1 为什么选 Pygame 而不是 Unity
这个决定其实花了我十分钟。Unity 功能强大,但对 AI 辅助来说有个致命问题:它的项目结构太复杂,场景文件、预制体、材质球这些东西都是二进制或半结构化的,AI 很难直接生成可用的完整工程。你让 AI 写一个 Unity 脚本,它能写,但你要把它挂到哪个 GameObject 上、参数怎么配,还是得手动搞。而 Pygame 是纯代码驱动的,所有逻辑都在 Python 文件里,AI 可以一次性生成整个游戏的骨架,我只需要跑起来看效果。
另一个原因是启动成本。Unity 新建一个项目要等半天,编译一次几十秒。Pygame 就是pip install pygame,然后python main.py,秒级反馈。对于两小时做 Demo 这个目标来说,反馈速度就是生命线。
当然,Pygame 也有明显短板:没有内置的物理引擎、没有动画系统、性能上限低。但《霓虹地窖》这种 2D 俯视角、几十个实体的游戏,Pygame 完全够用。如果你要做 3D 或者复杂物理,那还是得回到 Unity 或 Godot,AI 辅助的收益会打折扣。
2.2 游戏核心循环的设计取舍
我一开始想做的其实更复杂:有装备系统、有技能树、有剧情对话。但很快我就砍掉了。原因很简单:两小时的时间预算下,每增加一个系统,就多一份 AI 可能写错、我需要调试的风险。所以我定了一个原则:只做“最小可玩循环”。
最终的核心循环是这样的:
- 玩家进入地窖,出现在随机位置
- 敌人从边缘刷新,向玩家移动
- 玩家用方向键移动,空格攻击
- 攻击命中敌人,敌人扣血,死亡后掉落经验
- 经验攒够升级,玩家属性提升
- 清完一波敌人,地窖“下沉”一层,敌人变强
- 玩家死亡,显示分数,可以重开
这个循环里,每一个环节都是独立的、可测试的。AI 生成代码后,我可以逐个模块验证,而不是面对一个巨大的黑盒。这一点非常重要,后面讲调试的时候会再展开。
2.3 AI 在流程中扮演的角色定位
我把 AI 当成一个“手速极快但需要监督的初级程序员”。它能帮我做这些事:
- 生成项目骨架和样板代码
- 实现具体的算法逻辑(比如碰撞检测、寻路)
- 写配置文件和资源加载代码
- 解释报错信息并给出修复建议
但它不能做这些事:
- 判断游戏好不好玩
- 决定数值平衡
- 处理模糊的需求(比如“手感好一点”)
- 保证代码没有隐藏 bug
所以我的工作流是:我负责设计和验收,AI 负责实现和填空。这个分工贯穿了整个两小时。
3. 核心细节解析与实操要点
3.1 项目结构怎么搭才不容易乱
AI 生成代码最大的问题是“全塞一个文件”。如果你直接说“帮我写一个游戏”,它很可能给你一个 800 行的main.py,所有逻辑混在一起。这种代码能跑,但一旦出 bug,你根本不知道从哪查。
我的做法是先手动定好目录结构,再让 AI 往里面填。最终的结构是这样的:
neon_cellar/ ├── main.py # 入口,游戏循环 ├── settings.py # 所有常量配置 ├── player.py # 玩家类 ├── enemy.py # 敌人类 ├── bullet.py # 攻击判定 ├── level.py # 关卡和波次管理 ├── ui.py # 血条、分数显示 └── assets/ # 图片和音效(我用纯色块代替)这个结构的好处是,每个文件职责单一,AI 生成的时候我可以说“只写 player.py,实现移动和攻击”,它就不会跑偏。而且调试的时候,报错信息会直接指向具体文件,定位速度快很多。
注意:不要一开始就让 AI 生成整个项目。先定结构,再逐个文件生成,最后组装。这比一次性生成再拆解要快得多。
3.2 提示词怎么写才能让 AI 输出可用代码
这是整个流程里最关键的技能。我试过几种写法,效果差异巨大。
最差的写法是:“帮我做一个游戏。”AI 会给你一个极其笼统的框架,跑起来一堆报错。
中等写法是:“用 Pygame 做一个俯视角射击游戏,玩家用方向键移动,空格射击。”这个能跑,但细节全靠 AI 猜,比如敌人怎么刷新、碰撞怎么判定,它可能用很粗糙的方式实现。
我最终用的写法是“结构化提示词”,包含五个部分:
- 技术栈:明确说用 Python 3.10 + Pygame 2.5,不要用其他库
- 文件路径:指定生成到哪个文件,比如
player.py - 类和方法签名:告诉它类名、初始化参数、需要哪些方法
- 具体逻辑:用自然语言描述每个方法的行为,越具体越好
- 约束条件:比如“不要用全局变量”“所有坐标用 Vector2”“帧率锁定 60”
举个例子,我生成player.py时的提示词是这样的:
用 Python 和 Pygame 写一个 Player 类,放在 player.py。 类需要: - __init__(self, x, y, speed):初始化位置和速度 - update(self, keys, dt):根据按键更新位置,限制在屏幕内 - draw(self, screen):画一个青色方块,带发光效果 - attack(self):返回一个 Bullet 对象,方向为当前朝向 约束:用 pygame.math.Vector2 处理坐标,不要用全局变量,dt 是秒。这样生成的代码,基本一次就能用,最多改几个参数。
3.3 数值平衡的“拍脑袋”方法论
游戏好不好玩,很大程度取决于数值。但两小时做 Demo,不可能做精细的数值测试。我的方法是:先给一组“能跑”的数值,然后根据实际手感微调。
初始数值我是这么定的:
| 参数 | 初始值 | 调整后 | 调整原因 |
|---|---|---|---|
| 玩家速度 | 200 px/s | 260 px/s | 太慢,躲不开敌人 |
| 敌人速度 | 80 px/s | 110 px/s | 太慢,没压迫感 |
| 玩家血量 | 100 | 100 | 保持 |
| 敌人伤害 | 10 | 15 | 掉血太慢,没紧张感 |
| 攻击冷却 | 0.5s | 0.35s | 手感太钝 |
| 敌人刷新间隔 | 2s | 1.2s | 节奏太拖 |
这些调整都是在实际玩了几十秒后做的,每次只改一两个参数,改完立刻跑。AI 在这里帮不上忙,因为它不知道“手感”是什么。但你可以让 AI 帮你把参数抽到settings.py里,这样改起来不用翻代码。
实操心得:把所有数值常量集中到一个文件,用大写命名。改数值的时候只动这一个文件,不要散落在各个类里。这个习惯能帮你省下大量找参数的时间。
4. 实操过程与核心环节实现
4.1 第一步:搭骨架和游戏循环(约 15 分钟)
我先让 AI 生成main.py和settings.py。settings.py很简单,就是一堆常量:
# settings.py SCREEN_WIDTH = 960 SCREEN_HEIGHT = 640 FPS = 60 PLAYER_SPEED = 260 ENEMY_SPEED = 110 PLAYER_HP = 100 ENEMY_DAMAGE = 15 ATTACK_COOLDOWN = 0.35 ENEMY_SPAWN_INTERVAL = 1.2main.py是游戏主循环,结构是经典的“事件处理 → 更新 → 绘制”三段式。AI 生成的版本基本可用,但我改了两处:一是加了dt(delta time)传递,保证不同帧率下速度一致;二是把退出逻辑从pygame.quit()改成先sys.exit(),避免某些系统上的卡死。
这里有个小坑:AI 默认写的游戏循环往往不带dt,直接用固定像素移动。这在 60 帧下没问题,但如果你电脑性能波动,游戏速度就会变。加上dt后,移动逻辑变成position += speed * dt,就稳了。
4.2 第二步:玩家和攻击系统(约 25 分钟)
player.py是核心。我让 AI 生成了移动、绘制、攻击三个方法。移动逻辑很简单,就是读键盘状态,更新Vector2位置,然后clamp到屏幕边界。
攻击系统稍微复杂一点。我原本想让玩家朝鼠标方向射击,但 AI 生成的代码里,鼠标坐标转换有问题,子弹总是偏。我懒得调,就改成了“朝最后一次移动方向射击”。这个改动反而让操作更简单,适合 Demo。
子弹的实现我单独开了bullet.py,每个子弹是一个对象,有位置、速度、生命周期。更新时位置加上速度乘dt,超出屏幕就销毁。碰撞检测用的是矩形碰撞,pygame.Rect.colliderect,简单够用。
注意:AI 生成的碰撞检测有时候会用像素级检测(
mask),那个性能差很多。对于方块游戏,矩形碰撞完全够,而且快。如果 AI 给你写了mask,直接让它改成Rect。
4.3 第三步:敌人 AI 和波次管理(约 30 分钟)
敌人逻辑我让 AI 写了两种:一种是直线追击,一种是带一点随机偏移的追击。后者更有趣,因为玩家不能站桩输出。
敌人的寻路其实没有寻路,就是每帧计算“玩家位置 - 敌人位置”的方向向量,然后归一化,乘以速度。这个逻辑 AI 一次就写对了,因为太标准了。
波次管理在level.py里。逻辑是:维护一个敌人列表,每隔ENEMY_SPAWN_INTERVAL秒生成一个新敌人,位置在屏幕边缘随机。当敌人列表为空时,进入下一层,敌人速度和血量按比例提升。
这里我踩了一个坑:AI 生成的波次逻辑是“清完所有敌人后等 3 秒再刷新”,但实际玩起来,3 秒的空窗期很无聊。我改成了“清完后立刻刷新,但给玩家一个 1 秒的无敌时间”。这个改动让节奏紧凑了很多。
4.4 第四步:UI 和反馈(约 20 分钟)
UI 包括血条、分数、层数显示。血条我用的是两个矩形叠加:底层红色,上层绿色,宽度按血量比例缩放。分数就是击杀数乘以 10。层数显示在右上角。
反馈方面,我加了两个效果:一是敌人死亡时闪一下白色,二是玩家受伤时屏幕边缘闪红。这两个效果都是 AI 生成的,代码很简单,就是改一下绘制颜色,持续几帧。
音效我没做,因为找素材和调音量太花时间。对于 Demo 来说,视觉反馈已经够了。
4.5 第五步:组装和调试(约 30 分钟)
把所有文件组装起来跑,第一次运行报了三个错:
Vector2没有导入 —— AI 在某个文件里忘了写from pygame.math import Vector2- 敌人列表在遍历时被修改 —— 经典的“删除元素导致跳过”问题,改成用列表推导式过滤
- 攻击冷却计时器用了整数除法 —— 改成浮点数
这三个错都是 AI 生成的典型问题。第一个是遗漏导入,第二个是逻辑陷阱,第三个是类型问题。我直接把报错信息贴给 AI,它给出了修复方案,我验证后应用。
整个调试过程大概花了 30 分钟,其中大部分时间是在反复运行、观察、微调数值。代码层面的 bug 其实不多,AI 写的代码质量比我想象的好。
5. 常见问题与排查技巧实录
5.1 AI 生成的代码跑不起来怎么办
这是最常见的问题。我的排查顺序是:
- 看报错信息的第一行和最后一行。第一行告诉你是什么错,最后一行告诉你在哪一行。中间的是调用栈,新手可以忽略。
- 检查导入。AI 经常忘记导入它用到的模块。
Vector2、math、random是重灾区。 - 检查缩进。Python 对缩进敏感,AI 生成的代码有时候混用空格和 Tab。用编辑器的“显示空白字符”功能看一眼。
- 检查变量名拼写。AI 有时候前后不一致,比如前面叫
enemy_list,后面叫enemies。
如果以上都查了还不行,把完整报错和出错的代码片段一起贴给 AI,让它解释。通常它能指出问题。
5.2 游戏能跑但不好玩,怎么调
“不好玩”通常有三个原因:节奏太慢、反馈太弱、难度曲线不对。
节奏太慢的解决方法是缩短所有时间间隔。刷新间隔减半,攻击冷却减 30%,移动速度加 20%。改完立刻试,直到你觉得“有点忙不过来”为止。
反馈太弱的解决方法是加视觉和听觉刺激。敌人死亡加粒子效果,玩家受伤加屏幕震动,攻击命中加音效。哪怕是最简单的“闪白”,效果也比没有强。
难度曲线不对的解决方法是分层调整。第一层敌人速度设为玩家速度的 40%,每层加 5%。这样前期轻松,后期紧张。
5.3 常见问题速查表
| 问题现象 | 可能原因 | 解决方法 |
|---|---|---|
| 游戏窗口一闪而过 | 主循环没有while或提前退出 | 检查running变量和事件循环 |
| 角色移动速度随帧率变化 | 没有用dt乘速度 | 所有移动逻辑加* dt |
| 子弹不消失 | 生命周期没减或没判断 | 检查bullet.life -= dt和销毁逻辑 |
| 敌人重叠在一起 | 没有分离逻辑 | 加简单的排斥力,或接受重叠 |
| 分数不增加 | 击杀事件没触发 | 检查碰撞检测和score += 10的位置 |
| 游戏越来越卡 | 对象没销毁,内存泄漏 | 检查所有列表是否及时清理 |
实操心得:每次只改一个变量,改完立刻测试。同时改多个参数,你永远不知道是哪个起了作用。这个原则在调数值和调 bug 时都适用。
6. 两小时之后,我得到了什么
最终成品是一个能跑 5 到 10 分钟的小游戏。玩家有移动、攻击、升级,敌人有追击、刷新、增强,关卡有递进,UI 有反馈。代码量大概 600 行,分布在 7 个文件里。从打开编辑器到第一次能玩,花了 1 小时 40 分钟,剩下 20 分钟调数值和修 bug。
这个 Demo 当然不能直接上架,但它验证了核心玩法,也验证了 AI 辅助开发的可行性。如果你也想试,我的建议是:从最小的循环开始,先让 AI 生成能跑的骨架,再逐步加功能。不要一开始就追求完整,那样只会卡在调试里出不来。
另外,AI 生成的代码一定要自己读一遍。不是为了改,而是为了理解。只有你理解了代码在做什么,出问题的时候才能快速定位。把 AI 当工具,别当替身。