ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

不用游戏引擎,纯AI用原生JavaScript开发蚂蚁搬家小游戏的完整实践

不用游戏引擎,纯AI用原生JavaScript开发蚂蚁搬家小游戏的完整实践 游戏引擎都没用纯AI又上线了一款蚂蚁搬家小游戏这句话是我在一个技术交流群里发出来的当时群友的第一反应基本都是你又来吹牛了之前用纯AI做过拼图和打地鼠这次又要用AI直接干出一个能玩的蚂蚁搬家小游戏。但事实是整个项目从第一句提示词开始到手机浏览器里能玩、能计分、还有音效全程确实没有打开过Unity、Godot这类游戏引擎也没有下载任何素材。这篇文章就把这次的完整过程拆开来讲为什么放着游戏引擎不用、纯AI到底怎么把游戏代码写出来的、中途踩了哪些没引擎才会碰到的坑以及最后怎么把一个单文件HTML变成能上线的产品。如果你也想用AI快速做点小游戏或者单纯好奇程序生成游戏这条路能走到哪一步这篇应该能给你一些参考。1. 为什么我把游戏引擎踢出了这次项目1.1 先看游戏的真实体量一碗蚂蚁搬家根本不需要精装房游戏引擎当然是好东西但这次要做的蚂蚁搬家是一个单屏、单角色、只有十来个交互对象的休闲小游戏。它需要的物理规则也就是撞到食物就背上碰到蚁巢就放下这种级别的判断连刚体、重力、碰撞体这类引擎核心概念都用不上。我用原生Canvas加JavaScript实现整个逻辑就是三个循环接收输入、更新状态、画帧。游戏对象只有蚂蚁、食物、蚁巢、障碍物和一只巡逻的蜘蛛。这种情况下用Unity会是什么效果新建项目、导入工程、配置场景、写脚本、打包WebGL光是流程走下来一个下午就没了产物还有几MB到几十MB的加载体积。我当时列过一个简单的对比用原生Canvas、Unity WebGL和Phaser这类轻量框架放在一起看对比项原生Canvas JSUnity WebGLPhaser加载体积单个HTML几十KB基包数MB起步框架本身几百KB移动端适配靠容器和viewpoint即可需要做屏幕适配方案需引入官方Scale Manager上手门槛会JavaScript就能读需要理解场景、预制体等要学会框架的API体系AI直接生成友好度极高模型见得太多了中低容易混淆引擎概念中等偶尔生成多余代码这不是说引擎不行而是说杀鸡不必用牛刀。我做的是H5页面就能承载的小东西目标是快速验证玩法、快速上线试水。一把合适的瑞士军刀比开一台挖掘机效率高得多。1.2 不用引擎的真正理由让AI能读懂全局很多人觉得游戏引擎都没用是一种噱头但其实背后有个很实际的考虑我要让AI帮我写代码那就得选一个AI最容易理解的实现路径。游戏引擎有自己的一套抽象体系场景树、组件、物理材质、动画状态机、序列化文件。你要让AI生成一段给场景里加一只蚂蚁的代码它得先理解你的工程结构、命名空间、资源引用的方式稍微给得不准确就报错。但原生JavaScript的网页游戏底层逻辑极其直白页面加载、创建Canvas、获取上下文、监听键盘、写更新函数、写渲染函数。这种结构的代码在大模型的训练数据里出现过无数次AI几乎不需要额外思考就能给你端出一份能直接跑的骨架。用一个生活化的例子来比喻游戏引擎是精装修好的样板房拎包入住体验很好但我想搭的只是自家后院的一个小凉棚。让AI直接给我写怎么立柱子、怎么搭顶棚它很清楚让它在一个复杂的智能家居系统里去找哪个模块管凉棚反而容易绕晕。所以游戏引擎都没用背后其实是一句话体量越小越要把技术栈选得简单直接简单到AI能一眼看穿全局。2. 从蚂蚁搬家到AI能听懂的规则说明书2.1 把玩法拆成三句人话开始写提示词之前我先把蚂蚁搬家这个游戏在纸上拆成了三条核心规则玩家通过键盘或者屏幕按键控制一只蚂蚁在场景里移动。地图上随机分布10颗果子蚂蚁碰到果子就把它背在身上。蚂蚁把果子带回蚁巢后果子放下得分加1。就这三条。什么剧情、什么皮肤、什么多关卡在开工阶段统统不做先把最小可玩版本跑起来再说。但这三条规则还不够严密。AI非常老实你如果不把边界条件讲清楚它就会写出一堆你不想看到的逻辑。所以我又补了几个限定条件蚂蚁一次只能背一颗果子背的时候不能再拾取其他果子。玩家移动蚂蚁而不是让蚂蚁自己寻路。因为这是一个受控游戏不是模拟蚂蚁生态。场景中间随机放两个水坑作为障碍蚂蚁碰到会进入晕头转向状态2秒内方向键反向。加入一只蜘蛛在场景里来回巡逻碰到蜘蛛则蚂蚁被传送回起点并扣1点体力。这些规则最终写进了第一版提示词里。我的原则是给AI的规则必须像给一个从没听过这个游戏的新同事讲需求少用术语多说什么情况发生什么结果。2.2 第一版提示词全文这个项目的第一条提示词我保留了原样可以给想复刻的朋友直接抄请用原生JavaScript写一个单文件HTML5游戏画布用Canvas。游戏内容为蚂蚁搬家玩家用WASD控制一只蚂蚁在一片灰绿色草地上移动草地上随机放置10颗橙色果子蚂蚁碰到果子就把果子背到背上带着果子碰到画面左下角的蚁巢后果子放下并得分加1。限制条件一次只能背一颗果子背果子时不能拾取下一颗。请使用简单的canvas图形绘制蚂蚁、果子、蚁巢不用图片资源。创建完整的单文件HTML包含基本样式和开始游戏按钮。这段提示词里包含了五个关键信息技术栈、玩法、操作方式、美术资源策略、交付格式。这是AI能直接开工的底线缺一个它就会开始自由发挥。你可能会觉得原生JavaScript这几个字没什么稀罕的但它非常重要。如果你只说做一个蚂蚁搬家小游戏AI有可能会给你生成一个基于Python Pygame的项目那你还要配置Python环境、装依赖、处理窗口系统整个链路就复杂化了。明确单文件HTML5游戏后所有问题都收敛到了一个文件里运行门槛降到了零。2.3 用状态机代替一堆布尔变量第一版代码生成出来后我意识到蚂蚁的行为其实有三个阶段找食物、把食物运回巢、放下后再去找食物。如果只是用一个布尔变量是否在搬运来控制代码会越改越乱。比如找到食物但没走到跟前背起食物但还没到达巢穴放下食物后接下来干嘛这些都会分支爆炸。所以在第二次迭代时我让AI把蚂蚁的行为写成了状态机const ant { x: 140, y: 480, vx: 0, vy: 0, speed: 180, state: explore, // 状态explore 找食物, return 回巢 carrying: false, stunned: 0 }; function updateAnt(dt) { if (ant.stunned 0) { ant.stunned - dt; return; } if (ant.state explore) { let food findNearestFood(foods); if (food dist(ant, food) ant.r food.r) { ant.carrying true; food.taken true; ant.state return; } } else if (ant.state return) { moveTowards(ant, home); if (dist(ant, home) 24) { score; ant.carrying false; ant.state explore; spawnNewFood(); // 补一颗新果子维持场景里的资源总量 } } }这个状态机结构非常轻量但好处是显而易见的在explore状态里只关心找食物在return状态里只关心回巢规则之间不会互相污染。AI对于这种经典的状态机模式也特别擅长你只需要把伪代码大致说清楚它一般会实现得很干净。3. 纯AI迭代实录从第一行代码到能玩的小游戏3.1 第一次生成骨架能跑但画面很裸出发点是上面那版提示词。AI生成的第一个版本确实就是一个能跑的HTML文件——打开后看到一片灰绿色草地左下角一个深褐色的圆形蚁巢随机散落着一些橙色小圆点代表果子中央有一只用三个椭圆拼成的蚂蚁。键盘的WASD能控制它走到果子上果子消失再走回蚁巢顶部计分器加1。那一刻我其实挺感慨的因为这个骨架如果让我从零写也得花差不多一两个小时而AI大概用了四十秒。虽然画面很简陋但核心循环已经通了移动、拾取、搬运、交付、得分。当时我做的第一件事不是让它加功能而是把整个代码从头到尾读了一遍。原因很简单AI生成的代码如果第一步就有隐患后面所有迭代都会建立在一个坏地基上。值得庆幸的是这一版的逻辑写得还算直白没有明显的全局变量滥用或内存泄漏。3.2 一个需求一个需求地喂倒计时、水坑、蜘蛛我的迭代习惯是一次只加一个功能。这个教训来自于之前做打地鼠时我在同一轮提示词里要求AI加入分数、音效、锤子动画、倒计时四件事结果它给出的代码跑起来后出现了三个新问题排查难度直接翻倍。这次我严格按顺序来第一轮加一个30秒倒计时时间走完游戏结束并显示总分。第二轮加两个水坑进入水坑区域2秒内上下左右方向反转。第三轮加一只来回移动的蜘蛛碰到蜘蛛后蚂蚁被传送到起点。第四轮加屏幕上的虚拟方向键处理手机没有键盘的情况。每一轮改动之后都实际打开浏览器跑两分钟确认没问题再进入下一轮。AI写这种单点功能其实非常稳很少出错出错也往往是我在需求描述里留下了模糊空间。3.3 让AI自己画素材一只会抖腿的蚂蚁是怎么来的既然不用游戏引擎也就不存在美术管线。我的选择是让AI直接用Canvas画所有素材而且是足够辨识、但不需要精美的程度。蚂蚁的绘制是这样的身体由三个连续椭圆构成颜色用深棕色六条腿用细线绘制每帧根据一个正弦函数做轻微摆动背上有果子的时候在身体上方多画一个小橙圆。这听上去简单但在小屏幕上的辨识度反而很高因为形状和颜色都足够聚焦。蚁巢则用半圆弧加渐变填充外圈加上一些小颗粒模拟土堆质感水坑用半透明的蓝色圆形外圈加白边果子用高饱和橙色。整个过程没有一张外部图片全部是代码绘图。如果要调整美术风格我就告诉AI把果子的颜色改成高饱和红色增加一小片叶子轮廓它会立即在生成逻辑里对应修改。这种程序化美术对AI来说非常友好对人也非常友好——想改什么参数就改什么参数不用重新找素材。3.4 高分屏适配没有引擎之后要自己处理的事当你用原生Canvas又希望能适配手机浏览器时有一个细节特别容易忽视设备像素比。如果不处理在Retina屏幕上的Canvas画面会糊文字会发虚。这个适配逻辑很简短function setupCanvas() { const dpr window.devicePixelRatio || 1; // 逻辑坐标固定为 480x720 canvas.width 480 * dpr; canvas.height 720 * dpr; canvas.style.width 480px; canvas.style.height 720px; ctx.scale(dpr, dpr); }这样设置之后你的游戏内坐标始终按480乘以720的逻辑尺寸思考和计算画面实际渲染时用更高的物理像素清晰度就有保证了。在游戏引擎里这类屏幕适配通常被引擎的渲染管线自动处理了但用原生Canvas这就是你必须知道、并且要主动改的一行代码。4. 没有引擎之后调试反而更直接三个典型坑4.1 坑一蚂蚁原地转圈根因不在动画而是坐标轴状态当我把蜘蛛功能加上后发现了一件怪事蚂蚁在移动过程中偶尔会突然原地疯狂转向位置却没怎么变。最开始我怀疑是蜘蛛的碰撞逻辑改坏了蚂蚁速度然后怀疑是方向向量归一化出问题。查了两轮都没结果。后来我把所有和绘制无关的逻辑临时注释掉只留下每帧打印蚂蚁坐标发现坐标本身更新正常。再把绘制函数恢复问题重现。于是锁定范围在渲染层。问题出在AI为了让蚂蚁朝向移动方向在绘制时调用了ctx.rotate(angle)但是没有在旋转之前保存画布状态。之前画蚂蚁的代码只有一段后面的果子绘制在同一个上下文里坐标系统就一直在旋转导致蚂蚁视觉上原地转圈。修复方法也很简单ctx.save(); ctx.translate(ant.x, ant.y); ctx.rotate(angle); // 绘制蚂蚁本身 ctx.restore();这算是一个经典的原生Canvas状态栈问题。如果在游戏引擎里每个Game Object自带Transform你根本不会被这种问题绊住。但也正是因为没引擎我才能直接看到那一行rotate调用几秒钟就定位了问题。没有引擎有时候反而让代码的因果更透明。4.2 坑二手机打开一片空白键盘事件根本没人按下我最初是在电脑上测试的自然用的键盘WASD。第一次用手机扫码打开时画面出来了但完全无法移动。这当然不是AI的错误而是我的一个需求遗漏手机上没有键盘。解决方式是让AI生成一组屏幕上的虚拟方向键。四个半透明圆形按钮放在画面右下角。每个按钮在touchstart时设置对应的移动向量在touchend时清除。同时调用e.preventDefault()避免触发页面的默认滚动行为。顺带还要处理一个老问题移动端页面不缩放。在HTML的meta标签里必须明确meta nameviewport contentwidthdevice-width, initial-scale1.0, user-scalableno这个坑很典型——没有游戏引擎帮你抽象输入系统你就得自己补齐不同设备上的输入来源。但对AI来说这都是它见惯了的场景你只需要描述清楚手机需要虚拟方向键即可。4.3 坑三碰撞判定够得着和碰上了差了一大截另一个我在调试中注意到的现象蚂蚁有时候离果子还有一段距离就隔空取物了有时候又明明看起来撞上了却一直拾不起来。原因在于AI生成的碰撞判定喜欢用圆心距离小于某个半径之和但果子的视觉大小和碰撞半径没有对齐或者蚂蚁的视觉触角太长让玩家觉得我的手已经碰到了。解决思路分两步第一步把果子、蚂蚁、水坑和蜘蛛的碰撞半径统一放进各自的属性里视觉大小直接参照这个半径来画保证看起来碰上了就是逻辑上碰上了第二步在高速移动时把每帧位移拆成两次小步避免快速穿过障碍物。低速小游戏其实不用做什么复杂四叉树精确的圆形碰撞检测就够用了。我的观点是没有引擎时这些基础的游戏数学不能完全甩给AI你得知道它为什么这么写才能讲清楚让它怎么改。5. 不用引擎也有产品感音效、动效与上线流程5.1 用Web Audio合成音效一个音频文件都不存纯HTML小游戏如果要上线最怕的就是关联外部资源。所以我让AI直接用Web Audio API合成音效。效果其实超出预期尤其是那种短促的电子音非常契合小游戏的调性。比如拾取果子的音效就是一段频率从880Hz滑升到1320Hz的短振荡function playPickup() { const audioCtx new AudioContext(); const osc audioCtx.createOscillator(); const gain audioCtx.createGain(); osc.type sine; osc.frequency.setValueAtTime(880, audioCtx.currentTime); osc.frequency.exponentialRampToValueAtTime(1320, audioCtx.currentTime 0.08); gain.gain.setValueAtTime(0.1, audioCtx.currentTime); gain.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime 0.15); osc.connect(gain); gain.connect(audioCtx.destination); osc.start(); osc.stop(audioCtx.currentTime 0.15); }返回蚁巢放下果子的音效则用更低频、更短的下降音和水坑的晕眩音形成区分。这样做的好处是零外部文件零版权问题而且整个页面依然维持单文件结构。5.2 手感不是玄学反馈时机才是关键在我实际试玩时画面有了、音效也有了但总觉得手感不对。仔细感受之后发现问题出在反馈延迟上拾起果子的一瞬间画面没有任何变化要等蚂蚁走回蚁巢放下后才出现加分的数字玩家会误以为拾取失败了。于是我把反馈做得即时化。逻辑很简单当玩家碰到果子立刻执行三个动作——切换蚂蚁状态、播放拾取音效、在拾取位置生成一个向上漂浮并淡出的分数提示。这个飘分效果只要用很小的代码量就能实现维持一个浮点数数组每帧更新位置和透明度即可。反馈密度高玩家就会觉得游戏跟手。这也是没有引擎时的一个好处你不需要翻引擎的UI事件回调直接用Canvas原语绘制就完事了。5.3 发布上线还真就一个文件的事整个游戏开发完成后我把它压缩成一个单文件HTML所有样式、脚本、逻辑都在里面gzip之后体积只有三十多KB。发布流程也简单得让群友有点不敢相信传到任意静态托管服务或者直接放进一个支持静态页面的项目仓库就能通过链接访问。如果你想接特定平台的能力比如把游戏嵌入某个容器、需要接入侧边栏之类的能力那就在这个单文件基础上让AI再加入一个适配层再重新打包整个过程依然不用碰游戏引擎。6. 关于纯AI做游戏我碰出来的边界6.1 什么游戏适合纯AI做、什么不适合经过这几个项目我对AI能不能做游戏这个问题有了一个比较现实的判断。表格总结如下适合纯AI原生Canvas不建议用纯AI硬扛单屏休闲游戏大型多场景RPG交互逻辑简单直接复杂物理效果布料、流体无美术管线的小体量需要真实2D骨骼动画快速原型验证需要多人实时同步核心还是那句话纯AI做游戏的上限取决于你把需求拆得有多清楚。越是能让规则一句话说清楚的游戏AI就越能快速给你一个完整实现。6.2 我更推荐的人机协作流程以及一点真心话很多人以为纯AI写游戏是丢一句话给机器坐那里等结果。真实情况下我给AI改需求、审代码、测手感的时间比敲代码的时间多得多。每轮只改一个点每轮实测版本库管理几乎成了肌肉记忆。AI帮我省掉了大量写模板代码的时间但游戏好不好玩的判断依然要我自己去试、去调。每次吞下AI写出的缺陷代码时也会怀疑纯AI做游戏这条路是不是太折腾。但每次打开手机看到那只从Canvas上抖着腿跑的蚂蚁真的搬回了一颗果子听到自己合成的音效在扬声器里响起又会觉得这个折腾很值。如果你也想试一试建议从最简单的玩法开始先把游戏引擎都没用当成一个玩具再用AI把这个玩具滚成能上线的小游戏。下一步我打算让场景里出现多只蚂蚁、各自从不同方向搬运食物再加上两三个不同形态的关卡试试这套流程能撑到什么复杂度。
返回列表