
我惦记做游戏这件事不是一天两天了。之前每次下定决心都是在“先做地图还是先做角色”这种问题上纠结到放弃最后留下的产物往往是一个能显示背景色的空窗口。今年AI编程助手的能力大家有目共睹我就想换个方式试试让AI帮我写那些琐碎的脚手架代码我专注在玩法和体验设计上。于是有了这次“浅尝一下AI游戏开发”的完整记录。先解释清楚我在这篇文章里说的“AI游戏开发”其实是两层东西叠加一层是用AI辅助开发也就是让大模型帮我把游戏代码写出来、把报错修掉、把功能迭代上去另一层是游戏内的AI也就是NPC角色并不是脚本走位而是自己拥有“看见、判断、追你、找不到你就回去”的行为逻辑。我这次两手都沾用AI写了一个2D小游戏又在游戏里实现了一个真正跑起来的AI敌人系统。如果你也处在“想试试做游戏但总觉得门槛高”的状态或者你好奇“让AI写游戏代码到底靠不靠谱”这篇博客应该能给你一份真实可参考的答案。毕竟我更想聊的不是“AI多神奇”而是它帮我省了哪些事、又在哪些地方把我带沟里去了。1. 浅尝之前先把“AI游戏开发”这个词拆清楚1.1 两种常见理解这次我两个都碰了很多人一听到“AI游戏开发”要么以为要训练神经网络玩游戏要么以为让AI一键生成一个完整游戏。这两种都不是我这次做的。真实情况是业界大部分“游戏AI”指的还是NPC行为逻辑——敌人会不会绕路、怪物什么时候追击、队友怎么配合这些在游戏行业里已经有几十年的成熟方案主流是状态机、行为树、GOAP这类相对“老派”但极其可靠的方法跟“深度学习”基本不沾边。而我这次实践里用到的“AI写代码”才是这几年才火起来的新东西本质上是大模型根据你的描述来生成代码。我建议第一次尝试的人把这两件事分开理解不然很容易抓不住重点。你可以用AI辅助开发来降低写代码的门槛同时用最经典的状态机方法来实现游戏里的智能两条线互不干扰组合起来反而特别适合入门。1.2 技术选型为什么是Python和Pygame这次项目我直接选了Python配合Pygame库没有纠结更多。选型逻辑其实很直白。Pygame的学习曲线足够平缓一个主循环加几个事件就能把画面跑起来对“想快速看到成果”的入门者非常友好。第二个原因跟AI写代码的效率强相关大模型的训练语料里包含海量Pygame代码示例所以它生成这类代码的“命中率”特别高。我试过用同样的需求去生成网页版Canvas代码结果也还行但生成的Pygame版本明显更少出现一些莫名其妙的逻辑错误。还有一个隐藏原因Pygame的运行依赖非常干净装一个库就行不用配置复杂的环境。对第一次尝试的人来说环境搭建越顺利放弃的概率越低。1.3 我把游戏范围压到了“一晚上能跑起来”新手做游戏最容易犯的错就是开局想太多。什么技能树、装备系统、多张地图、存档读档这些需求一旦堆在一起AI也救不了你因为你的验证循环会变得漫长又混乱。我给自己定的MVP最小可行版本非常克制一张2D小地图玩家用方向键控制角色移动地图上放置3到5个AI敌人敌人有巡逻、警觉、追击三种行为状态追击碰到玩家则游戏结束玩家按空格键释放“闪光弹”让附近敌人短暂失明这个范围小到能在一两个晚上跑通但又能覆盖到游戏开发最核心的几块移动控制、渲染循环、碰撞检测、AI行为、交互道具。后面所有折腾都是在这个地基上长出来的。2. 和AI的第一轮协作从需求描述到可运行骨架2.1 需求描述的写法决定了代码质量很多人让AI写代码喜欢丢一句“帮我做个游戏”结果自然是一堆华丽但没有灵魂的示例代码。我自己第一轮就吃过这个亏后来摸索出一个比较稳定的写法把需求当成给新同事的交接说明来写。我当时的提示词大概长这样分成了几个固定段落项目概述一句话说清楚这是什么游戏技术约束用什么语言、什么库、窗口多大功能清单按优先级列出必须有的交互和系统验收标准怎样才算跑通了比如“玩家碰到敌人后窗口显示Game Over并退出”明确不做的事比如“不需要UI菜单不需要音效”关键的心得是一次性只让AI交付一屏能验证的东西。我第一轮只让它做“窗口玩家角色移动”第二轮加敌人第三轮加AI行为。每轮都先跑起来再继续否则一旦问题混在一起你很难判断是AI代码的锅还是你自己需求描述不清的锅。2.2 收到的第一版骨架代码长什么样AI生成的骨架基本是这个结构比我预想中规范很多import pygame import sys # 初始化 pygame.init() screen pygame.display.set_mode((800, 600)) clock pygame.time.Clock() # 玩家属性 player_pos [400, 300] player_speed 200 # 主循环 running True while running: dt clock.tick(60) / 1000.0 for event in pygame.event.get(): if event.type pygame.QUIT: running False # 按键处理 keys pygame.key.get_pressed() if keys[pygame.K_LEFT]: player_pos[0] - player_speed * dt if keys[pygame.K_RIGHT]: player_pos[0] player_speed * dt if keys[pygame.K_UP]: player_pos[1] - player_speed * dt if keys[pygame.K_DOWN]: player_pos[1] player_speed * dt # 绘制 screen.fill((30, 30, 30)) pygame.draw.rect(screen, (0, 200, 0), (player_pos[0], player_pos[1], 20, 20)) pygame.display.flip() pygame.quit() sys.exit()说实话这个骨架的完成度让我有点意外用了delta time来控制帧率无关的移动速度这一点很多新手教程都未必会第一时间强调。这也侧面说明AI从优秀范例里学到了不少好习惯而不是只会堆砌API调用。但骨架能用不代表后面每一步都顺利。我得提醒一句AI生成的代码你要能读懂至少要知道主循环里发生了什么。如果完全没有读代码的能力后面出bug时你会彻底抓瞎。2.3 首轮运行就翻车快速定位代码问题的思路第一版能跑起来但跑起来之后问题一个接一个。我遇到的最典型的报错之一是变量名引用不一致AI定义了一个player_rect后面绘制时却用了player_rects单复数差一个字母直接报AttributeError。遇到这种问题我的处理策略很粗暴先把完整报错信息原样贴回给AI让它自己看。大模型对“头尾呼应”这件事比人敏感它很快就能发现自己哪里变量名写岔了。但有一种情况必须自己动手查代码本身不报错但行为不符合预期。比如角色移动方向反了、碰撞判定范围明显偏大这类问题AI往往找不到原因因为它的“思维”里代码逻辑是自洽的。这种时候你得学会自己打印变量、自己加日志来观察中间状态别指望AI替你感受“手感不对”。3. 让AI角色“活”起来巡逻、警觉、追击的状态机实现3.1 游戏AI为什么普遍用状态机而不是机器学习这是整个实践里我最想让读者弄明白的一点。很多人受“AI”这个词影响觉得游戏里的智能角色应该靠机器学习来实现实际上主流游戏AI恰恰是反过来的。状态机的核心思想很简单把角色的行为划分成几个互斥的状态然后定义“什么条件触发什么迁移”。比如我的敌人只有三个状态巡逻、警觉、追击外加一张迁移表当前状态触发条件迁移到巡逻距离 200 且 在视野角度内追击追击距离 320 或 被闪光弹命中巡逻追击碰到玩家游戏结束为什么不用神经网络因为游戏AI的第一要求是可预测和可调试。玩家的体验建立在“这个敌人的行为大体有规律可循”之上一个用深度模型训练出来的敌人你没法预判它何时抽风也没法在测试时快速定位“它为什么突然冲向墙壁”。状态机的每个决策都有明确理由对开发者和玩家都透明这才是游戏里智能角色的正解。3.2 视野判定与状态迁移的核心代码我给敌人做视野的逻辑并不复杂核心是两点距离判断加角度判断。class Enemy: def __init__(self, x, y, patrol_points): self.pos pygame.Vector2(x, y) self.patrol_points patrol_points self.state PATROL self.speed 120 self.vision_radius 220 self.vision_half_angle 35 # 视野半角即左右各35度 def update(self, player_pos, dt): to_player pygame.Vector2(player_pos) - self.pos dist to_player.length() # 距离过远直接不判断省计算 if dist self.vision_radius: return # 计算朝向与玩家方向的夹角 forward self.get_forward() if forward.dot(to_player.normalize()) 0.5: self.state CHASE else: self.state PATROL角度判断用的是向量点积两个向量方向越接近点积越接近1。我用0.5作为阈值对应大概60度的夹角范围也就是左右各30度。倒不是90度不行而是试了几组参数后发现狭窄一点更有“偷偷绕后”的爽快感。这段代码基本是我和AI一起打磨出来的我先给出状态机和判断思路AI负责把具体实现补全。这正是我认为比较舒服的协作模式——你出知识框架AI出代码细节。3.3 调参才是“像不像人”的关键代码能跑只是第一步AI角色“像不像人”的决定性工作在调参。这是我这次实践最大的体会。几个我印象很深的参数调整第一是追击速度。一开始敌人和玩家移动速度完全一样导致永远追不上玩家甚至可以站在原地看它原地跑步。后来我把敌人速度调成玩家的1.1倍紧张感立刻就出来了。这个差值的把握只有上手玩过才知道AI给不了你答案。第二是巡逻路径的随机性。让敌人按固定折返点走十秒之后玩家就摸清楚规律了毫无压迫感。我给巡逻点加了一个随机偏移量每隔几秒重新随机一次机械感少了很多。第三是状态切换的迟滞。刚实现视野时敌人在视野边缘疯狂横跳进入视野变成追击退出视野变回巡逻再进入又追击看起来像个抽搐的机器人。后来我在追击状态下把“失去目标”的判定距离加到了比“发现目标”更远的320用这种不对称的阈值消除抖动。这在控制理论里叫迟滞在游戏AI里是常见的手感细节。提示这类经验参数AI永远不可能替你一次到位。它没法“玩”你的游戏所以它读不懂“手感不对”是什么意思。调参这个环节必须自己坐上来玩、听反馈、改数字。4. 实测阶段三个隐蔽bug和一次性能优化4.1 三个不跑起来根本发现不了的bug第一个是敌人互相重叠。多个敌人同时追击玩家时他们会挤在同一个坐标上看起来像合体了一样。原因是AI生成的角色移动逻辑里没有“角色之间也要碰撞”的概念。解决方法是给每个敌人加一个简单的分离力相邻敌人距离过近时各自往相反方向推开一点。这个在AI生成的基础上改不算难但如果你没玩过这类游戏根本不会想到要加这个逻辑。第二个是追击穿墙。我的地图加入了墙壁玩家会绕着墙柱躲敌人但敌人在“视野内看到你”之后会无视墙壁直直冲过来穿模。这暴露了状态机的盲区视野判定只计算了距离和角度没有计算视线遮挡。简单的修复是加一条线段与矩形相交的检测看玩家和敌人之间有没有墙有墙就不触发追击。这个坑特别典型因为它属于“需求描述时你没想到AI自然也不会主动考虑”的盲区。第三个bug有点讽刺是AI生成代码里对帧率的处理不一致。敌人移动用了delta time但巡逻点之间的插值却按帧算的导致同一台机器上60帧和144帧下敌人巡逻速度完全不一样。排查方法是我把帧率锁定到30测试了一遍发现敌人动作明显变慢才意识到是帧率依赖问题。AI生成代码时经常“局部正确、全局不一致”这种问题只能靠人通读代码去发现。4.2 一屏塞下100个AI角色的性能测试功能稳定后我好奇地把AI敌人数量往上拉做了个粗暴的压力测试。结果很直观敌人数量帧率表现感受5个稳定60FPS流畅30个稳定60FPS流畅50个40到50FPS能感知到卡顿100个20FPS左右明显幻灯片瓶颈不难猜每个敌人每帧都要算距离、点积、状态迁移再加上角色之间的两两碰撞检测复杂度直接往(O(n^2))走了。我的优化就两步。第一步是预筛先用便宜到几乎不耗时的平方距离判断把“远到不可能发生交互”的敌人筛掉再做昂贵的角度计算。第二步是降低AI决策频率敌人不需要每帧都做完整状态判断改成每10帧思考一次人类肉眼完全察觉不到区别但CPU占用立刻降了一大截。优化之后50个敌人稳回60FPS100个也从幻灯片变成了勉强能玩。这个优化思路是通用的AI系统里90%的敌人在90%的时间里根本不需要精细决策把计算留给真正需要反应的那个瞬间就行。4.3 让AI继续改需求的真实体验游戏能玩之后我尝试让AI继续迭代了几个功能体验差别很大。加“玩家按J发射子弹”这件事AI完成度很高。因为它本质上是“生成一个对象、沿直线移动、检测碰撞、销毁”的纯逻辑代码模式非常成熟AI直接给了一套能跑的实现。加“血条和得分UI”就差了很多。AI生成的UI代码要么坐标错乱要么渲染层级不对改了好几轮才勉强能看。这类问题的难点在于全局状态管理——血条要同时知道玩家状态、敌人状态、当前回合状态而AI并没有一个统筹全局的“项目视图”它只能基于你给的局部信息打补丁。加音效更是直接暴露短板API用法它门儿清但音频素材它变不出来你仍然要自己去找或者自己生成。AI能帮你写播放音频的代码但帮不了你决定用什么音效。5. 浅尝之后我看到的AI游戏开发现状与下一步5.1 AI写代码这件事的边界在哪一次完整的“浅尝”下来我对AI辅助开发有了更具体的判断。AI最擅长的是把成熟模式快速落地。游戏循环、碰撞检测、状态机、粒子效果这些都是社区里写了无数遍的代码范式大模型见过的样本足够多生成质量自然高。它就像一个移动速度很快但不太认路的新同事你给它清晰指令它执行得又快又好但如果你自己也说不清要去哪它会把你在原地打转的姿势也优化得很流畅。最明显的边界在于AI缺乏对“整体体验”的把握。它不会知道敌人穿墙会让玩家觉得不公平不会知道数字闪跳一点比卡顿更影响手感更不会感受到“这个游戏好不好玩”。这些反馈只能来自真实玩家的游玩体验而把体验翻译成修改需求、再翻译成代码逻辑这个翻译者的角色目前还是只能由人来做。5.2 想继续深入的话建议补这些底子这次实践之后我整理了三条继续深入的方向给同样想入门的读者作参考。第一条是补习数据结构与算法基础。AI帮你写代码时你得有能力判断它写的碰撞检测是不是真的高效、状态查询是不是合理。我这次优化过程中用到的空间预筛、降低决策频率这些手段背后都是最基础的数据结构思路没有这些底子你连“优化哪里”都找不到。第二条是学习游戏AI的经典方法论。状态机只是最入门的一种往上还有行为树、GOAP目标导向规划、群集行为、蒙特卡洛树搜索等。如果你想让游戏AI再“聪明”一点这些才是绕不开的正路而不是去学什么神经网络控制角色。第三条是锻炼把需求拆小的能力。这次经验证明AI协作的核心瓶颈不是AI而是我对需求的拆解能力。一个模糊的“做个好玩的敌人AI”会让AI束手无策但把它拆成“巡逻点、视野角度、追击速度、失去目标距离、脱战休息”之后AI能非常高效地逐项实现。这种拆解能力也是以后带团队、写技术方案都通用的核心能力。最后再说点私人的感触。这次“浅尝”最开心的时刻不是游戏第一次跑起来而是我把敌人追得满地图跑、然后丢了一颗闪光弹趁它“失明”绕到背后那几秒钟。一个方块、几条线段组成的粗糙画面因为行为逻辑对了突然就有了“刺激感”。我开始理解为什么做游戏这么让人上瘾——写代码只是手段创造出一小段可以被体验的“过程”才是这件事真正的乐趣所在。如果你也想试听我一句劝别贪大让自己玩的第一个游戏小到“一晚上能跑起来”剩下的乐趣会在迭代里自己长出来。