二七王:UI 清单补冲关定义,算奖牌型与建房选项改精灵复制

- 补「冲关」的准确定义(class.arith.js:1277 get_chongguan):它就是
  design §8.1 常规算奖的服务端命名,不是独立规则。列出 count/wang/cards
  三个返回值的去向与计数规则,并点明两处易错:连对链必须先有 ≥3 王才
  计算;固定主牌 ≥10 张只触发亮牌、不算奖。前端不重算,一律取下发值。

- 算奖牌型叠加层改用 SpriteCopyUtils 精灵复制:cards 张数无小上限
  (四王 + 长连对链 + 八个 7 + 八个 2 可达 20+ 张),预置既可能不够又
  常年空占。编辑器只建 5 个精灵(遮罩 + 3 容器 + 1 模板),省约 19 个 ID,
  关闭 T-24。

- 建房界面按「类别标题(牌局/模式/规则)+ 选项组」重构:
  选项组分单选 / 多选 / 单选(可不选)三型,后者复用复选图;
  每个选项 = 选择框图片 + 文字精灵;选择框资源定为 2x2 四帧
  (单选未选/单选选中/复选未选/复选选中),帧号 =
  (useCheckbox?3:1)+(selected?1:0);类别标题一张图 3 帧。
  整个界面由「类别→选项组→选项」配置数据驱动渲染,渲染代码不认识
  具体玩法名,roomtype 靠每项自带的 bit 拼串。同样改精灵复制,
  编辑器只建 4 个精灵(原预置方案需 21 个)。

- 新增「预置 vs 精灵复制」的选用判据表,并据此标出下一个候选:
  已出牌区 84 个预置精灵(T-29,需先确认复制精灵满足 z 序与出牌动画)。

