Files
erqiwang_youle/client/js/01_SubGame/codes/config/Sprites_Action.js
T
joywayerandClaude Opus 5 8f36b61620 二七王:补齐三处配置缺口(扣底按钮 / 出牌提示按钮槽位 / 三个 View 的布局节点)
这三处都是「精灵或按钮已在清单里定案,但配置层缺东西」,不补的话 C/D/E 阶段
写渲染代码时会发现没有布局节点,极易就地硬编码坐标(违反零裸值红线)。

1) 底栏「扣底」按钮没有精灵(清单 §2.6 列了 5 个功能按钮,只登记了 4 个)
   - 新增 BTN_BURY_CARDS(1056) / BTN_BURY_CARDS_TEXT(1057),群组 205 号段内空闲号,
     资源沿用 BTN_BOTTOM_FUNC,与其余四个按钮同构。
   - FOOTER_FUNC_BUTTONS 的 items 由 4 项扩到 5 项,扣底紧邻底牌(照 §2.6 表序)。
     扣底宽 78 是【估值】:清单未给,取同为两字按钮的「底牌」实测值,已在配置与清单里注明。
   - 扣底看【埋牌底牌】(burycards)、底牌看【底牌】(bottomcards),两批不同的牌,
     JSDoc 里补了防写反的提示(对应验收清单第 13 条)。

2) 出牌阶段「提示」按钮有精灵、无布局槽位
   - PLAY_OPERATION_BAR.items 补上 PLAY_BTN_TIP,顺序照清单 §1.7 行文:倒计时 / 出牌 / 提示。
   - 宽 180 是【估值】:清单 §6.8 自身漏了该项;与埋牌条的提示按钮同资源 BTN_TIP
     (§3.3 实测 180×63),埋牌条 items 首项亦取 180,故沿用。
   - 顺带记下一处待裁定项:本条 itemHeight 为 55(对齐 BTN_PLAY 157×55),
     而 BTN_TIP 原生高 63,高度差待设计稿定。

3) AccountView / HistoryView / MingPaiView 一个布局节点都没有
   - AccountView(§6.9a 新增):外壳 6 个节点 + 玩家栏「容器 ACC_ROW_CONTAINER +
     行节点 ACC_ROW(itemHeight 即行高,行数由 ctx.count 给出)+ 行内模板贴附到行矩形」
     + 面板外 4 按钮,共 14 个节点。行内节点求出的是相对容器的坐标,可直接喂
     SpriteCopyUtils.create(与 §5.6a 冲关牌同一用法)。
   - HistoryView / MingPaiView(§6.9c 新增):遮罩 + 容器 + 每家一排牌(fan) + 座位标签,
     各 4 个节点。照 CHONGGUAN_FAN 同构、锚点沿用 §6.7 冲关牌的三家落点;
     差别只在张数上限——出牌历史摊平后可达 28 张以上,故 maxWidth 放宽到 500、
     spacingMin 收到 -96【估值】。MING_* 只有 LEFT/RIGHT 两个 bySeat 变体(明牌不看自己)。
   - 坐标来源:大局结算.png / 冲关牌型显示.png 目视实测,w/h 取资源尺寸;
     配置与清单里均已注明「目视实测估值,待设计稿复核」。
   - 运行时才确定的字段(动态文字宽高、随行浮动的 anchorY、数字精灵宽)一律
     runtime 显式声明。

钉死断言按实际重新数并更新:精灵总数 378 → 380,布局节点总数 61 → 83。
另把 ACC_TPL_SCORE_NUM 加进 NUM_STYLE 同源校验表(与 RESULT_SCORE_NUM 同一套资源)。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 08:40:48 +08:00

