From 2c3464b6f0bb6a982952a71b55e4a5ba8efc8bf3 Mon Sep 17 00:00:00 2001 From: Joywayer Date: Tue, 25 Aug 2026 09:01:52 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BA=8C=E4=B8=83=E7=8E=8B=EF=BC=9AUI=20?= =?UTF-8?q?=E6=B8=85=E5=8D=95=E5=85=B3=E9=97=AD=207=20=E9=A1=B9=E5=BE=85?= =?UTF-8?q?=E7=A1=AE=E8=AE=A4=EF=BC=8C=E8=A1=A5=E5=B9=B3=E5=8F=B0=E5=9B=BE?= =?UTF-8?q?=E5=B1=82=E6=B8=85=E5=8D=95=E4=B8=8E=E9=AA=8C=E6=94=B6=E6=A3=80?= =?UTF-8?q?=E6=9F=A5=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 从平台代码/编辑器数据查证后关闭: - T-2 解散投票:平台全包(Layer 420 CheckFree_Layer + GameUI.openCheck + Desk.self_apply_free_room 一族),子游戏只处理解散结算包,D-10 缩到 只剩结算面板。 - T-3 建房图层:Layer 27 CreateRoom_Layer;Layer 28 SeniorOptions_Layer 是代开房/抽水,与玩法规则选项无关,不走它。 按参考图算定 / 技术自决: - T-21 手牌间距:单排 spacingMin=-78(36 张露 32px,与实测 33px 吻合), 双排 -65。 - T-27 埋牌分行:上排 floor(n/2)、下排 ceil(n/2);参考图 17/19 按 mock 处理。 - T-25 line 增加可选 items 支持逐项不等宽,底栏功能钮组与埋牌/出牌操作条 改用它。 - T-17 倒计时归零停在 0 不隐藏(隐藏会被误读为已超时/已跳过)。 - T-28 EQW_Layout 为权威,配置区手工同步并列入验收。 另补: - §0.2 增列平台已占用的 14 个图层(创建房间/解散/帮助/设置/加载/重连/ 战绩/聊天语音等),凡列出者子游戏不必重建。 - 新增 §7.3 验收检查清单 12 条,逐条对应一处已知易错点。 Co-Authored-By: Claude Opus 5 (1M context) --- docs_dev/二七王-UI资源与精灵清单.md | 86 ++++++++++++++++++++++------- 1 file changed, 67 insertions(+), 19 deletions(-) diff --git a/docs_dev/二七王-UI资源与精灵清单.md b/docs_dev/二七王-UI资源与精灵清单.md index d8723d4..b92e0f3 100644 --- a/docs_dev/二七王-UI资源与精灵清单.md +++ b/docs_dev/二七王-UI资源与精灵清单.md @@ -84,7 +84,27 @@ get_nextseat: function(seat){ return (seat + 1) % 3; } | Loading / Message / Confirm 全局弹窗 | 框架 `UIManager` 全局 UI | 由子游戏在 `UIManager.init` 注入精灵常量 | 若要用,需**另建**这三套弹窗精灵并注入;不用则跳过 | | 战绩列表 | 框架 `RecordView` 组件 + 平台入口精灵 `13` | `gameabc-framework/ui/RecordView.js` | 提供 `RecordView` 配置;战绩数据结构见协议「gameinfo1 / gameinfo2」 | | 帮助界面 | 平台 `GameUI.OpenHelp()`,入口精灵 `150` | —— | 提供二七王玩法说明文案 | -| 创建房间界面**骨架** | 平台界面 + 约定精灵 `25`(确认/提交按钮) | 见 `01_SubGame_modify.js` 顶部注释 | **规则选项区要子游戏自建**(§1.1):渲染 5 个开关行、拼 `roomtype` 串、注册 25 号点击后 `Net.Send_create_room` | +| 创建房间界面**骨架** | 平台界面 **Layer 27 `CreateRoom_Layer`** + 约定精灵 `25`(确认/提交按钮) | 见 `01_SubGame_modify.js` 顶部注释 | **规则选项区要子游戏自建**(§1.1):渲染选项、拼 `roomtype` 串、注册 25 号点击后 `Net.Send_create_room` | +| **解散申请 / 投票 / 同意拒绝** | **平台全包**:`Layer 420 CheckFree_Layer` + `GameUI.openCheck/closeCheck` + `Desk.self_apply_free_room` / `other_apply_free_room` / `self_agree_free_room` / `self_refuse_free_room` / `agreefree` / `free_room` | —— | **无**。子游戏只需处理解散**结算包**(§1.10),投票界面不用做 | +| 高级选项 / 代开房 | `Layer 28 SeniorOptions_Layer` + `GameUI.openSeniorOptions` | —— | 无。它管短号 / 抽水 / 房间列表,**与玩法规则选项无关**,二七王的规则选项不走这里 | + +**平台已占用的图层一览**(读 `gameabc_Layer.json`,凡此列出者子游戏都不必重建): + +| 图层 | 名称 | 用途 | +| --- | --- | --- | +| 27 / 28 | `CreateRoom_Layer` / `SeniorOptions_Layer` | 创建房间 / 高级选项 | +| 50 | `MainScene_Layer` | 牌桌主场景 | +| 202 / 416 | `Player_Head_Score_Layer` / `MainScene_PlayerInfo_Layer` | 玩家头像与分数 | +| 409 / 410 / 418 | `Chat_Voice_Layer` / `Chat_Text_Layer` / `ChatPannel_Layer` | 聊天与语音 | +| 420 | `CheckFree_Layer` | **解散投票** | +| 608 / 609 | `Help_Layer` / `Setting_Layer` | 帮助 / 设置 | +| 612 | `Tips_Layer` | 通用提示 | +| 613 | `updateRoomCard_Layer` | 房卡更新 | +| 614 / 615 | `Loading_Layer` / `Reconnect_Layer` | 加载 / 断线重连 | +| 616 / 619 | `Kick_Layer` / `BackHall_Layer` | 踢人 / 返回大厅 | +| 620 | `recordLayer` | 战绩 | + +> 这些都落在框架保留段(1–100 / 201–300 / 401–500 / 601–700),与子游戏段 101–200 / 301–400 不冲突。 > ⚠️ 参考图底栏左侧的「头像 + 玩家昵称 + 10 + 庄」一行里,**头像/昵称/分数是平台的**,只有 **`庄` 印章**是二七王专属、需子游戏新建。左上/右上玩家位同理:头像框是平台的,**`庄` 印章、`主N`、`对N` 角标、状态文字**是子游戏的。 @@ -665,7 +685,9 @@ EQW_RoomOptions = { - 解散局 `aset.multiple = 0`、`upgrade = 0`、各家 `grade = 0`,`account` 恒有; - **`data.deskfree` 可能缺失**(开战后、首局发牌前解散时 `get_disbandRoom` 返回 `null`)→ 前端必须容忍。 -界面复用 §1.9 的大局总结算面板。解散**投票**界面是否由平台提供,见 T-2。 +界面复用 §1.9 的大局总结算面板。 + +> **解散的申请/投票/同意拒绝界面由平台全包**(`Layer 420 CheckFree_Layer` + `GameUI.openCheck` + `Desk.self_apply_free_room` / `other_apply_free_room` / `self_agree_free_room` / `self_refuse_free_room` / `agreefree`),子游戏**不做投票界面**,只处理上面这个结算包。 ### 1.11 断线重连 `deskinfo` @@ -751,7 +773,7 @@ EQW_RoomOptions = { - 数据来源:各包的 `countdown`。 - **只做展示,不触发任何操作**(design §11 / 协议 §0.3):倒计时归零后**不自动叫分/选主/埋牌/出牌**,也不判负、不跳过。前端**不得**在归零时做任何乐观界面推进(不跳阶段、不清控制权),一切仍等服务端推送。 -- 归零后的表现【待确认 T-17】:显示 `0` 还是隐藏。 +- **归零后停在 `0` 继续显示,不隐藏**:协议 §0.3 明确归零不触发任何动作、牌局原地等待该玩家;隐藏会被误读为「已超时/已跳过」。 - 精灵:群组 224,号段 1150–1159。 ### 2.5 亮牌信息条 【图:多张】 @@ -1183,6 +1205,15 @@ for (var i = 0; i < cards.length; i++) { `count` 由运行时数据给出,不进配置。 +**逐项不等宽**:给出可选的 `items` 时逐项取宽,`itemWidth` 失效——用于底栏功能钮组(74/87/93/78)与埋牌操作条(180/60/180)这类宽度不一的排: + +```js +{ kind: 'line', direction: 'horizontal', + anchorX: 1250, anchorY: 672, itemHeight: 30, spacing: 15, anchor: 'right', + items: [ {key:'BTN_MINGPAI', width:74}, {key:'BTN_HISTORY', width:87}, + {key:'BTN_LAST_ROUND', width:93}, {key:'BTN_BOTTOM_CARDS', width:78} ] } +``` + #### `fan` — 自适应压缩排 张数可变、**总宽受限**、需要动态压缩间距的牌排(手牌、出牌区、算奖牌)。 @@ -1290,14 +1321,12 @@ CARD_SIZE: { | 亮牌信息条 | `point` | `x:35 y:400 w:210 h:35` | | 底栏条 | `point` | `x:0 y:648 w:1280 h:72` | | 底栏 · 局数文字 | `point` | `x:635 y:672 w:65 h:26`,`textStyle{fontSize:20, align:center}` | -| 底栏 · 功能钮组(明牌/已出牌/上一轮/底牌) | `line` | `direction:horizontal, anchorY:672, itemHeight:30, spacing:15, anchor:right, anchorX:1250`;**各钮宽度不等**(74/87/93/78),故按 `anchor:right` 从右往左排,宽度逐项给 | +| 底栏 · 功能钮组(明牌/已出牌/上一轮/底牌) | `line` + `items` | `direction:horizontal, anchorX:1250, anchorY:672, itemHeight:30, spacing:15, anchor:right`,`items:[74,87,93,78]`(逐项不等宽,见 §6.1) | | 底栏 · 庄标 | `point` | `x:338 y:668 w:32 h:34` | | 底栏 · 提示按钮组(踩/有分/没分) | `line` | `direction:horizontal, anchorX:335, anchorY:672, itemWidth:52, itemHeight:30, spacing:26, anchor:left` | | 右侧语音钮(平台) | `point` | `x:1210 y:310 w:56 h:56` | | 右侧聊天钮(平台) | `point` | `x:1210 y:385 w:56 h:56` | -> 底栏功能钮组是**宽度不等**的一排,`line` 的 `itemWidth` 不适用 → 该组用 `line` + 每项独立 `itemWidth` 的变体,或退化为 4 个 `point`【待确认 T-25:是否给 `line` 增加「逐项宽度」支持】。 - ### 6.6 玩家位配置(含气泡朝向) 平台负责头像/昵称/分数,子游戏的附加标记全部 `attach` 到平台头像框上——这样平台布局一调,标记自动跟随。 @@ -1328,8 +1357,8 @@ CARD_SIZE: { | 区域 | kind | 参数(实测估值) | | --- | --- | --- | -| **自己手牌 · 单排** | `fan` | `anchorX:640 anchorY:455 maxWidth:1215 size:L spacingMax:0 spacingMin:-84 anchor:center overlapFrom:left` | -| **自己手牌 · 双排(埋牌)** | `fan` ×2 | 上排 `anchorX:644 anchorY:285 maxWidth:928 size:L`;下排 `anchorX:644 anchorY:455 maxWidth:928 size:L`。**分行策略**:上排 `ceil(n/2)-1`、下排其余【待确认 T-27:17/19 的分法依据】 | +| **自己手牌 · 单排** | `fan` | `anchorX:640 anchorY:455 maxWidth:1215 size:L spacingMax:0 spacingMin:-78 anchor:center overlapFrom:left`。36 张时算出 `spacing = 1215−110)/35 − 110 ≈ −78`,即每张露 32px,与参考图实测 33px 吻合 | +| **自己手牌 · 双排(埋牌)** | `fan` ×2 | 上排 `anchorX:644 anchorY:285 maxWidth:928 size:L spacingMin:-65`;下排 `anchorX:644 anchorY:455 maxWidth:928 size:L spacingMin:-65`。**分行策略:上排 `floor(n/2)`、下排 `ceil(n/2)`**(36 张 = 18/18)。参考图的 17/19 无规则依据,按 mock 处理 | | 手牌 · 选中上浮 | —— | `selectedOffsetY: -40`(配置项,不写死) | | **暗牌区** | `line` | `anchorX:655 anchorY:110 size:L spacing:-36 anchor:center`(8 张) | | **底牌区(结算)** | `line` | `anchorX:640 anchorY:163 size:S spacing:2 anchor:center`(8 张) | @@ -1354,8 +1383,8 @@ CARD_SIZE: { | 选主 · 花色图标 | `attach` | `target:对应花色按钮, hAlign:left, vAlign:middle, offsetX:14` | | 选主 · 张数大字 | `attach` | `target:对应花色按钮, hAlign:center, vAlign:middle, offsetX:14` | | 选主 · 对数角标 | `attach` | `target:对应花色按钮, corner:topRight, offsetX:-36, offsetY:2` | -| 埋牌 · 操作条 | `line` | `direction:horizontal anchorX:640 anchorY:165 itemHeight:63 spacing:45 anchor:center`(提示 180 / 倒计时 60 / 埋牌 180,宽度不等,同 T-25) | -| 出牌 · 操作条 | `line` | `direction:horizontal anchorX:640 anchorY:345 itemHeight:55 spacing:35 anchor:center`(倒计时 75 / 出牌 157) | +| 埋牌 · 操作条 | `line` + `items` | `direction:horizontal anchorX:640 anchorY:165 itemHeight:63 spacing:45 anchor:center`,`items:[180,60,180]`(提示 / 倒计时 / 埋牌) | +| 出牌 · 操作条 | `line` + `items` | `direction:horizontal anchorX:640 anchorY:345 itemHeight:55 spacing:35 anchor:center`,`items:[75,157]`(倒计时 / 出牌) | | 捡分飘字 | `point` | `x:570 y:180 w:170 h:55`;另配 `floatRise:-60`、`floatDuration:800`(动画参数也进配置) | ### 6.9 结算区配置 @@ -1446,7 +1475,7 @@ codes/config/ | D-7 | 出牌历史面板 | §1.7 | 按轮次 × 3 家 | | D-8 | 判定结果文字(大光/小光/过庄/升N级/投降) | §1.8 | 结算时的判定展示 | | D-9 | 大局总结算 | §1.9 | 三家 × N 局成绩表 | -| D-10 | 解散结算 / 解散投票 | §1.10 | 可能复用 D-9 + 平台投票界面 | +| D-10 | 解散结算 | §1.10 | **投票界面平台全包**(Layer 420),只剩结算面板,可直接复用 D-9 | | D-11 | 准备标识 | §1.12 | 或复用平台准备标识;**`下一局` 按钮已有图**(§1.8),准备状态标识仍缺 | | ~~D-12~~ | ~~左上家已出牌区~~ | §2.3 | **已定**:与右上家左右镜像,无需单独设计稿 | @@ -1455,8 +1484,8 @@ codes/config/ | 编号 | 问题 | 影响 | | --- | --- | --- | | ~~T-1~~ | ~~逆时针方向:下家是 `(seat+1)%3` 还是 `(seat+2)%3`~~ | **已定论**,见 §0.1:`class.paiju.js:264` `get_nextseat = (seat+1)%3`,下家显示在右上 | -| **T-2** | 解散投票界面是平台提供还是子游戏自建? | 是否需要 D-10 的一半工作 | -| **T-3** | 平台创建房间界面在哪个图层?子游戏选项精灵挂在哪? | §5.8 的图层归属 | +| ~~T-2~~ | ~~解散投票界面是平台提供还是子游戏自建?~~ | **已定论**:**平台全包**(`Layer 420 CheckFree_Layer` + `GameUI.openCheck` + `Desk.*_free_room` 一族),子游戏只处理解散结算包 | +| ~~T-3~~ | ~~平台创建房间界面在哪个图层?~~ | **已定论**:**Layer 27 `CreateRoom_Layer`**(`Layer 28 SeniorOptions_Layer` 是代开房/抽水,与玩法规则无关) | | **T-4** | 是否需要发牌动画? | 动画配置与工期 | | **T-5** | 手牌排序规则(主牌左/右、副牌花色顺序);选主后重排的动画表现 | 布局算法 | | **T-6** | 叫分档位按钮第 3 帧(参考图第二行橙色)的含义 | `BTN_CALL_SCORE` 帧数 | @@ -1470,21 +1499,40 @@ codes/config/ | ~~T-14~~ | ~~结算面板是否展示算奖明细~~ | **已定论**:走独立的**算奖牌型叠加层**(`算奖牌型` 按钮打开),见 `算奖牌型显示.png` | | **T-15** | 准备状态用平台标识还是自建? | D-11 | | **T-16** | 顶部 `抓分` 列角标:早期图为 `1子`、三张新图均为 `1倍`。**推定为 `1倍`**,但语义待定:是 `aset.upgrade` 判定倍率,还是 `bottom.multiple` 扣底倍数? | 精灵 1008 的数据源 | -| **T-17** | 倒计时归零后显示 `0` 还是隐藏? | 渲染规则 | +| ~~T-17~~ | ~~倒计时归零后显示 `0` 还是隐藏?~~ | **已定**:**停在 `0` 继续显示**。协议 §0.3 明确归零不触发任何动作、牌局原地等待;隐藏会被误读为「已超时/已跳过」 | | **T-18** | 底栏 `底牌` 按钮:庄家点了看自己埋的 8 张?闲家点了看什么?未埋牌时呢? | 交互定义 | | **T-19** | 数字用图片精灵(多帧)还是文字精灵(`setText`)? | 是否需要资源 631–634 | | **T-20** | **整套音效**:清单、是否需要语音包、是否分男女声 | §4 全节 | -| **T-21** | 手牌 `fan` 的 `spacingMin` / `spacingMax` 具体取值(36 张时最大重叠量) | §6.7 配置值 | +| ~~T-21~~ | ~~手牌 `fan` 的 `spacingMin`/`spacingMax` 取值~~ | **已按参考图算定**:单排 `spacingMax:0, spacingMin:-78`(36 张时露 32px,与参考图实测 33px 吻合);埋牌双排 `spacingMin:-65`。见 §6.7 | | **T-22** | 算奖牌型叠加层的关闭方式(再点按钮 / 点遮罩 / 独立关闭钮) | §1.8 交互 | | **T-23** | 算奖叠加层是否并列显示奖数(`chongguan` / `wang` / `naward`) | 精灵 1825–1827 是否需要 | | ~~T-24~~ | ~~算奖牌 `cards` 超过 8 张时怎么排~~ | **已定论**:改用**精灵复制**(§5.6a),张数不设上限,`fan` 自适应压缩 | -| **T-25** | `line` 布局器是否需要支持「逐项不等宽」(底栏功能钮组、埋牌操作条) | §6.1 布局器参数 | +| ~~T-25~~ | ~~`line` 是否支持「逐项不等宽」~~ | **已定**:支持。`line` 增加可选 `items:[{width},…]`,给出时逐项取宽、不给时用统一 `itemWidth`。见 §6.1 | | **T-26** | 自己发的提示是否需要本地回显气泡(协议不回执,默认看不到) | §6.6 SELF 气泡 | -| **T-27** | 埋牌双排的分行策略(参考图 17/19,依据未知) | §6.7 配置值 | -| **T-28** | `EQW_Layout` 与 `Game_Modify.PLAYER_INFO_LAYOUT` 的坐标一致性如何保障(转发壳不能引用 codes) | §6.11 同步机制 | +| ~~T-27~~ | ~~埋牌双排分行策略~~ | **已定**:上排 `floor(n/2)`、下排 `ceil(n/2)`(36 张即 18/18)。参考图的 17/19 无规则依据,按 mock 处理 | +| ~~T-28~~ | ~~两份布局配置的坐标一致性~~ | **已定**:`EQW_Layout` 为权威,`01_SubGame_modify.js` 配置区手工同步并加注释;一致性列入验收清单(§7.3 第 10 条) | | **T-29** | 建房界面的整体位置与可用尺寸(依赖平台创建房间界面,与 T-3 同源) | §6.9b 的 anchor 起点 | -### 7.3 开发前置条件 +### 7.3 验收检查清单 + +编码完成后必须逐条核对(每条都对应一处已知易错点): + +| # | 检查项 | 依据 | +| --- | --- | --- | +| 1 | `cardIdToFrame` 通过 §0.4 的 10 条校验样例 | 花色段与 id 段序相反,最易静默画错牌 | +| 2 | 三家显示位映射正确:下家 `(mySeat+1)%3` 在右上 | §0.1 | +| 3 | 提示按钮顺序(踩/有分/没分)与 `tip` 编号(1踩/2没分/3有分)的映射未按下标硬推 | §1.7 | +| 4 | 气泡帧号 = `(箭头向右?3:0)+tip`,朝向按头像相对位置取 | §1.7 / §6.6 | +| 5 | 不可查牌模式下:`明牌`/`已出牌`/`上一轮` 按钮不出现、亮牌条不出现、`主N`/`对N` 角标不出现 | design §9 | +| 6 | 投降结算(无 `bottom`)与解散结算(无 `deskfree` 的情形)都不崩、不显示空框 | §1.8 / §1.10 | +| 7 | 解散包从 `data.deskfree.data.aset` 取值,不是 `data.aset` | §1.10 | +| 8 | 倒计时归零不做任何界面推进 | 协议 §0.3 | +| 9 | 算奖牌型叠加层关闭时 `SpriteCopyUtils.removeRange` 已清理 | §5.6a | +| 10 | `EQW_Layout` 与 `Game_Modify.PLAYER_INFO_LAYOUT` 的头像框坐标一致 | §6.11 | +| 11 | 丢弃 `this.data`、仅凭最近一次服务端快照重画,界面完全一致 | 前端 05 §6.2 | +| 12 | 所有布局参数都在配置文件里,业务代码无裸值 | §6 | + +### 7.4 开发前置条件 在本清单的资源补齐前,前端**不具备开发条件**的部分: