下载 App
开发日志06:双端
修改于昨天 08:45综合
上一篇结尾说,这一篇讲双端。
先说结论:这不是同一套界面缩两下,是两份东西。
同一套规则、同一批零件、同一批数值。但操作面完全不一样——电脑端有一整块屏幕和一只鼠标,信息可以全摊在边上;手机端只有两个拇指,大部分信息必须收起来,只在需要的时候出现。


一、为什么不做「响应式」
最省事的想法是把电脑端那张设计画布整体缩到手机上。我们确实在电脑端用了这个办法:所有元素画在一块固定大小的画布上,再整体缩放,像缩放一张图。1920 的屏幕上下留一点黑边,1280 的屏幕小一点,但版式永远不变。
这个办法在电脑上很好用。拿到手机上就不行。
一是字。窄屏档位缩到 0.75 倍,11px 的正文只剩 8px,在手机上是看不清的。
二是手指。按钮按设计尺寸缩过去,命中区比指尖还小。画得看得见,和点得中,是两件事。
所以手游版是另外一份:把缩放框整个拆掉,画面直接铺满,所有控件按视口重新排。
代价是两份代码。改一个数值要改两处,改一层界面要同步两处。这次真的翻过车——有一次把电脑版的页面文件直接覆盖到手游版,手游的布局层引用被整个冲掉,进游戏后 HUD 一个都没有,画面干干净净。这类错误不会报任何错,只能靠人眼发现。
进游戏前是一段三秒多的开场:扫描线、四枚刻度依次点亮、裸核点火,标题擦出来。零件是真的一片片吸上去的,落位时有火花和焊缝——和局内吸残骸用的是同一套曲线和同一套判定,不是另做一段动画。

开场之后落在机库。左边是标题和主动作,右边是机体示意——这里放的是示意,不是存档里的机体,因为新开一局永远是从一枚裸核开始。下面三个小按钮管读档、机库编装和设置,重量级压在主按钮之下。



二、电脑端:三列信息,各回答一个问题
电脑端的战斗界面分成四块,每一块只回答一个问题:
| 位置 | 回答什么 | 具体内容 |
|---|---|---|
| 顶部细条 | 我在哪 | 区域名、当前舱位名 |
| 左侧一列 | 我现在什么状态 | 核心血量、电池组、电量/供能、推进器与当前移速、炮台可用数、最高组件等级、操作指南 |
| 右侧一列 | 外面是什么情况 | 本区舱位小图(含全舰航图入口)、安装/卫星计数、战场雷达 |
| 底部一排 | 我现在能按什么 | 五张技能卡,每张实时写状态 |
我们没做「血条 + 蓝条 + 冷却圈」那一套。这台机体不是一个人,是一堆零件拼起来的,所以左边的信息更像一块仪表盘:电池组几块、电量多少、供能容量几点、推进器几个、当前移速多少、炮台几门可用。

底部五张卡,每张都会把「为什么按不出来」写出来:核心脉冲是就绪还是冷却、磁力回收附近有几块能吸、炮台齐射有几门受阻、推进冲刺是没接推进器还是冷却中、分支抛射是这个方向有没有合法分支。
玩家按了没反应,最需要的不是提示音,是一句「两台炮都不可用」。

开火的手感来自三件事:脉冲本身要有一条能看清的亮线,命中要有反馈,而且不能把屏幕糊住。屏幕中央是一台机甲,周围还有三四个敌人,任何一层全屏光效都会让玩家看不清自己有没有被打中。我们宁可把亮度收一点,也不让玩家看不清战局。

按「组件」会打开这个:左边是按真实网格位置排的机体,右边是选中组件的全部参数。它不是为了好看——你装歪了、把某个件伸得太远、某个炮被挡了射界,都在这里看得出来。

暂停页可以直接存档、读档,不用退回主菜单。


三、手游端:先把框拆掉
手游版第一件事是拆框。
电脑端有四层框:外框、内唇、画面框、面板框。这套东西在宽屏上很有机械感,在手机上就是四条黑边加一圈装饰。我们把它们全去掉,画面铺满整个屏幕,控件直接浮在画面上。
拆完框立刻出现一个新问题:左边那五块面板没地方放了。
在电脑上它们可以常驻,因为屏幕够宽;在手机上,五块面板会吃掉三分之一画面,而且它们回答的问题——我还剩多少电、我还有几门炮——在战斗中往往只需要看一眼,不需要一直看。
所以:
核心状态收进右上角一块小面板:等级图标、核心血量、经验进度,再加一行组件数、卫星数、经验。放在右上,是因为横屏握持时右手拇指在右下角操作,右上是最不容易被手挡住的位置。
顶栏压成一颗圆形菜单键。它可以拖,松手会自动吸到最近的左右边缘;闲置几秒自己缩小变淡;位置记在本机,下次打开还在你放的地方。
左上角只留本区小图,下面是「地图 / 跟随」两个按钮。小图和战场雷达二选一、同位置切换——手机屏幕放不下两张图,硬塞的结果是两张都看不清。
左下角是摇杆和核心血条。血条的位置不是写死的像素,是读完摇杆的实际矩形再贴上去的,所以换任何屏幕比例都不会压住摇杆,也不会跑出屏幕。