533 lines
36 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
///////////////////////////////////////////////////////////////
////////// EQW_Sprites: 精灵结构(清单 §5.4/§5.5 阶段操作区与浮层)
///////////////////////////////////////////////////////////////
// 子游戏精灵段 1001–2999。结构与 Sprites_Table.js 一致:
// View 下 Layer 为图层声明(一个 View 恰好一个图层),其余键是 group 容器;
// 容器内 id 为群组 ID、其余键才是精灵 id。
// 连号精灵逐条写全,不用循环生成。
var EQW_Sprites = EQW_Sprites || {};
// ============================================================================
// 叫分面板 - Layer 104 (ACTION), Group 220 (CALL_PANEL)
// ============================================================================
/**
* 叫分面板 - CallPanelView
*
* 用途: 轮到【自己】叫分时在桌面中央弹出,14 个档位按钮(两行 × 7)+「不叫」按钮 +
* 上方一条静态提示条。收到 jiaofen 推送后收起。轮到他家叫分时本面板不出现。
*
* 布局说明(参考图 docs_dev/uiref/自己叫分.png 全景、docs_dev/uiref/叫分按钮面板.png 近景):
*
* ┌──────────────────────────────┐ y=100 x=470,345×33
* │ 70分坐庄才可投降 │ ← CALL_HINT_BG(1601)
* └──────────────────────────────┘ y=133 +CALL_HINT_TEXT(1602)
* ┌────────────────────────────────────────────────────────────┐ y=140
* │ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ │ x=355
* │ │70│ │65│ │60│ │55│ │50│ │45│ │40│ ← 行1 = 档位 1–7 │ 575×170
* │ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ │
* │ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ │
* │ │35│ │30│ │25│ │20│ │15│ │10│ │5 │ ← 行2 = 档位 8–14 │
* │ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ │
* └────────────────────────────────────────────────────────────┘ y=310
* ↑ CALL_PANEL_BG(1600) 面板底
* 档位排布 EQW_Layout.CALL_BTN_GRID: grid, anchor center, anchorX=640 anchorY=160,
* cols=7 rows=2, itemWidth=74 itemHeight=56, spacingX=7 spacingY=24, fillOrder='row'
*
* 12 ┌──────────────┐ y=345
* ↑ │ 不 叫 │ x=553, 184×57
* CD_SELF └──────────────┘ y=402
* (CountdownView, ↑ CALL_BTN_NONE(1645)+CALL_BTN_NONE_TEXT(1646)
* EQW_Layout.P_COUNTDOWN.SELF = 445,345)
*
* 单个档位按钮由【3 个精灵】叠成(第 n 档 n=1..14):
*
* ┌───────────────┐
* │ ┌────┐│ ← CALL_BTN_BADGE_n (1631+n-1) 文字精灵,随爬坡开关变
* │ │2子 ││ EQW_Layout.CALL_BTN_MULTIPLE_BADGE: attach 按钮 topRight(-30,+2)
* │ 70 └────┘│ ← CALL_BTN_NUM_n (1617+n-1) 多帧图数字精灵
* │ │ EQW_Layout.CALL_BTN_SCORE_NUM: attach 按钮 center/middle(+4)
* └───────────────┘
* ↑ CALL_BTN_n (1603+n-1) 按钮底(已含右上角角标底),74×56
*
* 元素说明:
* - 14 档固定为 70 65 60 55 50 45 40 / 35 30 25 20 15 10 5(行1 = 70…40,行2 = 35…5)。
* - 【按钮配色按档位位置写死,不随数据变】:
* 位置 1–4 (70/65/60/55) → 帧1 浅黄底 + 蓝角标底
* 位置 5–7 (50/45/40) → 帧2 金黄底 + 绿角标底
* 位置 8–14 (35…5) → 帧3 橙底 + 深橙角标底
* 不可叫(已被叫过 / 不高于 currcall)→ 帧4 全灰
* ⚠ 参考图里角标写的 1子/2子/4子 是填充假数据(§0.5),恰好与三组配色一一对应,
* 【不要据此以为颜色随子数变】——颜色按位置固定,角标数值才随爬坡开关变。
* 反证:常规算子下 50/45/40 与 35…5 的 multiple 同为 6 子,图里却是两种颜色。
* - 【两种数字,两种精灵】档位分数用多帧图数字精灵(带描边美术字,setNumberImage 整串一个
* 精灵,两位数不拆);角标子数用文字精灵(值域 2–15,随爬坡动态变,用文字最省)。
* - 可选性由服务端权威 currcall 决定,前端只据其置灰、不自行推导规则:
* 暂定庄家首叫 → 5–70 全可选,【无「不叫」】;其后 → 只有严格低于 currcall 的档位可选。
* - 【悲观 UI】点击后只发包(jiaofen {seat, call},不叫为 call:0),面板收起与状态文字
* 出现一律等推送包到达再做;唯一允许的乐观处理是按钮本身防连点禁用。
* - 上方提示条「70分坐庄才可投降」是静态文字,仅在面板展开时显示。
*
* 资源说明:
* - 面板底: EQW_Images.PANEL_CALL_SCORE (602), 1 帧, 575×170
* - 提示条底: EQW_Images.BAR_HINT_TOP (603), 1 帧, 345×33
* - 档位按钮底: EQW_Images.BTN_CALL_SCORE (531), 4 帧, 74×56(含角标底,见上)
* - 档位数字: EQW_Images.NUM_CALL_SCORE (635), 16 帧固定帧序 0123456789.+-x/p,
* 单字符 30×40, 整图 480×40;charWidth 取 EQW_Layout.NUM_STYLE.CALL_SCORE.charWidth
* - 不叫按钮: EQW_Images.BTN_NO_CALL (532), 1 帧, 184×57, 蓝色渐变
*
* 精灵ID分配: 1600–1646(群组 220 号段 1600–1649)
*
* @see docs_dev/二七王-UI资源与精灵清单.md §1.3 叫分坐庄 / §5.4 Layer 104 / §6.8
* @see docs_dev/uiref/自己叫分.png
* @see docs_dev/uiref/叫分按钮面板.png
* @see docs_dev/uiref/自己已经叫分轮到下家叫分.png
*/
//叫分面板:14 档位按钮 + 「不叫」按钮(清单 §5.4,Layer 104 群组 220)
EQW_Sprites.CallPanelView = {
Layer: EQW_Layers.ACTION, //104
CallPanel: {
id: EQW_Groups.CALL_PANEL, //220
CALL_PANEL_BG: 1600, //图片:面板底,资源 EQW_Images.PANEL_CALL_SCORE
CALL_HINT_BG: 1601, //图片:提示条底,资源 EQW_Images.BAR_HINT_TOP
CALL_HINT_TEXT: 1602, //文字:「70分坐庄才可投降」
//—— 14 档位按钮底(含角标底),资源 EQW_Images.BTN_CALL_SCORE,档位 70..5,
// 帧1=浅黄+蓝角标(70/65/60/55) 帧2=金黄+绿角标(50/45/40) 帧3=橙+深橙角标(35..5) 帧4=灰(不可选),
// 颜色按档位位置固定,仅因不可叫切换到灰帧4 ——
CALL_BTN_1: 1603,
CALL_BTN_2: 1604,
CALL_BTN_3: 1605,
CALL_BTN_4: 1606,
CALL_BTN_5: 1607,
CALL_BTN_6: 1608,
CALL_BTN_7: 1609,
CALL_BTN_8: 1610,
CALL_BTN_9: 1611,
CALL_BTN_10: 1612,
CALL_BTN_11: 1613,
CALL_BTN_12: 1614,
CALL_BTN_13: 1615,
CALL_BTN_14: 1616,
//—— 14 档位分数数字(多帧图数字精灵),资源 EQW_Images.NUM_CALL_SCORE(16 帧固定帧序),
// 字符宽见 EQW_Layout.NUM_STYLE.CALL_SCORE.charWidth。
// 显示用 SpriteManager.setNumberImage(spriteId, '70', charWidth):整串交给引擎按字符逐帧渲染、
// 精灵宽度自动按字符数调整,故 14 档(其中 13 档是两位数)各只需【一个】精灵,不拆十位/个位 ——
CALL_BTN_NUM_1: 1617,
CALL_BTN_NUM_2: 1618,
CALL_BTN_NUM_3: 1619,
CALL_BTN_NUM_4: 1620,
CALL_BTN_NUM_5: 1621,
CALL_BTN_NUM_6: 1622,
CALL_BTN_NUM_7: 1623,
CALL_BTN_NUM_8: 1624,
CALL_BTN_NUM_9: 1625,
CALL_BTN_NUM_10: 1626,
CALL_BTN_NUM_11: 1627,
CALL_BTN_NUM_12: 1628,
CALL_BTN_NUM_13: 1629,
CALL_BTN_NUM_14: 1630,
//—— 14 档位 multiple 子数角标文字(「2子」…「15子」),随爬坡规则开关变 ——
CALL_BTN_BADGE_1: 1631,
CALL_BTN_BADGE_2: 1632,
CALL_BTN_BADGE_3: 1633,
CALL_BTN_BADGE_4: 1634,
CALL_BTN_BADGE_5: 1635,
CALL_BTN_BADGE_6: 1636,
CALL_BTN_BADGE_7: 1637,
CALL_BTN_BADGE_8: 1638,
CALL_BTN_BADGE_9: 1639,
CALL_BTN_BADGE_10: 1640,
CALL_BTN_BADGE_11: 1641,
CALL_BTN_BADGE_12: 1642,
CALL_BTN_BADGE_13: 1643,
CALL_BTN_BADGE_14: 1644,
CALL_BTN_NONE: 1645, //图片:「不叫」按钮,资源 EQW_Images.BTN_NO_CALL
CALL_BTN_NONE_TEXT: 1646 //文字:按钮文案「不叫」
}
};
// ============================================================================
// 选主 / 投降面板 - Layer 104 (ACTION), Group 221 (CHOOSE_MAIN)
// ============================================================================
/**
* 选主 / 投降面板 - ChooseMainView
*
* 用途: 庄家上庄后弹出,让庄家在【4 个花色】与【投降】之间二选一(同一决策点、互斥)。
* 只有庄家看得到;两个闲家此时看到的是「等待庄家选主」提示条(OverlayView)。
* 收到 xuanzhu 推送后收起,进入埋牌。
*
* 布局说明(参考图 docs_dev/uiref/亮主.png):
*
* ┌─────────────────────────────────────────┐ y=315 x=330, 425×50
* │ 亮主 20 │ ← MAIN_TITLE_BG(1650) 斜角条
* └─────────────────────────────────────────┘ y=365 +MAIN_TITLE_TEXT(1651)「亮主」
* ↑ ↑
* 标题文字 倒计时 CD_SELF(属 CountdownView,不在本群组)
*
* ┌─────────┐┌─────────┐┌─────────┐┌─────────┐┌─────────┐ y=373 x=330 起
* │ ♠ 2对 ││ ♥ 2对 ││ ♣ 2对 ││ ♦ 2对 ││ 投 降 │ 128×55,间距 9
* │ 6张 ││ 8张 ││ 6张 ││ 7张 ││ │
* └─────────┘└─────────┘└─────────┘└─────────┘└─────────┘ y=428
* ↑ ↑ ↑ ↑
* │ │ └ MAIN_SUIT_BTN_2(1653) … └ MAIN_BTN_SURRENDER(1672)
* │ └ MAIN_SUIT_PAIR_TEXT_n(1668+)「N对」文字精灵,叠在按钮帧内的角标底上
* │ EQW_Layout.MAIN_SUIT_PAIR_BADGE: attach 按钮 topRight(-36,+2), 34×18
* └ MAIN_SUIT_BTN_1(1652):一个精灵一帧就含「按钮底 + 花色图标 + 右上角蓝色角标底」
* 下方 MAIN_SUIT_COUNT_n(1674+)「N张」多帧图数字精灵
* EQW_Layout.MAIN_SUIT_COUNT: attach 按钮 center/bottom(-6)
*
* 排布 EQW_Layout.MAIN_SUIT_LINE: line/horizontal, anchor='left',
* anchorX=330 anchorY=373, itemWidth=128 itemHeight=55, spacing=9
* —— anchor 取 left 是有意的:投降按钮不显示时只排前 4 项,前 4 个位置保持不变。
*
* 元素说明:
* - 花色按钮帧 = 花色序号 1–4,按【服务端 flower 编号】:帧1=方块♦ 帧2=梅花♣
* 帧3=红心♥ 帧4=黑桃♠。⚠ 参考图上 4 个按钮自左向右显示为 ♠♥♣♦,与 flower 编号相反;
* 槽位与帧的对应由渲染代码决定,本文件只登记 4 个精灵、不预设槽位顺序。
* - 「N对」= 该花色的对子数;「N张」= 该花色在庄家手中的总张数(两副牌单花色最多 26 张)。
* 两者都【由前端据自己的 cards 本地统计】,协议明确服务端不额外下发。
* - 「N张」用 SpriteManager.setNumberImage(spriteId, '26张', charWidth) 在【一个】精灵上
* 显示整串,后缀「张」= 资源第 16 帧;不拆十位/个位(2026-08-26 定案,见下方空号说明)。
* - 投降按钮仅 touxiang === 1(即叫分 70)时显示;点它直接跳到结算,不选主、不埋牌、不出牌。
* - 交互:点花色 → xuanzhu { seat, flower };点投降 → touxiang { seat }。收包后才收面板。
* - 【时序】收到 xuanzhu 推送后:顶部信息条「主」列显示花色图标 → 手牌按新主牌集合重排
* (正2/正7 升格为主牌)→ 本面板收起 → 进入埋牌。
*
* 资源说明:
* - 标题斜角条: EQW_Images.BAR_CHOOSE_MAIN (604), 1 帧, 425×50
* - 花色/投降按钮: EQW_Images.BTN_SUIT_CHOOSE (533), 5 帧, 128×55
* 帧1–4 = 四花色按钮(各含按钮底 + 花色图标 + 右上角蓝色角标底);帧5 = 投降按钮(含文字)
* - 张数数字: EQW_Images.NUM_MAIN_SUIT_COUNT (636), 16 帧固定帧序, 单字符 24×32,
* 整图 384×32, 第 16 帧 = 后缀「张」;charWidth 取 NUM_STYLE.MAIN_SUIT_COUNT.charWidth
*
* 精灵ID分配: 1650–1655 / 1668–1672 / 1674–1677(群组 221 号段 1650–1699)
* —— 中间的空号是美术改一张图 5 帧出图后作废的键,逐条追溯见下方原注释。
*
* @see docs_dev/二七王-UI资源与精灵清单.md §1.5 选主·投降 / §5.4 / §6.8
* @see docs_dev/uiref/亮主.png
*/
//选主/投降面板:4 花色按钮 + 投降按钮(清单 §5.4,Layer 104 群组 221)
//
//以下键号在源清单中被显式判定「不需要」,本文件不占用,留空号以便追溯(美术改一张图 5 帧出图,
//花色图标与右上角角标底已并入 BTN_SUIT_CHOOSE 各帧,2026-08-26):
// 1656–1659 MAIN_SUIT_ICON_1..4 —— 花色图标并入 BTN_SUIT_CHOOSE 帧1–4
// 1660–1663 MAIN_SUIT_COUNT_1..4 —— 原文字精灵,改为下方数字图片精灵(键名沿用,ID 改到 1674–1677)
// 1664–1667 MAIN_SUIT_PAIR_BG_1..4 —— 角标底并入 BTN_SUIT_CHOOSE 帧1–4
// 1673 MAIN_BTN_SURRENDER_TEXT —— 「投降」二字并入 BTN_SUIT_CHOOSE 帧5
// 1678–1681 原 MAIN_SUIT_COUNT_3/4_TENS/ONES —— 张数改回「一个花色一个精灵」(多帧图数字,见下:
// SpriteManager.setNumberImage 一个精灵就能显示整串),上一轮的十位/个位拆分作废,
// 空出的 4 个 ID 不复用(2026-08-26)
EQW_Sprites.ChooseMainView = {
Layer: EQW_Layers.ACTION, //104
ChooseMain: {
id: EQW_Groups.CHOOSE_MAIN, //221
MAIN_TITLE_BG: 1650, //图片:「亮主」斜角条,资源 EQW_Images.BAR_CHOOSE_MAIN
MAIN_TITLE_TEXT: 1651, //文字:「亮主」
//—— 4 个花色按钮,资源 EQW_Images.BTN_SUIT_CHOOSE,帧 = 花色序号 1–4(服务端 flower 编号),
// 该帧已含「按钮底 + 花色图标 + 右上角蓝色角标底」——
MAIN_SUIT_BTN_1: 1652,
MAIN_SUIT_BTN_2: 1653,
MAIN_SUIT_BTN_3: 1654,
MAIN_SUIT_BTN_4: 1655,
//—— 4 个对数角标文字:「N对」,叠在对应花色按钮的角标底之上 ——
MAIN_SUIT_PAIR_TEXT_1: 1668,
MAIN_SUIT_PAIR_TEXT_2: 1669,
MAIN_SUIT_PAIR_TEXT_3: 1670,
MAIN_SUIT_PAIR_TEXT_4: 1671,
//—— 4 个花色张数数字精灵(多帧图数字精灵,一花色一个):该花色在庄家手中的张数
// (两副牌单花色最多 26 张,两位数),资源 EQW_Images.NUM_MAIN_SUIT_COUNT(16 帧固定帧序,
// 第16帧=后缀「张」),字符宽见 EQW_Layout.NUM_STYLE.MAIN_SUIT_COUNT.charWidth。
// 显示用 SpriteManager.setNumberImage(spriteId, '26张', charWidth),整串一个精灵搞定,
// 不拆十位/个位(2026-08-26)——
MAIN_SUIT_COUNT_1: 1674,
MAIN_SUIT_COUNT_2: 1675,
MAIN_SUIT_COUNT_3: 1676,
MAIN_SUIT_COUNT_4: 1677,
MAIN_BTN_SURRENDER: 1672 //图片:「投降」按钮,资源 EQW_Images.BTN_SUIT_CHOOSE 帧5(已含底与「投降」字)
}
};
// ============================================================================
// 阶段操作条 - Layer 104 (ACTION), Group 222 (BURY_BAR) / 223 (PLAY_BAR)
// ============================================================================
/**
* 埋牌 / 出牌操作条 - OperationBarView
*
* 用途: 自己该行动时,在手牌区【上方】横排一条操作按钮。两条操作条按阶段【互斥】出现:
* 埋牌条只有庄家在埋牌阶段看得到,出牌条在出牌阶段轮到自己时出现。
* 两条都把倒计时 CD_SELF 排在自己的 items 里,故倒计时随操作条一起移动。
*
* 布局说明(参考图 docs_dev/uiref/庄家埋牌.png = 埋牌条;docs_dev/uiref/出牌.png = 出牌条):
*
* 埋牌操作条(群组 222,EQW_Layout.BURY_OPERATION_BAR)
* line/horizontal, anchor center, anchorX=640 anchorY=165, itemHeight=63, spacing=45
* items 逐项不等宽:BURY_BTN_TIP 180 / CD_SELF 60 / BURY_BTN_SUBMIT 180
*
* ┌────────────────┐ ┌────────────────┐ y=165
* │ 提示 │ 12 │ 埋牌 (1/8) │
* └────────────────┘ ↑ └────────────────┘ y=228
* ↑ CD_SELF ↑
* BURY_BTN_TIP(1700) BURY_BTN_SUBMIT(1702)
* +_TEXT(1701) +_TEXT(1703)「埋牌 (N/8)」
* 帧1=可提交(金黄) / 帧2=灰(未满 8 张)
*
* ┌── 手牌【双排】(Layer 102,见 Sprites_Cards.js HandView)──┐ y=285 起
*
* 出牌操作条(群组 223,EQW_Layout.PLAY_OPERATION_BAR)
* line/horizontal, anchor center, anchorX=640 anchorY=345, itemHeight=55, spacing=35
* items:CD_SELF 75 / PLAY_BTN_SUBMIT 157 / PLAY_BTN_TIP 180【估值】
*
* 20 ┌──────────────┐ ┌────────────────┐ y=345
* ↑ │ 出 牌 │ │ 提示 │
* CD_SELF └──────────────┘ └────────────────┘ y=400
* ↑ PLAY_BTN_SUBMIT(1710)+_TEXT(1711) ↑ PLAY_BTN_TIP(1712)
* 帧1=可出 / 帧2=灰(选中牌数为 0 时) +_TEXT(1713)
*
* ┌── 手牌【单排】(Layer 102)──┐ y=455 起
*
* 元素说明:
* - 埋牌条:N 为已选张数,N < 8 时提交按钮置灰;选中的牌在手牌区上浮表示待埋。
* 提交后庄家手牌回到单排 28 张。
* - 出牌条:点手牌选中(上浮)→ 点「出牌」→ 发 chupai { seat, cards }。
* 【只发意图不发结论】——不回传牌型、不回传「我最大」之类判定;前端可用 shared/ 做本地
* 预校验与提示,结果不回传。
* - 【自动选中】服务端会在下发包里带「应当选中的牌」(mustcard, S-2),前端收到后自动把这些
* 牌选中上浮,玩家确认后点「出牌」即可——方向是服务端→前端的建议,不违反红线。
* - 【2026-08-27 补齐】出牌阶段的「提示」按钮 PLAY_BTN_TIP(1712)/PLAY_BTN_TIP_TEXT(1713)
* (清单 §1.7 明确「出牌阶段必须有」)此前只登记了精灵、没有布局槽位——
* EQW_Layout.PLAY_OPERATION_BAR 的 items 只排了倒计时与出牌两项(清单 §6.8 自身也漏了它)。
* 现已按 §1.7 的行文顺序补为第 3 项,宽度取 BTN_TIP 资源原生宽 180【估值,待设计稿复核】:
* 参考图 出牌.png 里未画出该按钮,位置仍属目视推定。
*
* 资源说明:
* - 提示按钮: EQW_Images.BTN_TIP (535), 1 帧, 180×63, 蓝色渐变(埋牌/出牌两条共用同一资源)
* - 埋牌按钮: EQW_Images.BTN_BURY (536), 2 帧, 180×63, 帧1=可提交 帧2=置灰
* - 出牌按钮: EQW_Images.BTN_PLAY (537), 2 帧, 157×55, 帧1=可出 帧2=置灰
*
* 精灵ID分配: 1700–1703(埋牌条)/ 1710–1713(出牌条)
*
* @see docs_dev/二七王-UI资源与精灵清单.md §1.6 埋牌 / §1.7 出牌对局 / §5.4 / §6.8
* @see docs_dev/uiref/庄家埋牌.png
* @see docs_dev/uiref/出牌.png
*/
//操作条:埋牌操作条(群组 222)+ 出牌操作条(群组 223),同一屏幕位置随阶段互斥展示(清单 §5.4)
EQW_Sprites.OperationBarView = {
Layer: EQW_Layers.ACTION, //104
BuryBar: {
id: EQW_Groups.BURY_BAR, //222
BURY_BTN_TIP: 1700, //图片:「提示」按钮,资源 EQW_Images.BTN_TIP
BURY_BTN_TIP_TEXT: 1701, //文字:按钮文案「提示」
BURY_BTN_SUBMIT: 1702, //图片:「埋牌」按钮,资源 EQW_Images.BTN_BURY,帧1=可提交 帧2=灰(未满8张)
BURY_BTN_SUBMIT_TEXT: 1703 //文字:「埋牌 (N/8)」
},
PlayBar: {
id: EQW_Groups.PLAY_BAR, //223
PLAY_BTN_SUBMIT: 1710, //图片:「出牌」按钮,资源 EQW_Images.BTN_PLAY,帧1=可出 帧2=灰
PLAY_BTN_SUBMIT_TEXT: 1711, //文字:按钮文案「出牌」
PLAY_BTN_TIP: 1712, //图片:「提示」按钮(出牌阶段必备),资源 EQW_Images.BTN_TIP
PLAY_BTN_TIP_TEXT: 1713 //文字:按钮文案「提示」
}
};
// ============================================================================
// 倒计时 - Layer 104 (ACTION), Group 224 (COUNTDOWN)
// ============================================================================
/**
* 倒计时 - CountdownView
*
* 用途: 把当前操作者剩余的秒数显示在【他自己的位置旁】。三家各一个精灵,
* 按当前操作者显隐其一——所以看到数字在哪儿,就知道在等谁。
*
* 布局说明(参考图:等待叫分.png 的「12」在左上家、出牌2.png 的「15」在左上家、
* 自己叫分.png 的「12」在不叫按钮左侧、庄家埋牌.png 的「12」在操作条中间):
*
* ┌──────────────────────────────────────────────────────────────┐ y=0
* │ ┌ 顶部信息条 ┐ │
* │ ┌────┐ ┌────┐ │
* │ │头像│ 12 15 │头像│ │ y≈165
* │ └────┘ ↑ ↑ └────┘ │
* │ CD_LEFT(1150) CD_RIGHT(1151) │
* │ point(195,165) point(1010,165) │
* │ │
* │ 20 ┌──────────┐ │ y≈345
* │ ↑ │ 出 牌 │ │
* │ CD_SELF └──────────┘ │
* │ (1152) │
* └──────────────────────────────────────────────────────────────┘ y=720
*
* ⚠ 左右两家的倒计时与该家的状态文字(P_LEFT/RIGHT_STATUS_TEXT,见 Sprites_Table.js)
* 落在【同一块区域】:轮到他时显示秒数,他表态后显示「60分」/「不叫」,两者不共存。
*
* CD_SELF 一个精灵、三处落点,由当前阶段的布局节点决定:
* 叫分阶段 → EQW_Layout.P_COUNTDOWN.SELF = point(445, 345)(不叫按钮左侧)
* 埋牌阶段 → EQW_Layout.BURY_OPERATION_BAR 的 items 第 2 项(提示与埋牌之间,y=165)
* 出牌阶段 → EQW_Layout.PLAY_OPERATION_BAR 的 items 第 1 项(出牌按钮左侧,y=345)
* 选主阶段 → 参考图 亮主.png 显示在「亮主」标题条内、标题文字右侧(布局节点待补)
*
* 元素说明:
* - 三个精灵均为【多帧图数字精灵】而非文字精灵(2026-08-27 订正):玩家视线焦点、视觉权重
* 最高的数字,参考图是带描边/渐变的美术字,文字精灵做不出这个效果。
* 显示走 SpriteManager.setNumberImage(spriteId, '15', charWidth),纯秒数、无后缀。
* - 布局节点 EQW_Layout.P_COUNTDOWN 的 h 恒取 NUM_STYLE.COUNTDOWN.charHeight(SSOT),
* w 留到运行时注入——setNumberImage 会按【字符数 × charWidth】自动改精灵宽。
* - 数据来源:各包的 countdown 字段。
* - 【只做展示,不触发任何操作】倒计时归零后不自动叫分/选主/埋牌/出牌,也不判负、不跳过;
* 前端不得在归零时做任何乐观界面推进(不跳阶段、不清控制权),一切仍等服务端推送。
* 超时裁定在服务端,前端只做插值显示。
* - 【归零后停在 0 继续显示,不隐藏】——隐藏会被误读为「已超时 / 已跳过」。
*
* 资源说明:
* - 数字: EQW_Images.NUM_COUNTDOWN (631), 16 帧固定帧序 0123456789.+-x/p,
* 单字符 44×60, 整图 704×60;帧11–15 本套用不到但必须留占位,帧16 出空白(无后缀)
* - charWidth / charHeight 只在 EQW_Layout.NUM_STYLE.COUNTDOWN 定义一处,业务代码只引用
*
* 精灵ID分配: 1150–1152(群组 224 号段 1150–1159)
*
* @see docs_dev/二七王-UI资源与精灵清单.md §2.4 倒计时 / §5.4 / §6.8
* @see docs_dev/uiref/等待叫分.png
* @see docs_dev/uiref/自己叫分.png
* @see docs_dev/uiref/庄家埋牌.png
*/
//倒计时:左上家/右上家/自己 三处操作区倒计时(清单 §5.4,Layer 104 群组 224)
//
//三处均为【多帧图数字精灵】(非文字精灵):玩家视线焦点、视觉权重最高的数字,参考图是带描边/渐变
//的美术字,文字精灵做不出这个效果。资源 EQW_Images.NUM_COUNTDOWN(16 帧固定帧序),纯秒数无后缀。
//显示用 SpriteManager.setNumberImage(spriteId, '15', charWidth),charWidth 见
//EQW_Layout.NUM_STYLE.COUNTDOWN.charWidth(2026-08-27,与 NUM_STYLE.COUNTDOWN 一起落地)
EQW_Sprites.CountdownView = {
Layer: EQW_Layers.ACTION, //104
Countdown: {
id: EQW_Groups.COUNTDOWN, //224
CD_LEFT: 1150, //多帧图数字精灵:左上家位倒计时
CD_RIGHT: 1151, //多帧图数字精灵:右上家位倒计时
CD_SELF: 1152 //多帧图数字精灵:自己操作区倒计时
}
};
// ============================================================================
// 桌面浮层 - Layer 105 (OVERLAY), Group 230 (OVERLAY)
// ============================================================================
/**
* 桌面浮层 - OverlayView
*
* 用途: 盖在牌桌之上的一次性/短时表现层,三类互不相干的东西共用一个群组:
* (1) 闲家提示气泡 (2) 捡分飘字 (3) 通用状态提示条。
* 都是「浮」在桌面上、不属于任何固定面板的元素,故集中在 Layer 105。
*
* 布局说明(参考图:自己是闲家时,底下的踩有分没分按钮.png = 气泡入口;
* 出牌2.png 中央的「20分」= 捡分飘字;强甩失败提示.png / 等待庄家选主.png = 提示条):
*
* ┌──────────────────────────────────────────────────────────────┐ y=0
* │ ┌ 顶部信息条 ┐ │
* │ ┌────┐ ┌────┐ │
* │ │头像│(踩) (踩)│头像│ │ y≈122
* │ └────┘ ↑ ↑ └────┘ │
* │ BUBBLE_TISHI_LEFT(1750) BUBBLE_TISHI_RIGHT(1751) │
* │ 箭头向左(帧1–3) 箭头向右(帧4–6) │
* │ │
* │ ┌────────────────────────────────┐ │ y=172
* │ │ 强 甩 失 败 │ ← TOAST_INSTANT│ 462,363×50
* │ └────────────────────────────────┘ │
* │ ┌──────────────┐ │ y=180
* │ │ 20分 │ ← GRADE_FLOAT │ 570,170×55
* │ └──────────────┘ │
* │ │
* │ ┌────────────────────────────┐ │ y=373
* │ │ 等待庄家选主 │ ← TOAST_WAIT │ 500,320×47
* │ └────────────────────────────┘ │
* └──────────────────────────────────────────────────────────────┘ y=720
*
* (1) 提示气泡 BUBBLE_TISHI_LEFT/RIGHT/SELF (1750–1752)
* EQW_Layout.TISHI_BUBBLE, attach 平台头像框, 96×44(尺寸为占位估值,资源待定稿):
* LEFT → attach P_LEFT_AVATAR(379) right/middle, offsetX=+10, arrowRight=false
* RIGHT → attach P_RIGHT_AVATAR(377) left/middle, offsetX=-10, arrowRight=true
* SELF → attach P_SELF_AVATAR(376) right/top, offset(+10,-70), arrowRight=false
* 帧 = (arrowRight ? 3 : 0) + tip,tip:1踩 2没分 3有分。
* 【朝向是配置项 arrowRight,不按座位硬判】——头像在气泡左侧就用箭头向左的帧。
* (2) 捡分飘字 GRADE_FLOAT_BG(1755) + GRADE_FLOAT_TEXT(1756)
* EQW_Layout.GRADE_FLOAT = point(570, 180, 170×55) 为【起始】位置;
* 上飘与时长见 EQW_Anim.SCORE_FLOAT = { rise: -60, duration: 800 }(SSOT,布局里不重复)。
* (3) 通用状态提示条 BAR_TOAST(1760) + TXT_TOAST(1761)
* 整局【复用同一套精灵】,只换文案与位置预设,两个预设二选一:
* 等待类(常驻到状态结束)→ EQW_Layout.TOAST_WAIT = point(500, 373, 320×47)
* 即时反馈类(自动淡出) → EQW_Layout.TOAST_INSTANT = point(462, 172, 363×50)
* 自动消失时长见 EQW_Anim.TOAST_DURATION = 1500(SSOT)。
*
* 元素说明:
* - 【提示条文案共 3 条,T-33 已定案】:
* 「等待庄家选主」 状态类,两个闲家可见,收 shangzhuang 后 → 收 xuanzhu 前
* 「等待庄家埋牌」 状态类,两个闲家可见,收 xuanzhu 后 → 收 maipai 前
* 「强甩失败」 即时反馈,全场可见,收到 chupai1.shuaicuo == 1 时,自动淡出
* 明确【不做】:叫分等待 / 出牌等待(倒计时已指明在等谁)、准备等待(平台自带标识)、
* 掉线重连提示(平台已覆盖)、开底提示(画面本身已说清楚)。文案表进配置,不写死字符串。
* - 【甩错 D-3 已定】不做收回动画——甩出的牌不演「飞回手里」,直接按服务端下发的 cards
* (被强制打出的最小主牌单张)落牌即可,另配一条「强甩失败」提示。
* - 【气泡的受控例外】服务端只把提示转发给对家、不回执给发送者,所以发送者【自己的气泡由
* 前端在点击时本地回显】。这是「悲观 UI」红线的一处受控例外,成立理由是提示不含任何对局
* 状态、不改阶段/控制权/分数,服务端也明确不校验其真实性;失败回包到达时须撤掉本地回显。
* 本人看不到自己的气泡(BUBBLE_TISHI_SELF 是给对家看的,见清单 §6.6)。
* - 【报无主 D-4 已定】不做全场提示,唯一界面变化是他家的主N/对N 角标出现(PlayerMarkView)。
*
* 资源说明:
* - 气泡: EQW_Images.BUBBLE_TISHI (651), 6 帧 (3×2), 尺寸待定
* 帧1=踩·左 帧2=没分·左 帧3=有分·左 / 帧4=踩·右 帧5=没分·右 帧6=有分·右
* - 提示条底: EQW_Images.BAR_TOAST (653), 1 帧, 363×50, 可九宫拉伸(按文案长度变宽)
* - 捡分飘字底: EQW_Images.TXT_GRADE_FLOAT (654), 1 帧, 尺寸待定
*
* 精灵ID分配: 1750–1752 / 1755–1756 / 1760–1761(群组 230 号段 1750–1799)
* —— 中间空号(1753/1754/1757/1758/1759)是清单显式判定「不需要」的键,见下方原注释。
*
* @see docs_dev/二七王-UI资源与精灵清单.md §2.8 状态提示条 / §1.7 闲家提示·甩错 / §5.5 / §6.8
* @see docs_dev/uiref/自己是闲家时,底下的踩有分没分按钮.png
* @see docs_dev/uiref/强甩失败提示.png
* @see docs_dev/uiref/等待庄家选主.png
* @see docs_dev/uiref/出牌2.png
*/
//桌面浮层:提示气泡 + 通用状态提示条 + 捡分飘字(清单 §5.5,Layer 105 群组 230)
//
//以下键号在源清单中被显式判定「不需要」,本文件不占用,留空号以便追溯:
// 1753 TXT_BAOZHU —— 报无主不做全场提示(D-4),只让他家 主N/对N 角标出现
// 1754/1759 BAR_SHUAICUO —— 甩错提示并入通用状态提示条 BAR_TOAST/TXT_TOAST(§2.8)
// 1757/1758 BOTTOM_3S_* —— 70分底牌亮3秒复用底牌区翻牌(D-2),仅可见范围不同,不单独建精灵
EQW_Sprites.OverlayView = {
Layer: EQW_Layers.OVERLAY, //105
Overlay: {
id: EQW_Groups.OVERLAY, //230
//—— 提示气泡:踩/没分/有分,按发送者位置三选一显示,资源 EQW_Images.BUBBLE_TISHI,
// 帧 = (arrowRight ? 3 : 0) + tip(tip:1踩 2没分 3有分);朝向为配置项 arrowRight,非按座位硬判(清单 §6.6)——
BUBBLE_TISHI_LEFT: 1750, //左上家气泡:头像在气泡左侧,箭头向左,帧1–3,attach 头像框 hAlign:right
BUBBLE_TISHI_RIGHT: 1751, //右上家气泡:头像在气泡右侧,箭头向右,帧4–6,attach 头像框 hAlign:left
BUBBLE_TISHI_SELF: 1752, //自己气泡:头像在气泡左侧,箭头向左,帧1–3(本人看不到自己气泡,仅对家可见,见清单 §6.6)
GRADE_FLOAT_BG: 1755, //图片:捡分飘字底,资源 EQW_Images.TXT_GRADE_FLOAT
GRADE_FLOAT_TEXT: 1756, //文字:「20分」
BAR_TOAST: 1760, //图片:通用状态提示条底(等待类/即时反馈类共用,收敛为 3 条,见清单 §2.8),资源 EQW_Images.BAR_TOAST,可九宫拉伸
TXT_TOAST: 1761 //文字:提示文案
}
};