ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

游戏引擎都没用!纯AI又上线了一款蚂蚁搬家小游戏

游戏引擎都没用!纯AI又上线了一款蚂蚁搬家小游戏 1. 从“游戏引擎都没用”说起这个蚂蚁搬家项目到底在做什么第一次看到“游戏引擎都没用纯AI又上线了一款蚂蚁搬家小游戏”这个标题我脑子里蹦出来的第一个念头是又是一个标题党。毕竟做小游戏的人都知道微信小游戏生态里用Unity、Cocos、Laya这些引擎才是主流纯手写Canvas做商业级小游戏听起来像是回到2012年。但仔细看完这个项目的实现路径之后我发现它其实踩中了一个非常有意思的交叉点AI辅助编码 微信小游戏原生Canvas渲染 零引擎依赖。先说清楚这个项目是什么。它是一个运行在微信小游戏环境里的“蚂蚁搬家”玩法小游戏——玩家控制蚂蚁把食物搬回巢穴途中要避开障碍、规划路线、积累分数。核心玩法不复杂属于典型的休闲益智品类。但它的特殊之处在于整个项目没有引入任何游戏引擎没有Unity没有Cocos Creator没有LayaAir甚至连轻量级的Egret都没用。渲染层完全基于微信小游戏提供的Canvas 2D接口手写逻辑层用原生JavaScript组织开发过程中大量借助AI编码工具比如Codex这类代码生成助手来加速从零到一的搭建。这就引出一个很实际的问题为什么有人会选择“不用引擎”这条路我自己的判断是三个原因叠加。第一包体和启动速度。微信小游戏对首包体积有硬性限制主包不能超过4MB用Unity打包出来的小游戏即便做了裁剪首包也很容易逼近这个红线而纯Canvas项目的代码量可以控制在几百KB级别冷启动速度肉眼可见地快。第二AI编码工具对纯JS/Canvas项目的支持度远高于引擎项目。你让AI帮你写一个Canvas绘制循环、碰撞检测、精灵动画它给出的代码质量相当高但你让AI帮你写Unity的C#组件挂载逻辑它经常会在API版本和生命周期上出错。第三学习门槛和可控性。引擎有自己的一套抽象层出问题时排查链路长纯Canvas项目所有东西都在你眼皮底下哪里画错了、哪里帧率掉了打开微信开发者工具的Performance面板一看便知。这个项目适合谁来参考我认为三类人最值得看。一是想入门微信小游戏但被引擎劝退的前端开发者你有JavaScript和Canvas基础完全可以跳过引擎直接上手二是想用AI工具提升开发效率的独立开发者这个项目展示了AI在哪些环节真正能帮上忙、哪些环节必须自己兜底三是做轻量级休闲游戏的产品同学理解技术边界之后你在定需求时会更清楚什么能做、什么做不了。接下来我会把这个项目拆成几个层面来讲整体设计思路、Canvas渲染的核心细节、AI编码工具的实际使用方式、以及我在类似项目里踩过的坑和排查经验。不是教程是一个从业者做完之后的复盘。2. 整体设计与技术选型为什么敢不用引擎2.1 微信小游戏的技术底座到底给了什么要理解“不用引擎”这件事的可行性得先搞清楚微信小游戏平台本身提供了什么。微信小游戏运行在微信客户端内置的JavaScript引擎里它暴露了一套全局对象wx其中和渲染相关的是wx.createCanvas()。这个接口返回一个Canvas对象你可以拿到它的2D上下文然后就像在浏览器里一样调用ctx.drawImage、ctx.fillRect、ctx.arc这些标准Canvas 2D API。关键区别在于浏览器里的Canvas是DOM元素微信小游戏里的Canvas是平台托管的渲染表面。你不需要关心它怎么合成到屏幕上微信底层会处理。这意味着你只要有Canvas 2D的绘图能力就能完成所有2D游戏的渲染。蚂蚁搬家这种游戏所有视觉元素无非就是圆形蚂蚁身体、矩形食物块、线条路径Canvas 2D完全覆盖。再往上微信小游戏还提供了wx.createImage()来加载图片资源、wx.createInnerAudioContext()来播放音效、wx.onTouchStart等触摸事件接口。这些加起来构成了一套“刚好够用”的游戏开发基础设施。你缺的不是能力而是引擎帮你封装好的那些便利层——场景管理、精灵系统、物理引擎、动画状态机。但对于蚂蚁搬家这种量级的游戏这些便利层带来的收益可能还抵不上引入引擎带来的包体膨胀和调试复杂度。2.2 引擎方案和纯Canvas方案的取舍账我拿一个具体的对比表来说明这个决策过程。以下数据基于我实际参与过的几个微信小游戏项目数值是量级参考不是精确值。对比维度Unity WebGL方案Cocos Creator方案纯Canvas方案首包体积3.5MB~4.5MB1.5MB~2.5MB200KB~500KB冷启动时间中端机3~5秒1.5~3秒0.5~1.2秒开发语言C# 引擎APITypeScript 引擎APIJavaScript Canvas APIAI编码工具支持度低API版本敏感中有模板依赖高纯逻辑代码热更新灵活性受限于引擎机制较灵活完全自主控制复杂物理需求强中需手写团队协作门槛高中低前端即可从这张表能看出来纯Canvas方案的优势集中在体积、启动速度、AI工具友好度这三个维度。而它的劣势也很明显复杂物理、粒子特效、3D渲染这些需求手写成本极高。蚂蚁搬家这个项目的聪明之处在于它的玩法天然避开了这些劣势——没有物理碰撞的复杂模拟没有粒子系统没有3D。所有交互都是2D平面上的位置判断和状态切换。这里有一个选型原则值得记住引擎解决的是“复杂度的规模化问题”如果你的游戏复杂度没有达到需要规模化管理的地步引擎反而是负担。判断标准很简单——如果你的游戏核心逻辑用一张A4纸就能画完状态流转图那就不需要引擎。2.3 AI编码工具在这个项目里的真实角色标题里说“纯AI又上线了一款”这个“纯AI”需要拆开理解。它不是说游戏本身是AI在玩而是说开发过程大量依赖AI编码工具。具体来说Codex这类工具在这个项目里承担了以下几类工作第一类是样板代码生成。比如Canvas的初始化、游戏主循环的requestAnimationFrame封装、触摸事件的坐标转换这些代码有固定模式AI生成的质量很高基本一次成型。第二类是算法逻辑辅助。蚂蚁搬家涉及路径规划蚂蚁怎么绕开障碍走到食物、碰撞检测蚂蚁和障碍物的矩形/圆形相交判断、分数计算逻辑。这些算法AI能给出可用的实现但需要你理解之后做适配调整。第三类是调试辅助。遇到Canvas绘制错位、触摸坐标偏移、帧率抖动这些问题时把现象描述给AI它能给出排查方向。但注意AI给的排查方向经常是“通用可能性列表”真正定位到具体问题还是得靠你自己在微信开发者工具里打断点、看日志。第四类是代码重构建议。当项目文件变多、函数变长之后让AI帮你拆分模块、提取公共函数效率比手动重构高不少。但有几类工作AI帮不上忙或者说帮倒忙微信小游戏平台特有的API调用比如wx.createCanvas的返回值处理、wx.onTouchMove的事件对象结构AI经常混淆浏览器和小程序的差异性能优化AI给出的优化建议往往是泛泛而谈真正有效的优化必须基于微信开发者工具的性能面板数据游戏手感调优蚂蚁移动速度、动画帧间隔、触摸响应阈值这些参数只能靠人反复试。3. Canvas渲染核心细节从零搭建一个2D渲染循环3.1 初始化Canvas和适配屏幕微信小游戏里创建Canvas的方式和浏览器不同。浏览器里你写canvas idgame然后document.getElementById拿引用微信小游戏里你得调用wx.createCanvas()而且第一次调用返回的是上屏Canvas后续调用返回的是离屏Canvas。这个细节很关键搞错了就会出现“画了半天屏幕上什么都没有”的情况。// 获取上屏Canvas const canvas wx.createCanvas(); const ctx canvas.getContext(2d); // 获取屏幕尺寸信息 const systemInfo wx.getSystemInfoSync(); const screenWidth systemInfo.screenWidth; const screenHeight systemInfo.screenHeight; const pixelRatio systemInfo.pixelRatio; // 设置Canvas逻辑尺寸 canvas.width screenWidth * pixelRatio; canvas.height screenHeight * pixelRatio; // 缩放上下文让后续绘图按逻辑像素进行 ctx.scale(pixelRatio, pixelRatio);这段代码里有个容易踩的坑pixelRatio的处理。不同手机的物理像素和逻辑像素比例不同iPhone通常是2或3部分安卓机是1.5或2.75。如果你不处理这个比例在高分屏上画出来的东西会模糊或者尺寸不对。处理方式就是上面这样——Canvas的实际像素尺寸设为逻辑尺寸乘以比例然后通过ctx.scale把绘图坐标系缩回逻辑尺寸。这样你后续所有绘图代码都用逻辑像素思考不用关心设备差异。实操心得wx.getSystemInfoSync()在新版基础库里有同步和异步两个版本同步版本在冷启动阶段调用可能返回不完整信息。稳妥做法是在wx.onShow之后再读一次或者用wx.getWindowInfo()替代。我遇到过在部分安卓机型上冷启动时screenWidth返回0的情况加一个兜底默认值能避免白屏。3.2 游戏主循环的设计与帧率控制Canvas游戏的心脏是主循环。浏览器里通常用requestAnimationFrame微信小游戏也支持这个全局函数。但直接裸用会有问题不同设备的刷新率不同60Hz、90Hz、120Hz都有如果你的游戏逻辑和渲染都绑在requestAnimationFrame上高刷设备上游戏速度会变快。解决方案是固定时间步长的逻辑更新加可变步长的渲染。简单说就是逻辑更新按固定间隔比如每秒60次即16.67ms一次执行渲染每次requestAnimationFrame都执行但渲染用的数据来自最近一次逻辑更新的结果。const FIXED_DT 1000 / 60; // 固定逻辑步长单位毫秒 let lastTime 0; let accumulator 0; function gameLoop(currentTime) { if (lastTime 0) { lastTime currentTime; requestAnimationFrame(gameLoop); return; } let deltaTime currentTime - lastTime; lastTime currentTime; // 防止切后台回来后的巨大deltaTime导致逻辑爆炸 if (deltaTime 250) deltaTime FIXED_DT; accumulator deltaTime; // 固定步长更新逻辑 while (accumulator FIXED_DT) { updateGame(FIXED_DT); accumulator - FIXED_DT; } // 渲染 renderGame(ctx); requestAnimationFrame(gameLoop); }这个模式的好处是无论设备刷新率是多少蚂蚁的移动速度、动画播放速度都是一致的。accumulator机制保证了逻辑更新的总次数和真实时间成正比。那个deltaTime 250的判断是处理切后台场景——用户把微信切到后台几分钟再回来currentTime的跳变会非常大如果不做限制while循环会执行几千次直接卡死。3.3 蚂蚁和食物的绘制从圆形到精灵图蚂蚁搬家的视觉元素不复杂但要做到“看起来舒服”需要一些细节处理。最基础的蚂蚁可以用圆形加线条画出来function drawAnt(ctx, ant) { const { x, y, angle, scale } ant; ctx.save(); ctx.translate(x, y); ctx.rotate(angle); ctx.scale(scale, scale); // 身体三个椭圆 ctx.fillStyle #2d1b0e; ctx.beginPath(); ctx.ellipse(0, 0, 8, 6, 0, 0, Math.PI * 2); ctx.fill(); ctx.beginPath(); ctx.ellipse(-10, 0, 6, 5, 0, 0, Math.PI * 2); ctx.fill(); ctx.beginPath(); ctx.ellipse(10, 0, 5, 4, 0, 0, Math.PI * 2); ctx.fill(); // 触角 ctx.strokeStyle #2d1b0e; ctx.lineWidth 1.5; ctx.beginPath(); ctx.moveTo(13, -2); ctx.quadraticCurveTo(20, -10, 25, -8); ctx.stroke(); ctx.beginPath(); ctx.moveTo(13, 2); ctx.quadraticCurveTo(20, 10, 25, 8); ctx.stroke(); ctx.restore(); }但纯几何绘制在性能上有个隐患每帧重新构建路径的开销。如果屏幕上有几十只蚂蚁每只都这样画beginPath和ellipse的调用次数会很多。优化方案是预渲染到离屏Canvas把一只蚂蚁画好之后存成图片后续用drawImage直接贴。// 预渲染蚂蚁精灵 function createAntSprite() { const offscreen wx.createCanvas(); offscreen.width 64; offscreen.height 64; const octx offscreen.getContext(2d); // 在离屏Canvas上绘制蚂蚁坐标居中 octx.translate(32, 32); // ... 绘制代码同上 return offscreen; } // 使用时 const antSprite createAntSprite(); ctx.drawImage(antSprite, x - 32, y - 32);这个优化在蚂蚁数量超过20只时效果明显帧率能从40fps左右回到稳定60fps。代价是蚂蚁的旋转角度需要额外处理——drawImage不支持旋转你得用ctx.save/translate/rotate/drawImage/restore这一套。但即便如此也比每帧重新画路径快。注意事项wx.createCanvas()创建的离屏Canvas在部分低端安卓机上有数量限制一般不超过10个。如果你给每种蚂蚁、每种食物都创建一个离屏Canvas很容易超限导致创建失败。稳妥做法是用一个精灵图集把所有元素画在一张大离屏Canvas上通过drawImage的裁剪参数来取用。3.4 触摸交互与坐标转换蚂蚁搬家的操作方式是触摸拖动——玩家按住蚂蚁拖到食物上或者点击食物让蚂蚁过去搬。触摸事件的处理有一个经典坑事件坐标和Canvas坐标的映射。微信小游戏的触摸事件对象里touch.clientX和touch.clientY是相对于屏幕的坐标单位是逻辑像素。如果你的Canvas逻辑尺寸和屏幕逻辑尺寸一致上面初始化时就是这么做的那直接使用即可。但如果你做了缩放或者偏移就需要转换。wx.onTouchStart((e) { const touch e.touches[0]; const x touch.clientX; const y touch.clientY; // 判断是否点中了某只蚂蚁 for (let ant of ants) { const dx x - ant.x; const dy y - ant.y; if (dx * dx dy * dy 30 * 30) { // 30像素命中半径 ant.isDragging true; ant.dragOffsetX dx; ant.dragOffsetY dy; break; } } });命中检测用平方距离比较而不是开方省一次Math.sqrt调用。在触摸移动事件里更新蚂蚁位置时记得减去dragOffset否则蚂蚁会“跳”到手指正下方手感很怪。还有一个细节微信小游戏的触摸事件默认会冒泡如果你在页面上还有其他交互元素可能需要e.preventDefault()。但小游戏环境里通常不需要因为整个屏幕都是你的Canvas。4. AI编码工具实操哪些环节真能提效哪些是坑4.1 用Codex生成游戏骨架的完整流程我拿这个蚂蚁搬家项目里“从零搭建游戏骨架”这个环节来举例展示AI编码工具的实际使用方式。假设你打开Codex的对话界面输入这样一段提示用JavaScript写一个微信小游戏的骨架代码要求 1. 使用wx.createCanvas创建上屏Canvas 2. 处理pixelRatio适配 3. 实现固定时间步长的游戏主循环 4. 包含update和render两个空函数供后续填充 5. 处理切后台回来的deltaTime跳变Codex给出的代码基本就是上面3.1和3.2两段代码的合并版质量可用。但有几个地方需要你手动修正它可能会用wx.getSystemInfoSync()而不是更新的wx.getWindowInfo()它可能忘记处理requestAnimationFrame在微信小游戏里的兼容性部分旧版本基础库需要polyfill它给出的ctx.scale调用位置可能不对。我的做法是把AI生成的代码当作“第一稿”然后逐行审查对照微信官方文档确认每个API的用法。这个过程大概花10分钟比完全手写省一半时间但比直接复制粘贴多花5分钟。这5分钟是值得的因为AI对微信小游戏API的“幻觉”率不低。4.2 AI辅助算法实现的边界在哪里蚂蚁搬家涉及几个算法点蚂蚁的移动路径计算、食物生成的位置随机化、碰撞检测。我分别说一下AI的表现。移动路径计算如果只是“从A点直线移动到B点”AI写得很好。但如果要“绕开障碍物”AI会给出A算法的实现。A本身没问题但AI生成的A代码通常没有做网格化处理——它假设你有一个现成的网格地图。而蚂蚁搬家的障碍物是任意形状的你需要先把连续空间离散化成网格这个预处理步骤AI经常忽略。我的做法是让AI先写A然后自己补上网格化逻辑。食物生成随机化这个简单AI一次成型。但要注意它可能生成的食物位置和障碍物重叠需要加一个“重新生成直到不重叠”的循环并设置最大重试次数防止死循环。碰撞检测圆形和圆形的碰撞AI写得没问题圆形和矩形的碰撞它有时会搞混边界条件。我建议自己写一遍或者用成熟的分离轴定理SAT简化版。实操心得AI编码工具最擅长的领域是有大量公开代码样本的通用问题排序、查找、基础数据结构操作最不擅长的是平台特定API 业务逻辑耦合的场景。判断标准很简单——如果你在GitHub上能搜到100个类似实现AI大概率能写好如果搜不到AI大概率会编。4.3 调试环节AI能帮什么忙调试是AI工具价值被低估的环节。举一个我实际遇到的例子蚂蚁拖动时手指离开屏幕后蚂蚁会“飞”回原位而不是停在拖动位置。我把现象描述给AI它给出的排查方向包括触摸结束事件没有正确清除isDragging标志、蚂蚁位置更新逻辑在touchend之后仍然执行、渲染层使用了旧的位置数据。顺着这三个方向查发现是touchend事件里只清了isDragging但没有把蚂蚁的targetX/targetY更新为当前位置导致下一帧的逻辑更新把蚂蚁拉回了旧目标点。这个问题如果自己排查可能要打十几个断点AI给了方向之后五分钟定位。但AI的排查建议也有误导的时候。另一次遇到帧率突然从60掉到30AI建议检查“是否有内存泄漏”“是否每帧创建了新对象”。查了半天没发现问题最后用微信开发者工具的Performance面板一看是某张图片的尺寸是2048x2048每帧drawImage缩放绘制导致的GPU开销。AI没有考虑到微信小游戏在移动端GPU上的纹理尺寸限制。5. 常见问题与排查技巧实录5.1 白屏问题的五种可能原因白屏是微信小游戏开发里最高频的问题没有之一。我整理了一个排查顺序表按概率从高到低排列排查顺序可能原因验证方式解决方案1Canvas未正确创建在wx.createCanvas()后打印返回值确保第一次调用返回上屏Canvas2绘制代码未执行在render函数首行加console.log检查主循环是否启动3绘制坐标超出屏幕打印绘制坐标和Canvas尺寸检查pixelRatio适配逻辑4颜色与背景同色临时改绘制颜色为红色检查fillStyle设置5资源加载未完成检查图片onload回调加加载状态管理实际排查时我习惯先在renderGame函数第一行加一个console.log(render called)如果控制台没有输出说明主循环没跑起来如果有输出但屏幕还是白的说明绘制逻辑有问题。这个二分法能快速缩小范围。5.2 触摸事件不响应的排查路径触摸事件不响应通常有三个原因。第一是事件绑定时机——wx.onTouchStart必须在Canvas创建之后调用如果在wx.createCanvas之前绑定部分基础库版本会丢失事件。第二是层级遮挡——如果你在Canvas之上还创建了其他原生组件比如wx.createVideo它会拦截触摸事件。第三是坐标判断逻辑错误——触摸事件触发了但你的命中检测没通过。排查方法在wx.onTouchStart回调里第一行加console.log(e.touches[0].clientX, e.touches[0].clientY)确认事件是否触发、坐标是否合理。如果坐标是0或者负数说明坐标转换有问题如果坐标正常但游戏没反应说明命中检测逻辑需要调整。5.3 帧率波动的优化清单帧率波动在纯Canvas项目里比引擎项目更常见因为所有优化都得自己做。我按优先级列一个优化清单减少每帧的路径构建能用drawImage就不用beginPathfill。预渲染精灵是首选方案。控制离屏Canvas数量不超过5个超了就合并成精灵图集。避免每帧创建对象{x: 1, y: 2}这种字面量在循环里创建会触发GC用对象池复用。降低绘制分辨率如果游戏画面不需要Retina级别的清晰度把pixelRatio上限设为2能显著降低GPU填充率压力。批量绘制同类型元素所有食物用同一个fillStyle时可以合并路径一次性绘制减少状态切换。实测数据在一个有50个食物、10只蚂蚁的场景里优化前帧率在35~45fps波动做了精灵预渲染和对象池之后稳定在58~60fps。低端安卓机骁龙660级别也能跑到50fps以上。5.4 AI工具使用中的典型故障Codex这类工具在使用过程中会遇到一些环境问题。比如“无法加载组织设置”通常是网络配置或账号权限问题检查登录状态和网络连接即可。“模型不支持”的报错一般出现在工具版本和模型版本不匹配时更新到最新版通常能解决。安装过程中如果卡在“Windows设置未完成”检查系统权限和杀毒软件拦截。这些问题的共同特点是它们和你的代码无关是工具链本身的问题。遇到时不要怀疑自己的代码先确认工具环境是否正常。我的习惯是维护一个“工具环境检查清单”每次开始新项目前过一遍能省掉很多无效排查时间。6. 这个项目后续还能怎么扩展蚂蚁搬家这个玩法本身有扩展空间。从技术角度可以加入多蚂蚁协同——玩家控制多只蚂蚁需要设计简单的AI让它们自动寻路这会把A*算法的使用频率拉高也是检验纯Canvas方案能否撑住更多实体渲染的好场景。从玩法角度可以加入食物类型区分——不同食物重量不同蚂蚁搬运速度不同这需要引入简单的物理模拟速度和质量的关系但仍然是2D平面内的计算Canvas完全能处理。从工程角度这个项目最有价值的扩展方向是把AI编码工具的使用流程标准化。比如建立一个提示词模板库针对“生成游戏主循环”“生成碰撞检测”“生成触摸交互”这些高频任务每个任务有固定的提示词结构和验证清单。这样下次做类似项目时从零到可玩demo的时间能压缩到半天以内。我自己在类似项目里的体会是纯Canvas方案的上限比大多数人想象的高但它的下限也比引擎方案低——引擎帮你兜住的那些底你得自己兜。AI工具能帮你快速达到“能跑”的状态但从“能跑”到“跑得稳、跑得久”还是得靠对平台特性的理解和反复的实测调优。蚂蚁搬家这个项目最值得参考的地方不是它用了AI而是它在“不用引擎”这个约束下把该做的细节都做到了位。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进