首页也跟着重排了。电脑端的主按钮是通栏的「开始星舰战役」,下面三个小按钮管读档、机库和设置;手机上版面更窄,主按钮仍然保持整行,其余入口按重要性依次降级。我们不想让「开始游戏」和「设置」长得一样大。


四、右下角这只手
这一段是双端适配里最花时间的。
最开始做的就是弧形:技能沿右下角一圈排开,弧心放普攻。
然后在极扁的屏幕(800×360,20:9)上撞墙了。弧有边界,按钮又不能重叠——这两个约束在这么扁的空间里互相打架。我们反复缩尺寸、调角度,还是留下五处重叠。
那就退一步,上网格:主键在右下角,其余六个技能排成两列三行。网格的间距是写死的,几何上不可能重叠。我们先认输。
网格能用,但手感像遥控器。拇指在右下角的活动范围是一个扇形,不是方格。所以后来还是改回了真弧形:四个技能沿 180° 到 120° 排开,弧心是普攻键。普攻是唯一一个需要按住不放的键,放弧心最省力。
然后是超负荷和投掷炸药——两个不常用、但不能没有的键。
第一版做成「按住普攻往上滑,右侧列出 B 和 T」。问题是一根手指在同时干两件事:按住代表开火,滑动代表换键;只要开始滑,就得先停火。
第二版改成左轮:六个技能排在一个轮子上,四个槽位固定,按住转盘区域画圈就能转,转到第五、第六项时,超负荷和投掷炸药进槽。

这个改动之后我们才觉得「手机上能玩」了。不是因为它更华丽,是因为拇指画圈是自然的,上下滑不是。


五、手机上最有意义的三个 bug
这一节记录三个不报错、但会让人以为「这游戏坏了」的问题。
第一,技能卡只是显示卡。
电脑上的五张卡不接任何逻辑。左键在画布上开火,E 是磁力,Q 是齐射,全是键盘鼠标直接绑定的。手游把键鼠藏起来之后,五张卡还漂漂亮亮地待在那儿——点了没反应。
修法不是重写一套判定,而是把卡片接到既有入口:普攻按住连发、磁力按下松开、齐射和冲刺直接调用、抛射按下预览、拖动瞄准、松开提交。**规则只有一份,界面只是调用方。**这一点如果搞反,两端的手感会慢慢分叉。
第二,透明的命中层把点击吃掉了。
左轮需要一个透明区域来识别画圈。它盖在整个弧上,于是底下五个技能按钮全都收不到点击——实测取五个技能的中心点,五个全部落在命中层上。
修法:没转动、且按下不到 400 毫秒就抬起,判定为「点击」,临时关掉命中层的点击命中,重新取这一点的元素栈,找到白名单里的按钮,把按下和抬起补发过去。白名单只放技能键,避免误派发到画布。
第三,弹窗被 HUD 盖住。
手游控件的层级是 36 到 43,弹窗只有 20。一开弹窗,摇杆、技能、菜单全浮在上面,转盘的命中层还会把弹窗里的点击吃掉。
修法没用脚本记状态,纯 CSS:只要有弹窗打开,就把所有手游控件隐藏。弹窗一关自动恢复,不会留下「关完弹窗某个按钮不见了」的残留。
还有一些小的:按钮里的图片会触发浏览器原生拖拽,拖到一半指针事件被掐断;用背景简写写图标会把图片一起重置掉;旧规则是两个 ID 的选择器,新规则只写一个 ID,带最高优先级也压不住。
这些都不难。难的是它们全都不报错。


六、瞄准:手机上其实没有鼠标
电脑上,准星跟着鼠标走,这是理所当然的。
手机上,我们第一版让摇杆直接写准星坐标——结果就是你往哪走,炮口就往哪指。想让炮口对着敌人,得先把自己转过去。这显然不对。
第二版加了自动索敌:只要你没有手动瞄准,准星自动指向射程内最近的敌人。如果中间隔着掩体,这个目标的权重会被压下去 600 点,也就是优先选能打到的那个。没有目标时准星不动,不会乱飘。
还有一个很隐蔽的时序问题:自动索敌必须在一帧逻辑之前先跑一次。因为开火判定在逻辑内部执行,如果只在逻辑之后瞄准,那么这一发子弹用的是上一帧的准星——也就是摇杆方向。表现是「明明对着敌人,子弹却往旁边飞」。现在前后各跑一次:前一次决定这一帧往哪打,后一次保证画面和界面一致。
摇杆还兼了一个功能:猛拉到底会触发推进冲刺。阈值是摇杆半径的 0.92 倍,回中到 0.6 倍以下才重新武装。这样按住不放不会连续冲刺,但要跑的时候不用再去找按钮。


七、三档视角
手机屏幕小,只有「跟随 / 全景」两档不够用。现在是三档循环:
| 档位 | 倍率 | 用在哪 |
|---|---|---|
| 近景 | 2.15 | 看清自己的构筑和弹道,打 Boss 时用 |
| 跟随 | 1.65 | 默认,走路和清小怪 |
| 全景 | 1.00 | 看清整间舱室的门在哪、敌人从哪来 |
切换按钮就在地图按钮旁边,按钮上写的是当前档位的名字,点一下切到下一档。之前只有两档时它写「跟随 / 全景」,读起来像两个动作,其实是一个状态。


八、打包:三个只有装进 APK 才会暴露的坑
第一,前端是被编进库里的。
手机壳用的方案会把整个前端在编译时嵌进原生库。也就是说,如果你只重跑了打包那一步、没有重新编译原生库,装到手机上的还是上一次编译时的界面。
这一条坑了我们一整轮:改了按钮尺寸,网页上是对的,手机上纹丝不动。后来在构建脚本里加了一条硬校验——原生库的修改时间必须晚于前端最新文件,否则直接报错退出。
第二,全屏在安卓上是空实现。
桌面壳提供的全屏调用,在安卓端什么也不做。系统状态栏和导航栏还在,压住了最上面一行按钮,点菜单点不动。最后是在原生层隐藏系统栏,并且让导航栏只能从边缘划出。
第三,内存页对齐。
Android 15 之后,部分设备的内存页从 4KB 变成 16KB。旧的编译产物按 4KB 对齐,在这些设备上会直接加载失败。我们在链接参数里显式指定 16KB,重建后四个加载段全部对齐。
还有包名。原来包名里带着渠道标识,这是审核明确禁止的,属于首次上架之后就改不了的东西,已经改成独立的包名。游戏标题的三处写法也统一了。


九、两端现在验到什么程度
手游端在七种视口下逐一量过:超宽 20:9、19.5:9、iPhone 比例、4:3、小屏、平板、2K。
| 视口 | 按钮重叠 | 越界 | 报错 |
|---|---|---|---|
| 936×432 | 0 | 0 | 0 |
| 800×360 | 0 | 0 | 0 |
| 1024×768 | 0 | 0 | 0 |
| 844×390 | 0 | 0 | 0 |
| 667×375 | 0 | 0 | 0 |
| 1280×720 | 0 | 0 | 0 |
| 2560×1080 | 0 | 0 | 0 |
另外在安卓模拟器上跑过 x86_64 的安装包:全屏、菜单、普攻、摇杆、四个按钮、暂停页都通了。


十、游戏现在到哪一步了
把当前这一版完整摊开,进度如下:
| 项 | 现状 |
|---|---|
| 地图 | 175 个舱室(主区 140 + 支线 35),20 个主区,7 条支线 |
| Boss | 20 个(19 个区 Boss + 终局) |
| 零件 | 6 类,每类 5 级 |
| 道具 | 7 种一次性增益 |
| 卫星 | 最多 3 只 |
| 安装上限 | 默认 12,奖励可抬到 25 |
| 玩家核心 | 520 → 978 耐久,脉冲 14 → 22,冷却 12 → 8 tick |
| 敌人核心 | 140 → 252 耐久(成长低于玩家) |
| Boss 核心 | 五级 1512,终局三核合计 4536 |
| 装甲 | 325 耐久 |
| 炮台齐射 | 2.4 秒一轮 |
| 舱门判定 | 49.4 像素 |
| PC 包 | 上架 zip 41.9 MiB / 桌面安装包 40.2 MiB |
| 安卓包 | 85.5 MiB(arm64) |
装配台这一版也重做了:面板换成和战斗 HUD 同一套材质,组件图标换成写实贴图,空槽常驻显示,中间有按真实位置绘制的机体预览,下面一条「连接 / 方向 / 供电 / 归属」四规则条——就是这游戏的四条拼装规则。

机库里选的东西,这一版终于是真的带进战斗了。之前有个很尴尬的 bug:选好的携带件在开局时被初始化流程整个清空,界面上写着「已保存到本机」,实际上对局内完全没有作用。现在选中的三件会以未焊接状态散落在出生点,需要自己吸上来。
后续双端也会继续对齐:手机上把装配台压进一屏、补返回键和安全区,电脑端把长局性能查清楚。
开发日志会持续更新,游戏还在做,预计明天就可以上线,欢迎到时候来试玩。