- 新增 T-29 / T-30。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-25 08:23:25 +08:00
co-authored by Claude Opus 5
parent ddb4f7d6a2
commit 766ef7eae3
+190 -56
View File
@@ -158,11 +158,12 @@ get_nextseat: function(seat){ return (seat + 1) % 3; }
| 1650–1699 | 选主 / 投降面板 | ~21 |
| 1700–1749 | 埋牌 / 出牌操作条 | ~8 |
| 1750–1799 | 桌面浮层(气泡 / 飘字 / 报无主 / 甩错) | ~15 |
| 1800–1899 | 小局结算 | ~30 |
| 1800–1819 | 小局结算面板 | ~20 |
| 1820–1829 | 算奖牌型叠加层(**精灵复制**:遮罩 1 + 容器 3 + 模板 1 + 奖数 3) | **8** |
| 1900–1949 | 大局总结算 / 解散结算 | 待设计 |
| 1950–1999 | 出牌历史面板 | 待设计 |
| 2000–2049 | 明牌面板 | 待设计 |
| 2050–2099 | 建房规则选项 | ~20 |
| 2050–2099 | 建房规则选项(**精灵复制**:容器 1 + 模板 3) | **4** |
| 2100–2999 | **预留** | —— |
#### 图片资源(Image,≥501)
@@ -279,25 +280,60 @@ var CARD_BACK_FRAME = 55; // 牌背(二七王固定用牌背
> ⚠️ 参考图是**另一个游戏**的建房选项(局数 8/16/24、人数 2/3/4、霸王 ×2/×4 等,二七王都没有)。
> 如文件名所示:**只照搬视觉范式与控件样式,内容一律按二七王的 `roomtype` 重写**。
#### 视觉范式(照搬)
#### 结构模型:类别标题 + 选项组
- **行式布局**:每行 = 左侧标题(青绿色粗体,右对齐)+ 右侧若干选项,等距分布。
- **两种控件**:
- **单选圆钮**:`◉` 选中(橙色实心圆环)/ `◯` 未选中(灰色空心圆环);**选中项的文字同步变橙色**。
- **多选方框**:`▣` 浅绿方块,选中/未选中两态。
- **附注文字**:灰色小字跟在同一行末尾(参考图的 `【3张/人】`),二七王用来显示房卡消耗。
- 多选行可折行(参考图「玩法」行为 2 行 × 4 列)。
界面由**类别**纵向堆叠而成,每个类别是「类别标题 + 若干选项组」:
```
[类别标题] 选项组1 选项组2 …
牌局 ◉6局 ◯12局 ◉房主扣卡 ◯AA每人 【2张】
模式 ◉可查牌 ◯不查牌
规则 ▣傍王 ▣爬坡
```
**选项组有三种类型**(这是通用控件规格,不只为二七王):
| 类型 | 语义 | 用的选择框图 |
| --- | --- | --- |
| **单选** | 组内必选其一,互斥 | 单选(圆钮) |
| **多选** | 组内各项独立开关,可全不选、可全选 | 复选(方框) |
| **单选(可不选)** | 组内至多选一,也可一个都不选 | **复选(方框)**——因为它需要能表达「全不选」,视觉上不适合用单选圆钮 |
**每个选项 = 选择框(图片精灵)+ 文字精灵**,两者成对出现。
**选择框图片资源为 2 × 2 = 4 帧**:
| 帧 | 内容 |
| --- | --- |
| 1 | 单选 · 未选中 |
| 2 | 单选 · 已选中 |
| 3 | 复选 · 未选中 |
| 4 | 复选 · 已选中 |
帧号计算:`frame = (useCheckbox ? 3 : 1) + (selected ? 1 : 0)`,其中 `useCheckbox = (类型 === 多选 || 类型 === 单选可不选)`。
**类别标题放在一张图上多帧**,一个标题一帧:
| 帧 | 内容 |
| --- | --- |
| 1 | 牌局 |
| 2 | 模式 |
| 3 | 规则 |
其余视觉细节照搬参考图:标题青绿粗体、选中项文字变橙、灰色小字附注(参考图的 `【3张/人】`,二七王用来显示房卡消耗)、选项多时可折行。
#### 内容(二七王实际,对应 `roomtype` 5 位,协议 §0.5)
| 行 | 标题 | 控件 | 选项 | `roomtype` 位 | design |
| 类别(帧) | 选项组 | 类型 | 选项 | `roomtype` 位 | design |
| --- | --- | --- | --- | --- | --- |
| 1 | 局数 | 单选 | **6 局** / 12 局 | 位 0 | §10.1 |
| 2 | 扣卡 | 单选 | **房主扣卡** / AA 每人扣卡 + 附注房卡数 | 位 1 | §10.1 |
| 3 | 玩法 | **多选** | 傍王、爬坡(两者可同时勾选,互不冲突) | 位 2、位 3 | §8.3 / §7.3 / §10.3 |
| 4 | 查牌 | 单选 | **可查牌** / 不查牌 | 位 4 | §9 / §10.2 |
| **牌局**(帧1) | 局数 | 单选 | **6 局** / 12 局 | 位 0 | §10.1 |
| **牌局**(帧1) | 扣卡 | 单选 | **房主扣卡** / AA 每人扣卡 + 附注房卡数 | 位 1 | §10.1 |
| **模式**(帧2) | 查牌 | 单选 | **可查牌** / 不查牌 | 位 4 | §9 / §10.2 |
| **规则**(帧3) | 附加规则 | **多选** | 傍王、爬坡(可同时勾选,互不冲突) | 位 2、位 3 | §8.3 / §7.3 / §10.3 |
(加粗为缺省值,即 `roomtype = "00000"`。)
(加粗为缺省值,即 `roomtype = "00000"`。三个类别正好对应 design §10.1 / §10.2 / §10.3 三个小节。)
**二七王当前用不到「单选(可不选)」**——四个选项组里三个是单选、一个是多选。该类型仍须在控件层实现,供后续玩法与模板克隆使用。
**没有「人数」行**——二七王固定 3 人(design §2),不给玩家选。参考图里的「人数」「霸王」两行**不要照抄**。
@@ -311,11 +347,37 @@ var CARD_BACK_FRAME = 55; // 牌背(二七王固定用牌背
#### 实现要点
- 交互:点击平台约定的 25 号精灵 → 拼 `roomtype` 串 → `Net.Send_create_room({agentid, playerid, gameid, roomtype})`。
- 精灵:群组 250,号段 2050–2099;挂在平台创建房间界面所在图层(T-3)。
- 资源:单选圆钮(2 帧)、多选方框(2 帧)、行底/标题文字。
- **`roomtype` 的拼串必须只在一处实现**——与服务端 `class.config.js` `parse()` 对称的 SSOT 要求,不得在多处按下标硬拼。
- 精灵:群组 250,号段 2050–2099;挂在平台创建房间界面所在图层(T-3)。**用精灵复制生成**(见 §5.8)。
- 资源:选择框(4 帧)、类别标题(3 帧)。
- **整个界面由一份「类别 → 选项组 → 选项」的配置数据驱动渲染**,不为每个选项写死代码。加一个选项 = 配置里加一条,不改渲染逻辑(工程总则 §5 OCP、§6 配置优先)。
- **`roomtype` 的拼串必须只在一处实现**——与服务端 `class.config.js` `parse()` 对称的 SSOT 要求,不得在多处按下标硬拼。每个选项在配置里自带 `bit` 与 `value`,拼串就是遍历配置,无需按下标硬编码。
- 房卡数**不要硬编码在 UI 代码里**,做成「局数 × 扣卡方式 → 房卡数」的配置表(工程总则 §6)。
配置数据形态(示意,落地位置见 §6.10):
```js
EQW_RoomOptions = {
categories: [
{ titleFrame: 1, /* 牌局 */ groups: [
{ key: 'aset', type: 'radio', bit: 0,
items: [ {label:'6局', value:'0'}, {label:'12局', value:'1'} ] },
{ key: 'card', type: 'radio', bit: 1, note: 'cardCost',
items: [ {label:'房主扣卡', value:'0'}, {label:'AA每人扣卡', value:'1'} ] }
]},
{ titleFrame: 2, /* 模式 */ groups: [
{ key: 'peek', type: 'radio', bit: 4,
items: [ {label:'可查牌', value:'0'}, {label:'不查牌', value:'1'} ] }
]},
{ titleFrame: 3, /* 规则 */ groups: [
{ key: 'rules', type: 'checkbox',
items: [ {label:'傍王', bit:2}, {label:'爬坡', bit:3} ] } // 多选:bit 落在每一项上
]}
]
};
```
> `type` 取 `'radio'` / `'checkbox'` / `'radioOptional'`(单选可不选)。选择框帧号由 `type` 推出,见上文公式——**渲染代码不认识「傍王」「爬坡」这些具体玩法**,只认识三种控件类型,这样框架侧保持游戏中立、子游戏只提供配置。
### 1.2 发牌 `fapai` 【图:等待叫分.png】
**收包字段**:`asetidx`(当前局数)、`asetcount`(总局数)、`cards`(自己 28 张)、`seat`(当前等待叫分者)、`countdown`。
@@ -538,12 +600,35 @@ var CARD_BACK_FRAME = 55; // 牌背(二七王固定用牌背
| `算奖牌型`(蓝色) | 中央偏左 | 打开算奖牌型叠加层(见下) |
| `下一局`(金黄) | 中央偏右 | 发 `zhunbei { seat }` 进入下一局(§1.12) |
#### 「冲关」是什么(`chongguan` 字段的准确定义)
服务端 `class.arith.js:1277` `get_chongguan(mainflower, cards)`。**「冲关」就是 design §8.1「常规算奖」的服务端命名**——`chongguan` 的值即该玩家常规算奖的**奖数**,不是另一套独立规则。函数返回三项:
| 返回字段 | 含义 | 去向 |
| --- | --- | --- |
| `count` | 关数 = 常规算奖奖数 | `aset.seatlist[i].chongguan` |
| `wang` | 手牌中的王数 | `aset.seatlist[i].wang`(傍王按此计奖) |
| `cards` | **王牌 + 所有参与冲关的牌**,已按主牌序从大到小排好 | `aset.seatlist[i].cards` → **算奖牌型叠加层要显示的就是它** |
计数规则(与 design §8.1 逐条对应):
1. **前置**:`cards.length < 28` 直接返回 0 —— 手牌不足 28 张不参与算奖。
2. **三王 / 四王**:≥3 王 → `count = 1`;= 4 王 → `count = 3`。
3. **连对链续奖**:**必须先满足 ≥3 王**(整段逻辑在 `if (_wlist.length >= 3)` 内)。从小王编码 `9553` 起,沿主牌序往下逐对扫描,每遇到一个与上一节**位置相邻**的对子就 `count + 1`,链条为 `正7 → 副7 → 正2 → 副2 → 主A → 主K → …`,断则止。**没有三王就没有连对链奖**。
4. **六/七/八个 7**:`count += 张数 − 5`(6→1、7→2、8→3 奖)。
5. **六/七/八个 2**:同上。
6. **固定主牌 ≥10 张不算奖**——它只触发 design §8.2 的「亮牌」,代码里有明确注释。§1.6 的亮牌与这里的算奖是两回事。
> 前端**不重算冲关**,`chongguan` / `wang` / `naward` / `cards` 一律直接取服务端下发值(服务端权威,红线)。上面的规则只用于理解要显示什么。
**算奖牌型叠加层** 【图:算奖牌型显示.png】:
点 `算奖牌型` 后,在结算面板之上盖一层**半透黑遮罩**,三家各展示自己的算奖相关牌(`aset.seatlist[i].cards`,即王 / 冲关牌),资源用 `CARD_FACE_L`、重叠排列。`下一局` 按钮在遮罩层上**继续可见可点**,`算奖牌型` 按钮本身被遮住。再点一次或点遮罩空白处关闭【待确认 T-22:关闭方式】。
点 `算奖牌型` 后,在结算面板之上盖一层**半透黑遮罩**,三家各展示自己的 `aset.seatlist[i].cards`,资源用 `CARD_FACE_L`、重叠排列。`下一局` 按钮在遮罩层上**继续可见可点**,`算奖牌型` 按钮本身被遮住。再点一次或点遮罩空白处关闭【待确认 T-22:关闭方式】。
- 三家牌位:左上家、右上家在各自头像内侧;自己在中央偏下。
- 布局配置见 §6.6。
- 布局配置见 §6.7。
**牌用精灵复制生成,不预置固定数量**(见 §5.6a):`cards` 的张数**没有小上限**——四王 + 一条长连对链 + 八个 7 + 八个 2 叠加时可达 20 余张。预置精灵既会不够用,又在绝大多数局里白占 ID。
**`aset` 其余字段的用途**:
@@ -798,8 +883,8 @@ y≈648–720 深色条。左侧头像/昵称/分数由平台渲染(§0.2)
| ID | 键名 | 用途 | 帧数 | 帧说明 | 尺寸 |
| --- | --- | --- | --- | --- | --- |
| 681 | `RADIO_ROOM_OPT` | 建房**单选**圆钮(局数 / 扣卡 / 查牌) | 2 | 帧1=未选(灰色空心环) 帧2=已选(橙色实心环) | 22 × 22 |
| 682 | `CHECKBOX_ROOM_OPT` | 建房**多选**方框(玩法:傍王 / 爬坡) | 2 | 帧1=未选(浅绿空方块) 帧2=已选 | 20 × 20 |
| 681 | `ROOM_OPT_BOX` | 建房**选择框**(单选钮 + 复选框合一) | **4**(2×2) | **帧1=单选·未选中(灰空心环) 帧2=单选·已选中(橙实心环) 帧3=复选·未选中(浅绿空方块) 帧4=复选·已选中**。帧号 = `(useCheckbox ? 3 : 1) + (selected ? 1 : 0)`;「单选(可不选)」用复选帧 3/4 | 22 × 22 |
| 682 | `ROOM_CAT_TITLE` | 建房**类别标题**(一张图多帧) | **3** | 帧1=牌局 帧2=模式 帧3=规则 | 60 × 24 |
| 683 | `ROW_ROOM_OPT` | 选项行底(可选,参考图为无底透明) | 1 | —— | 待定 |
---
@@ -961,18 +1046,54 @@ design 与协议均**未定义任何音效**。以下是按牌类游戏常规推
> 底牌 8 张精灵复用 §5.3 群组 215(1258–1265),不在此重复。
**算奖牌型叠加层**(同 Layer 302,独立群组 **244**,可与群组 240 分别显隐):
### 5.6a 算奖牌型叠加层(Layer 302,群组 **244**,**精灵复制**)
**本层的牌用 `SpriteCopyUtils` 运行时复制,不预置固定张数。** `aset.seatlist[i].cards` 的长度不定(四王 + 长连对链 + 八个 7 + 八个 2 可达 20 余张),预置既可能不够、又在多数局里白占 ID。
**只需在编辑器里建 5 个精灵**(3 个容器 + 1 个牌模板 + 1 个遮罩):
| 精灵 ID | 键名 | 类型 | 用途 | 资源 / 帧 |
| --- | --- | --- | --- | --- |
| 1820 | `AWARD_MASK` | 图片 | 半透黑遮罩(拉伸满屏,兼作点击关闭热区) | `MASK_DIM` |
| 1821–1828 | `AWARD_CARD_LEFT_1..8` | 图片 ×8 | 左上家算奖牌 | `CARD_FACE_L` |
| 1831–1838 | `AWARD_CARD_RIGHT_1..8` | 图片 ×8 | 右上家算奖牌 | `CARD_FACE_L` |
| 1841–1848 | `AWARD_CARD_SELF_1..8` | 图片 ×8 | 自己算奖牌 | `CARD_FACE_L` |
| 1851–1853 | `AWARD_COUNT_LEFT/RIGHT/SELF` | 文字 ×3 | 奖数 `naward` 等【T-23】 | —— |
| 1821 | `AWARD_BOX_LEFT` | **容器** | 左上家算奖牌容器(复制的父精灵) | —— |
| 1822 | `AWARD_BOX_RIGHT` | **容器** | 右上家算奖牌容器 | —— |
| 1823 | `AWARD_BOX_SELF` | **容器** | 自己算奖牌容器 | —— |
| 1824 | `AWARD_CARD_TPL` | **模板** | 算奖牌模板(编辑器里放好、默认隐藏,只作样式来源) | `CARD_FACE_L` |
| 1825–1827 | `AWARD_COUNT_LEFT/RIGHT/SELF` | 文字 ×3 | 奖数 `naward` 等【T-23】 | —— |
> 每家预置 **8** 张:常规算奖的最大组合是「四王 + 连对链」,8 张足以覆盖典型展示;若 `cards` 超过 8 张需缩距或分行【待确认 T-24】。
> `RESULT_BTN_NEXT`(1817/1818)在遮罩层之上仍需可见可点 —— 其图层内层级须高于 `AWARD_MASK`。
**生成方式**:
```js
// 每个座位一个容器,tag 用牌在 cards 里的下标(父精灵内唯一即可)
var pos = LayoutSolver.solve(EQW_Layout.AWARD_CARDS, seatKey, cards.length); // fan 布局,见 §6.7
for (var i = 0; i < cards.length; i++) {
var sid = SpriteCopyUtils.create(boxId, sprites.AWARD_CARD_TPL, pos[i].x, pos[i].y, i);
SpriteManager.setFrame(sid, cardIdToFrame(cards[i])); // §0.4
}
```
**清理是硬要求**:关闭叠加层 / 组件 `onDestroy` 时必须 `SpriteCopyUtils.removeRange(boxId, 0, cards.length)`,否则复制精灵残留(client 02 §6)。
> `RESULT_BTN_NEXT`(1817/1818)在遮罩之上仍需可见可点 —— 其图层内层级须高于 `AWARD_MASK`。
#### 预置 vs 精灵复制的选用判据
| 判据 | 预置固定精灵 | 精灵复制 |
| --- | --- | --- |
| 数量 | 有明确且不大的上限 | 上限不定或很大 |
| 常态占用率 | 多数时候都在用 | 多数时候只用极少几个 |
| 逐个控制 | 需要独立 z 序 / 动画 / 命名引用 | 只需批量摆位 + 设帧 |
| 清理成本 | 无 | 必须显式 `remove`,忘了就残留 |
据此,本清单的选用:
| 区域 | 方式 | 理由 |
| --- | --- | --- |
| 自己手牌(36) | **预置** | 上限确定;需逐张选中上浮、独立动画与点击 |
| 暗牌(8)/ 底牌(8) | **预置** | 固定 8 张 |
| **算奖牌型** | **复制** | 张数不定、多数局用不满 |
| **建房规则选项** | **复制** | 选项由配置驱动、随游戏变(模板项目复用性),见 §5.8 |
| 已出牌区(28 × 3 = 84) | 预置(**待复议 T-29**) | 84 个精灵里绝大多数时候只用 1–4 个,是下一个适合改复制的候选;但出牌有叠压 z 序与出牌动画需求,改前需确认复制精灵能满足 |
### 5.7 Layer 303–306 · 其余弹窗 【待设计】
@@ -983,24 +1104,33 @@ design 与协议均**未定义任何音效**。以下是按牌类游戏常规推
| 305 | 243 | 2000–2049 | 明牌面板:另两家未出主牌的具体牌面 |
| 306 | —— | —— | 解散投票【T-2:是否平台提供】 |
### 5.8 建房规则选项(群组 250,2050–2099)
### 5.8 建房规则选项(群组 250,**精灵复制**)
**4 行**(局数 / 扣卡 / 玩法 / 查牌,§1.1),不是 5 行——傍王与爬坡合并在「玩法」多选行里。
界面由 §1.1 的配置数据驱动渲染,**类别数与选项数随配置变**(模板项目克隆到新游戏时 `roomtype` 位数不同)。因此用 `SpriteCopyUtils` 复制生成,**编辑器里只建 4 个精灵**:
| 精灵 ID | 键名 | 类型 | 用途 | 资源 / 帧 |
| --- | --- | --- | --- | --- |
| 2050–2053 | `ROOM_ROW_TITLE_1..4` | 文字 ×4 | 行标题(局数/扣卡/玩法/查牌),青绿粗体 | —— |
| 2054–2055 | `ROOM_RADIO_ASET_1..2` | 图片 ×2 | 局数单选钮(6局 / 12局) | `RADIO_ROOM_OPT` |
| 2056–2057 | `ROOM_RADIO_ASET_TEXT_1..2` | 文字 ×2 | 选项文字(选中变橙) | —— |
| 2058–2059 | `ROOM_RADIO_CARD_1..2` | 图片 ×2 | 扣卡单选钮(房主 / AA) | `RADIO_ROOM_OPT` |
| 2060–2061 | `ROOM_RADIO_CARD_TEXT_1..2` | 文字 ×2 | 选项文字 | —— |
| 2062 | `ROOM_CARD_COST_TEXT` | 文字 | 房卡消耗附注(灰色小字,随局数×扣卡联动) | —— |
| 2063–2064 | `ROOM_CHECK_RULE_1..2` | 图片 ×2 | 玩法多选框(傍王 / 爬坡) | `CHECKBOX_ROOM_OPT` |
| 2065–2066 | `ROOM_CHECK_RULE_TEXT_1..2` | 文字 ×2 | 选项文字 | —— |
| 2067–2068 | `ROOM_RADIO_PEEK_1..2` | 图片 ×2 | 查牌单选钮(可查 / 不查) | `RADIO_ROOM_OPT` |
| 2069–2070 | `ROOM_RADIO_PEEK_TEXT_1..2` | 文字 ×2 | 选项文字 | —— |
| 2050 | `ROOM_OPT_BOX_CONTAINER` | **容器** | 所有类别标题 / 选择框 / 文字的复制父精灵 | —— |
| 2051 | `ROOM_CAT_TITLE_TPL` | **模板** | 类别标题模板(默认隐藏) | `ROOM_CAT_TITLE`,帧 = 类别序号 |
| 2052 | `ROOM_OPT_BOX_TPL` | **模板** | 选择框模板(默认隐藏) | `ROOM_OPT_BOX`,帧见 §1.1 公式 |
| 2053 | `ROOM_OPT_TEXT_TPL` | **模板** | 选项文字模板(默认隐藏,兼作房卡附注) | —— |
共 21 个精灵。挂在平台创建房间界面所在图层(T-3)。布局配置见 §6.12。
**tag 分配**用框架的 `SpriteCopyUtils.createTagManager` 分段,避免三类复制精灵 tag 撞车:
```js
var tagMgr = SpriteCopyUtils.createTagManager({
title: { start: 1, size: 100 }, // 类别标题
box: { start: 101, size: 200 }, // 选择框
text: { start: 301, size: 200 } // 选项文字 + 附注
});
```
**点击命中**用 `SpriteCopyUtils.hitTest(containerId, e.offsetX, e.offsetY)` 拿到 tag,再由 tag 反查是哪个 `{类别, 选项组, 选项}`——**这层映射表在渲染时一并建好**,不靠 tag 算术反推。
**清理**:关闭建房界面时 `SpriteCopyUtils.removeRange` 清掉三段 tag。
> 挂在平台创建房间界面所在图层(T-3)。布局配置见 §6.9b。
> 只占 4 个精灵 ID(原预置方案需 21 个),且加选项不用回编辑器加精灵。
---
@@ -1211,7 +1341,7 @@ CARD_SIZE: {
| **已出牌区** | `fan` | 见 §6.2 的 `bySeat` 示例(三家共用 base,LEFT 镜像) |
| 已出牌 · 牌型标签 | `attach` | `target:该区首张牌, corner:bottomLeft, offsetX:0, offsetY:-24` |
| 已出牌 · 牌角 `庄`/`大` 标 | `attach` | `target:对应牌, corner:topRight, offsetX:-28, offsetY:0` |
| **算奖牌(叠加层)** | `fan` | `size:L spacingMax:-40 spacingMin:-70 maxWidth:260`;`bySeat{ LEFT:{anchorX:260,anchorY:120}, RIGHT:{anchorX:1035,anchorY:120}, SELF:{anchorX:640,anchorY:400} }` |
| **算奖牌(叠加层)** | `fan` | `size:L spacingMax:-40 spacingMin:-88 maxWidth:420`;`bySeat{ LEFT:{anchorX:260,anchorY:120}, RIGHT:{anchorX:1035,anchorY:120}, SELF:{anchorX:640,anchorY:400} }`。**精灵复制**(§5.6a):求解结果直接作为 `SpriteCopyUtils.create` 的 `x/y`(相对容器)。`spacingMin` 放宽到 `-88`(即最窄只露 22px)以容纳 20+ 张的极端情况 |
### 6.8 阶段操作区配置
@@ -1247,27 +1377,29 @@ CARD_SIZE: {
| `下一局` 按钮 | `point` | `x:835 y:518 w:180 h:65` |
| 算奖遮罩 | `point` | `x:0 y:0 w:1280 h:720`,`opacity:0.72`(透明度也是配置项) |
### 6.9b 建房规则选项配置(§1.1)
### 6.9b 建房规则选项配置(§1.1,精灵复制)
参考图是**行式等距**结构,正好用 `line` 嵌套 `line`:外层竖排行,内层每行横排选项。
布局是**两层嵌套**:类别竖排,类别内的选项组横排。复制精灵的坐标是**相对容器**的偏移,`LayoutSolver` 求解后直接作为 `SpriteCopyUtils.create(parentId, tplId, x, y, tag)` 的 `x/y`。
| 部件 | kind | 参数(按参考图比例估,实际以平台建房界面尺寸为准) |
| --- | --- | --- |
| 行容器(4 行) | `line` | `direction:vertical, anchorX:0, anchorY:0, itemHeight:32, spacing:8, anchor:left` |
| 行标题 | `attach` | `target:所在行, hAlign:left, vAlign:middle, offsetX:0`,`textStyle{fontSize:18, color:'#7FBFB0', bold:true, align:right, maxWidth:60}` |
| 行内选项组 | `line` | `direction:horizontal, anchorX:70, itemWidth:150, spacing:0, anchor:left`(`itemWidth` 即每个「圆钮+文字」的槽宽) |
| 单选钮 / 多选框 | `attach` | `target:所在选项槽, hAlign:left, vAlign:middle` |
| 选项文字 | `attach` | `target:同槽的钮, hAlign:right, vAlign:middle, offsetX:8` |
| 房卡附注 | `attach` | `target:扣卡行最后一个选项, hAlign:right, vAlign:middle, offsetX:20`,`textStyle{fontSize:16, color:'#999999'}` |
| 多选行折行 | `grid` | 若「玩法」选项超过一行,改用 `grid{cols:4, spacingX:0, spacingY:8, fillOrder:'row'}`(二七王只有 2 项,单行即可) |
| 类别(竖排) | `line` | `direction:vertical, anchorX:0, anchorY:0, itemHeight:32, spacing:8, anchor:left`;`itemHeight` 为**单行**类别高,折行类别按实际行数累加 |
| 类别标题 | `attach` | `target:所在类别行, hAlign:left, vAlign:middle, offsetX:0`;`ROOM_CAT_TITLE` 帧 = 类别序号 |
| 类别内选项槽(横排) | `line` | `direction:horizontal, anchorX:70, itemWidth:150, spacing:0, anchor:left`(`itemWidth` = 一个「选择框 + 文字」的槽宽) |
| 选项组之间的额外间隔 | —— | `groupGap: 40`(同类别下两个选项组之间比组内选项多留的间距,配置项) |
| 选择框 | `attach` | `target:所在选项槽, hAlign:left, vAlign:middle` |
| 选项文字 | `attach` | `target:同槽的选择框, hAlign:right, vAlign:middle, offsetX:8` |
| 房卡附注 | `attach` | `target:扣卡组最后一个选项, hAlign:right, vAlign:middle, offsetX:20`,`textStyle{fontSize:16, color:'#999999'}` |
| 折行 | `grid` | 选项数超过 `maxPerRow` 时改用 `grid{cols:maxPerRow, spacingX:0, spacingY:8, fillOrder:'row'}`;`maxPerRow: 4`(配置项,参考图「玩法」行即 4 列折 2 行)。二七王每组最多 2 项,不会触发 |
**选中态是配置驱动的**:单选钮选中时文字变橙,颜色写进配置:
**文字选中态也是配置**(单选选中时文字变橙):
```js
ROOM_OPT_TEXT: {
normal: { fontSize: 18, color: '#DDDDDD' },
selected: { fontSize: 18, color: '#E8873A' }
}
},
ROOM_CAT_TITLE_STYLE: { fontSize: 18, color: '#7FBFB0', bold: true, align: 'right', maxWidth: 60 }
```
不要在代码里写死 `'#E8873A'`。
@@ -1349,12 +1481,14 @@ codes/config/
| **T-20** | **整套音效**:清单、是否需要语音包、是否分男女声 | §4 全节 |
| **T-21** | 手牌 `fan` 的 `spacingMin` / `spacingMax` 具体取值(36 张时最大重叠量) | §6.7 配置值 |
| **T-22** | 算奖牌型叠加层的关闭方式(再点按钮 / 点遮罩 / 独立关闭钮) | §1.8 交互 |
| **T-23** | 算奖叠加层是否并列显示奖数(`chongguan` / `wang` / `naward`) | 精灵 1851–1853 是否需要 |
| **T-24** | 算奖牌 `cards` 超过 8 张时怎么排(缩距 / 分行 / 预置更多精灵) | §5.6 精灵数 |
| **T-23** | 算奖叠加层是否并列显示奖数(`chongguan` / `wang` / `naward`) | 精灵 1825–1827 是否需要 |
| ~~T-24~~ | ~~算奖牌 `cards` 超过 8 张时怎么排~~ | **已定论**:改用**精灵复制**(§5.6a),张数不设上限,`fan` 自适应压缩 |
| **T-25** | `line` 布局器是否需要支持「逐项不等宽」(底栏功能钮组、埋牌操作条) | §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-29** | 已出牌区(28 × 3 = 84 个预置精灵)是否也改精灵复制?需先确认复制精灵能满足叠压 z 序与出牌动画 | §5.6a 判据表;可省 ~80 个精灵 ID |
| **T-30** | 建房界面的整体位置与可用尺寸(依赖平台创建房间界面,与 T-3 同源) | §6.9b 的 anchor 起点 |
### 7.3 开发前置条件