不用代码,不用图片,仅靠Axure原生控件和Emoji,我做出了一个能在线玩的坦克对战原型《终章 2026》,它不到1M,却功能丰富,这究竟是怎么做到的?
本文是「终章 2026 · ChiTank」原型的介绍
主页:http://www.guochi.org/ChiTank/
GitHub:https://github.com/Axure-Guo/ChiTank
版本:v1.0
完成日期:2026-10-10
SHA256:8d307c101fcb89a334895157109e8e4c960437a1d4cfd55e15882c1943fb4ab1
开篇
先给你看个东西。
ChiTank《终章 2026》基础交互演示,浏览器直接打开即可游玩,无需安装客户端
这是一个用 Axure RP 11 做的坦克对战原型——ChiTank《终章 2026》。
它不到 1M,可以在浏览器里直接玩。 它不是游戏引擎,也不是商业游戏。 它是一次对 Axure 能力边界的正面测试:当大家说“原型工具做不了这个”的时候,它到底能不能?
一、它长什么样
5 种道具:星、满血闪充、幽灵、手雷、时钟
在线体验:http://www.guochi.org/ChiTank/
功能(可玩性)
坦克对战核心玩法:键盘移动、鼠标射击,消灭敌方坦克并保护基地(BUG)。
5 种道具:星(多轮次递进强化子弹)、幽灵(短暂无敌)、满血闪充(回满命)、手雷(全灭敌方坦克及子弹)、时钟(短暂冻结敌方坦克)。
1-R 关卡框架:第一关固定(原形),后续关卡随机变化。
多地图随机:每局地图随机生成,墙体布局永不重复。
Stage 与 Retry 计数:显示当前关卡和本关重试次数。
暂停/恢复:空格键暂停,任意键恢复(隐藏彩蛋)。
外场脉冲环境光:画布外光晕随事件变化:红(受伤)、金(吃星)、蓝(冻结)、紫(无敌)、灰(暂停)等。
性能探针可视化:画布外一条彩色光带,实时反映游戏卡顿程度(绿→红)。
三种终局画面:胜利、SHUTOUT(完胜)、Game Over,各有不同动效和文案。
基地 BUG 虫:基地形象为一只 BUG 虫,被击中则游戏结束。
键盘+鼠标操作:方向键移动、鼠标点击射击;WASD 为隐藏彩蛋操作。
全原创视觉:所有视觉基于 Axure 原生控件或 Emoji,零图片。
体积极小:整个原型不到 1MB,加载迅速。
二、技术要点节选:这是怎么做到的(重点)
这一章,是本文的核心。我把最能说明“Axure 能做什么”的 8 个技术点,一个一个拆开讲。每一条,都极有可能是全网未见、我在这个项目里原创的方法。
2.1 伪事件模拟程序结构(已普适性方法化)
Axure 没有特别丰富的函数、没有复杂可嵌套的 if-else、没有 return。
这是它的三重缺失。但我要做的,是把一个完整的游戏逻辑搭出来。没有函数,意味着代码无法封装、无法复用;没有复杂 if-else,意味着多层条件只能用“交互用例”硬叠;没有 return,意味着提前退出逻辑只能靠“把后续动作全部包在条件里”。
我用“伪事件”解决了这个问题。
思路是:用那些“用户不可能触发”的交互事件,当作函数入口。比如“尺寸改变”、“滚动”、“面板状态改变”这些事件,用户在日常操作中根本不会主动触发它们。我把它们当作纯函数入口来用。
【伪事件 A】(用“尺寸改变”做入口): 用例 1:[[条件 A]] → 执行 用例 2:[[条件 B]] → 执行 用例 3:Else → 执行一个伪事件,就是一个函数。它可以被“触发事件”这个动作调用,可以带参数(用全局变量传递),可以嵌套(伪事件触发伪事件),可以有返回值(写入全局变量)。
这套方法让我在 Axure 里模拟出了完整的程序结构:函数、参数、分支、嵌套、终止。整个坦克大战的敌方 AI 行为树、子弹碰撞判定、道具效果逻辑,都是用这套结构搭出来的。
这不是画出来的,是原生逻辑搭出来的
2.2 结界(减少吃空饷)
子弹每 20ms 步进一次。如果它一直在查询碰撞图(MapStr),那大部分时间都在“吃空饷”——查了,但什么都没碰到。
子弹在空旷战场上飞行的时间,远多于它接近墙体的时间。这意味着,绝大部分的碰撞查询是无效的。
我做了“护城河”——结界(多场景大量使用)。
子弹远离墙带时,走轻量循环,不做任何碰撞检测。只有进入墙带上下 24px 的缓冲区(护城河)时,才切换到监听循环,开始查询 MapStr。
护城河范围: 上边界:MapY - 24 - This.height 下边界:MapY + Map_l / 1.625 + 24效果:子弹在墙带外飞行时,完全不打扰碰撞检测。
这个优化把子弹对墙的检测频率砍掉了一半以上,是性能优化“减负三策略”里“减少吃空饷”的落地。
2.3 避免共振
三辆敌方坦克、五颗子弹、五个道具各自有独立的AI 循环。如果它们的周期相同或成整数倍关系,就会“共振”——在同一帧触发,造成峰值负载。
比如,如果五个道具都是 5 秒周期,它们会每 5 秒同时触发一次,形成脉冲式的计算高峰。
我把它们的周期设计成互质:5031ms / 6037ms / 7041ms / 8043ms / 9047ms。
互质的周期,最小公倍数极大。这五个周期的最小公倍数,大约是 24 小时以上——几乎不可能共振。
同样地,敌方坦克的准备时间也做了错峰:100 / 109 / 119 ms。子弹的步进周期也做了错峰:23 / 24 / 25 ms。
这是“避免共振”的完整落地。
穿钢弹演示:吃星第三档后,子弹变实心,可摧毁钢墙
2.4 独立副本原则
五个实体(1 个玩家 + 3 个敌坦 + 子弹),如果共享变量和事件,必然会出现状态污染。
比如,两个坦克如果共用同一个 status 变量,一个坦克被打死,另一个也会受影响。再比如,如果两个子弹共用同一个 zd_time,一个子弹发射后,另一个子弹的发射间隔就会被误判。
我给每个实体都配了独立的变量集和事件集。
敌方坦克 1/2/3 各有一套 tk_N_status、tk_N_fx、tk_N_str_1/2/3。子弹 A/B 各有一套 zd_A_status、zd_A_FX、zd_A_jz_1/2。
代价是元件数量增多,但换来的是:一个坦克的状态变化,绝不会污染另一个坦克。复制一套完整的坦克逻辑,只需要复制它的所有事件和变量,不需要改动其他任何地方。
内置 AI 坦克自动巡逻、转向、射击,全部 Axure 条件实现,无外部 JS 游戏引擎
2.5 镜轨渲染法
坦克大战有一个视觉难题:草丛要盖住坦克,坦克要盖住子弹,子弹要盖住地面。
如果所有元素都放在同一层,草丛就没法盖住坦克。
我用了“镜轨渲染法”:用两个中继器,一主一辅。
主中继器:渲染空地、砖墙、钢墙、河流。草丛格置空。
草地中继器:只渲染草丛,置顶。
两个中继器逐行对齐。主中继器渲染到第 N 行时,草地中继器也在第 N 行渲染它的草丛。视觉上,草丛就“浮”在坦克和子弹之上了。
最终实现的层结构:
1. 草丛(最顶) 2. 坦克 3. 子弹 4. 砖 / 钢 / 水 5. 空地(最底)镜轨渲染法实现的层结构
2.6 取景随机窗
地图怎么才能不重复?
一开始我想到的是“段对齐”——把地图库按固定长度切成若干段,每段是一张地图。比如 1000 字符的地图库,每 52 字符一张,可以切出 19 张。
但 19 张地图,玩几局就腻了。
我做了“取景随机窗”:从地图字符串的任意位置开始,向后截取固定长度。
Map_s = Math.floor(Math.random() * (aaa.length - Map_l)) MapStr = aaa.substring(Map_s, Map_s + Map_l)不再要求“对齐”,允许任意起点,允许跨越原有的段落边界。
同样一个 1000 字符的地图库:段对齐 = 19 张,取景随机窗 = 949 张。
地图多样性从“固定 N 张”推到了“几乎无限”。
另外一个好处是,任何人可以快速编辑N 张自己的地图。
2.7 性能探针可视化
我一直觉得游戏“有点卡”,但不知道哪里卡、卡多少?
直到有一天我发现:Timer 心跳的实际更新周期,在游戏进行中会变慢——它延迟了。这个延迟,就是 Axure 事件队列拥堵的直接证据。
我把 Timer 的延迟做成了一个可视化探针。
用两条线段的不透明度叠加,模拟从绿到红的连续色变:
t = [[Math.min(2 * Math.min((t1-t0-353) / 353, 1), 1)]] 红线不透明度 = [[Math.min(2 * t, 1) * 100]]% 绿线不透明度 = [[Math.min(2 * (1 - t), 1) * 100]]%绿=流畅,红=卡顿,探针越长说明越卡。卡顿从“感觉”变成了“颜色”、”长度“。
这个探针还有第二个价值:他人”战斗“时,只要截图发给我,我就能直观的看到他的性能数据。“人情反馈”被剔除了,剩下的是纯粹的数据。
性能探针——绿=流畅,红=卡顿
2.8 非受控滑步治理
这是最后一个被解决的 bug,也是最难的一个。
它的表现是:子弹偶尔掉头,敌方坦克重生时有时出现在原地(而不是顶部)。看起来是两个不相关的问题。
直到我意识到——它们是同一个问题。
问题出在“监听周期”和“步进周期”的差。我之前给坦克的步进监听周期设了 275ms,比 300ms 的步进周期短 25ms。这是凭“经验”给的安全垫。
但最近有了性能探针,终于量化出实际延迟只有 1.5~9ms,远小于 25ms。这个过大的余量,导致监听在步进尚未完成时触发,读到半途状态。单次无害,长期积累,就形成了“非受控滑步”——子弹漂移、重生失控。
我把 275 改成了 290(只留 10ms 余量),子弹的 3ms 余量也改成了 1ms。
问题消失了。
那根刺,不是“包容不了”,是“还没找到能量化它的工具”。
三、踩过的坑:Axure 做游戏天生的短板
性能瓶颈:对象越多、定时器越密集,浏览器开销越大。同屏 AI 数量要做限制,否则页面卡顿。当然,还有,中继器画面渲染更是吃性能怪兽(计划在后续版本中尝试替换成其他几个备选方案进行比较)。原型工具原本就不是为高频实时交互设计。
没有原生数组:如果是 JS,坦克、子弹可以放在数组循环遍历。Axure 只能手动逐个写条件,新增一个敌方坦克,就要新增一堆变量和条件,工作量线性暴涨。这是最折磨人的一点。
定时器不稳定:浏览器切后台,定时器会被节流,游戏时间会不准。
元件层级管理麻烦:子弹、坦克重叠时,Axure 原生元件层级控制很麻烦,需要额外逻辑处理。
项目调试文档节选,包含大量参数调优(此截图是早期的版本,后续已调整,以免误导大家,故而打码)、bug 修复记录
流畅度显著提升
我并不主张大家以后用 Axure 开发游戏。它不适合做商业游戏。 但这个项目对产品经理的启示是:AI 可以帮你画界面,但状态设计、多对象联动、边界条件校验,是 AI 很难替你深度思考的底层能力。当你能在 Axure 搭建出一套对战游戏的状态机,面对业务里复杂交互场景,思路会完全不一样。很多人放弃深耕 Axure 底层能力,把原型交给 AI,本质是放弃了交互逻辑训练的机会。
四、一个月,我收获了什么
产出类型 | 内容 |
|---|---|
方法 | 72 项高原创方法 |
洞察 | 289 条架构级认知 |
框架 | 1-R 关卡框架 |
文档 | 四份普适性方法文档 |
作品 | 一个可玩、可分享的完整原型 |
经验 | 从“解决问题”到“包容问题”的心态转变 |
但最大产出不是这些。
最大产出是:在工具限制下做架构级决策的思考。
这种思考,换任何工具、任何项目、任何领域,都能用。
击毁判定与游戏结束交互演示
五、尾声
比起这辆 Axure 坦克,更珍贵的是这场人与 AI 的搭子协作。它辅助拆解逻辑、推敲措辞,却也会出错、有局限。正是这份不完美,让并肩探索的过程足够真实。
我们造的从来不是坦克,而是在工具的桎梏之中,守住创造力的路径。
新工具层出不穷,光鲜省力,自有它擅长的领域。新旧工具并非非此即彼,各有所长。很多时候不是旧工具落伍,只是我们还没来得及和它处熟,就被新的东西推着往前走了。
工具不语,是使用者亲手赋予它生命力。
懂 Axure、在变量面板里反复打磨过交互逻辑的人,大概能读懂这份坚持。
若你愿意,欢迎试试这辆 ChiTank 坦克。或者,重新打开那个许久没动的 Axure RP,随便做点什么。
不急,慢慢来。她一直都在。
GitHub 已锚定:Release v1.0,SHA256 公开
附录:资源
项 | 链接 / 信息 |
|---|---|
在线体验 | http://www.guochi.org/ChiTank/ |
GitHub | https://github.com/Axure-Guo/ChiTank |
作者 | 郭池(www.guochi.org) |
授权联系 | live@aymi.cn |
版本 | v1.0 |
完成日期 | 2026-10-10 |
SHA256 | 8d307c101fcb89a334895157109e8e4c960437a1d4cfd55e15882c1943fb4ab1 |
版权声明:本作品由郭池独立创作。玩法致敬坦克对战品类,与任天堂、Namco 无关联。视觉全部原创,零图片。个人学习免费,商用需授权。
郭池 2026 年 10 月 12 日 上海