二七王:Sprites_Cards.js 补 4 个 View 的布局说明注释

为 HandView / BottomCardsView / BuryCardsView / PlayAreaView 各补一块 JSDoc:
分区标题标出 Layer 与 Group,正文含 ASCII 版式图(手牌单排/双排两种形态、
底牌背面与翻正面、埋牌底牌在结算面板内的位置、三家已出牌区的镜像关系与
牌型标签/牌角标贴附方式)、元素说明、资源说明、精灵 ID 分配与 @see 出处。

纯注释改动,数据部分一字未动(精灵总数仍 378、布局节点仍 61)。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-27 01:39:49 +08:00
co-authored by Claude Opus 5
parent 19f93bb96f
commit a4b12a1ebb
@@ -7,6 +7,73 @@
// 连号精灵逐条写全,不用循环生成——便于人逐张对照编辑器核对。
var EQW_Sprites = EQW_Sprites || {};
// ============================================================================
// 自己手牌区 - Layer 102 (HAND), Group 210 (HAND)
// ============================================================================
/**
* 自己手牌区 - HandView
*
* 用途: 屏幕下部铺开自己的手牌(重叠排列),并在每张牌上叠加牌型标记。
* 两种形态:常态【单排】、庄家埋牌时【双排】。张数上限 36(庄家摸底后 28+8)。
*
* 布局说明(参考图 docs_dev/uiref/等待叫分.png = 单排;
* docs_dev/uiref/庄家埋牌.png = 双排):
*
* 形态一 · 单排(叫分 / 选主 / 出牌阶段,EQW_Layout.HAND_FAN_SINGLE)
* fan/horizontal, anchor center, anchorX=640 anchorY=455, maxWidth=1215,
* 牌尺寸 CARD_SIZE.L = 110×190, spacingMax=0 spacingMin=-78, overlapFrom='left'
*
* x≈35 x≈1250
* ┌──┬──┬──┬──┬──┬──┬──┬──┬── … ──┬──┬──┬──────────┐ y=455
* │K │K │K │K │K │K │K │K │ │K │K │ K │
* │♦ │♦ │♦ │♦ │♦ │♦ │♦ │♦ │ …… │♦ │♦ │ ♦ │
* └──┴──┴──┴──┴──┴──┴──┴──┴── … ──┴──┴──┴──────────┘ y=645
* ↑ HAND_CARD_1(1200) 起自左,逐张右叠;末张整张露出(110px)
* 36 张时每张只露约 32px(spacing -78),与参考图实测 33px 吻合
*
* 形态二 · 双排(仅庄家埋牌阶段,EQW_Layout.HAND_TWO_ROW)
* splitStrategy='floorTop':上排 floor(n/2)、下排 ceil(n/2)(36 张 = 18/18)
* ROW_TOP anchorX=644 anchorY=285 maxWidth=928 spacingMin=-65
* ROW_BOTTOM anchorX=644 anchorY=455 maxWidth=928 spacingMin=-65
*
* ┌──┬──┬──┬── … ──┬──┬──────┐ y=285 ← ROW_TOP
* │K │K │K │ …… │K │ K │
* └──┴──┴──┴── … ──┴──┴──────┘ y=455
* ┌──┬──┬──┬── … ──┬──┬──────┐ y=455 ← ROW_BOTTOM
* │K │K │K │ …… │K │ K │
* └──┴──┴──┴── … ──┴──┴──────┘ y=645
* ⚠ 参考图画的是 17/19 分行,属填充画法(清单 §0.5),不作依据;分行以 floorTop 为准。
*
* 选中态: 整张牌上浮,偏移量 EQW_Anim.HAND_SELECT_OFFSET_Y = -40(SSOT,布局里不重复定义)。
*
* 元素说明:
* - HAND_CARD_1..36 与 HAND_MARK_1..36 【一一对应】(HAND_MARK_i 属于 HAND_CARD_i),
* 同属群组 210;张数少于 36 时隐藏多余精灵并重算间距。
* - 牌面帧 = cardIdToFrame(id)(清单 §0.4 唯一权威转换,前端只此一处实现)。
* - 手牌标记三种互斥、每张牌至多一个,由前端据 flower(主牌花色)本地标注,服务端不下发:
* 帧1 =「拖」红色圆标 —— 该牌属于一组拖拉机
* 帧2 = 橙色五角星 —— 正 2 / 正 7(主花色的 2 和 7)
* 帧3 = 蓝色五角星 —— 除正2正7外的其他主牌(双王、副2、副7、主花色普通牌)
* 在参考图 庄家埋牌.png 下排牌的左下角可看到这三种标记。
* - 【时序】发牌动画从右往左铺开(EQW_Anim.DEAL: 800ms / 每张 20ms 延迟);须先
* setHandCards() 把牌写进 this.data、再播动画,动画回调里只刷界面不写核心数据。
* - 【时序】选主后主牌集合会变(正2/正7 升格),手牌必须按新主牌序重排(清单 §7.2 T-5)。
*
* 资源说明:
* - 牌面: EQW_Images.CARD_FACE_L (501), 60 帧 (10列×6行行优先), 单帧 110×190, 整图 1100×1140
* 帧1–13 黑桃A–K / 帧14–26 红桃 / 帧27–39 梅花 / 帧40–52 方块 /
* 帧53 小王 / 帧54 大王 / 帧55–60 牌背(二七王用帧55)
* - 牌上标记: EQW_Images.MARK_CARD_GROUP (577), 3 帧, 26×26
* - 选中标记: EQW_Images.MARK_SELECTED (578) 尺寸待定,也可只用上浮表现、不出图
*
* 精灵ID分配: 1200–1235(手牌)+ 2100–2135(手牌标记)
* —— 标记另起 2100 段的原因见下方原注释(1236 起接不下 36 个连号)。
*
* @see docs_dev/二七王-UI资源与精灵清单.md §2.7 手牌区 / §5.2 Layer 102 / §6.7 牌区配置
* @see docs_dev/uiref/等待叫分.png
* @see docs_dev/uiref/庄家埋牌.png
*/
//自己手牌区:36 张手牌 + 36 个手牌标记(每张牌一个,见下方裁决说明),同属群组 210(清单 §5.2,Layer 102)
EQW_Sprites.HandView = {
Layer: EQW_Layers.HAND, //102
@@ -99,6 +166,59 @@ EQW_Sprites.HandView = {
}
};
// ============================================================================
// 底牌区(发牌留桌 8 张)- Layer 103 (TABLE_CARDS), Group 211 (BOTTOM_CARDS)
// ============================================================================
/**
* 底牌区 - BottomCardsView
*
* 用途: 桌面中央上部的 8 张【底牌】——发牌时没有发给玩家、留在桌面的那 8 张。
* 发牌起显示牌背;庄家摸底 / 70 分开底时【同一批精灵】翻成正面。
*
* 布局说明(背面:docs_dev/uiref/等待叫分.png 中央;正面:docs_dev/uiref/叫分确定庄.png、
* docs_dev/uiref/等待庄家选主.png 中央;
* 位置见 EQW_Layout.BOTTOM_CARDS = line/horizontal, anchor center,
* anchorX=655 anchorY=110, 牌尺寸 CARD_SIZE.L 110×190, spacing=-36):
*
* x 居中于 655
* ┌──────┬──────┬──────┬──────┬──────┬──────┬──────┬────────────┐ y=110
* │ 背 │ 背 │ 背 │ 背 │ 背 │ 背 │ 背 │ 背 │
* │ │ │ │ │ │ │ │ │
* └──────┴──────┴──────┴──────┴──────┴──────┴──────┴────────────┘ y=300
* ↑ ↑ ↑
* BOTTOM_ BOTTOM_ BOTTOM_
* CARD_1 CARD_2 … (等距 spacing -36,每张露 74px)… CARD_8
* (1250) (1251) (1257)
*
* 翻开后同一批精灵改帧为正面(帧 = cardIdToFrame(id)):
* ┌──────┬──────┬──────┬──────┬──────┬──────┬──────┬────────────┐
* │K │K │K │K │K │K │K │K │
* │♦ │♦ │♦ │♦ │♦ │♦ │♦ │♦ │
* └──────┴──────┴──────┴──────┴──────┴──────┴──────┴────────────┘
*
* 元素说明:
* - 未揭示时帧 = 55(牌背);揭示时帧 = cardIdToFrame(id)(清单 §0.4)。
* - 【时序·开底 D-2 已定】翻牌这套 UI 只有一套,两种情形只是【谁能看到】不同:
* 非 70 分坐庄(只摸底)→ 只有庄家看得到这 3 秒,闲家侧保持背面 / 直接收起
* 70 分坐庄(开底) → 全场三人都看得到 3 秒(EQW_Anim.ANCARD_REVEAL_DURATION = 3000)
* 开底【不做倒计时、不做单独的公示面板、不加提示文案】——画面本身已说清楚(§2.8)。
* 3 秒后庄家摸入手牌、闲家侧收起,底牌区隐藏。
* - 【重连不重放】70 分的 3 秒亮牌是上庄时的一次性事件,deskinfo 重连不得补播(§1.4)。
* - 底栏「底牌」按钮再看这 8 张时也复用本区(庄家全程可看,闲家仅开底过的局,S-3)。
* - ⚠ 参考图 等待庄家选主.png 把「开底摊牌」与「等待庄家选主」提示条画在了一起,属叠画
* 示意(§0.5);实际顺序是 开底 3 秒 → 庄家摸底入手 → 选主,摸底后本区即收起。
*
* 资源说明:
* - 牌面: EQW_Images.CARD_FACE_L (501), 60 帧, 单帧 110×190(与手牌同一套资源)
*
* 精灵ID分配: 1250–1257
*
* @see docs_dev/二七王-UI资源与精灵清单.md §1.2 发牌 / §1.4 看底牌·上庄 / §5.3 / §6.7
* @see docs_dev/uiref/等待叫分.png
* @see docs_dev/uiref/叫分确定庄.png
* @see docs_dev/uiref/等待庄家选主.png
*/
//底牌区:发牌留桌 8 张(清单 §5.3,Layer 103 群组 211)
EQW_Sprites.BottomCardsView = {
Layer: EQW_Layers.TABLE_CARDS, //103
@@ -118,6 +238,56 @@ EQW_Sprites.BottomCardsView = {
}
};
// ============================================================================
// 埋牌底牌展示区 - Layer 103 (TABLE_CARDS), Group 215 (BURY_CARDS)
// ============================================================================
/**
* 埋牌底牌展示区 - BuryCardsView
*
* 用途: 小局结算时亮出【埋牌底牌】——庄家埋牌阶段从手里扣下的那 8 张。
* 用最小的牌面尺寸档 S,摆在小局结算面板的上半部。
*
* 术语区分(清单 §2.6 已统一,别混):
* 「底牌」 = 发牌留桌的 8 张 → BottomCardsView(群组 211),协议字段 bottomcards
* 「埋牌底牌」= 庄家埋下的 8 张 → 本 View(群组 215),协议字段 burycards / bottom.cards
*
* 布局说明(参考图 docs_dev/uiref/小局结算.png 中央面板内那排小牌;
* 位置见 EQW_Layout.BURY_CARDS = line/horizontal, anchor center,
* anchorX=640 anchorY=163, 牌尺寸 CARD_SIZE.S 50×70, spacing=2):
*
* ┌──────────────────────────────────────────┐ y=140 ← RESULT_BOTTOM_PANEL(1800)
* │ ┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐ │ y=163 (见 Sprites_Result.js)
* │ │10││10││10││10││10││10││10││10│ │
* │ │♠ ││♥ ││♣ ││♦ ││♠ ││♥ ││♣ ││♦ │ │ y=233
* │ └──┘└──┘└──┘└──┘└──┘└──┘└──┘└──┘ │
* │ 叫分2子 底牌 20x0 │ ← RESULT_BOTTOM_TEXT(1801)
* └──────────────────────────────────────────┘ y=288
* ↑ ↑ ↑
* BURY_ BURY_ BURY_
* CARD_1 CARD_2 …(等距 spacing +2,不重叠)… CARD_8
* (1258) (1259) (1265)
*
* 本区居中于 x=640,与外层面板(EQW_Layout.RESULT_BOTTOM_PANEL = 430,140,420×148)
* 的中心 x=640 对齐;8×50 + 7×2 = 414,正好落在面板 420 宽度之内。
*
* 元素说明:
* - 数据取结算包 bottom.cards,【恒有】(design §11:牌局结束需要亮出底牌)——
* 即便闲家未扣底也照常亮 8 张,只是面板文案里的倍数位显示 0。
* - 帧 = cardIdToFrame(id),恒为正面(本区只在结算时出现,不存在牌背态)。
* - 【容错】投降结算只有 aset、无 bottom 分组 → 结算面板必须容忍底牌区缺失,
* 不能因读不到 bottom.cards 就崩或显示空框(§1.8)。
* - 底栏「扣底」按钮(清单 §2.6,尚无精灵)看的也是这 8 张。
*
* 资源说明:
* - 牌面: EQW_Images.CARD_FACE_S (503), 60 帧, 单帧 50×70, 整图 500×420
* 帧排布与 CARD_FACE_L 完全一致(§0.4)
*
* 精灵ID分配: 1258–1265
*
* @see docs_dev/二七王-UI资源与精灵清单.md §1.8 末轮扣底 + 小局结算 / §5.3 / §6.7
* @see docs_dev/uiref/小局结算.png
*/
//埋牌底牌展示区:结算时亮出的埋牌底牌 8 张(清单 §5.3,Layer 103 群组 215)
EQW_Sprites.BuryCardsView = {
Layer: EQW_Layers.TABLE_CARDS, //103
@@ -137,6 +307,81 @@ EQW_Sprites.BuryCardsView = {
}
};
// ============================================================================
// 三家已出牌区 - Layer 103 (TABLE_CARDS), Group 212 / 213 / 214
// ============================================================================
/**
* 三家已出牌区 - PlayAreaView
*
* 用途: 出牌阶段,三家各有一块区域展示【本轮】打出的牌(中号牌面 CARD_FACE_M)。
* 每家一个群组、各预置 28 张(= 单次出牌张数上限,甩牌最多可甩满手牌)。
*
* 布局说明(参考图 docs_dev/uiref/出牌2.png;
* 位置见 EQW_Layout.PLAY_AREA,三家共用 base + bySeat 三个变体:
* fan/horizontal, 牌尺寸 CARD_SIZE.M 90×155, maxWidth=170,
* spacingMax=-35 spacingMin=-62):
*
* ┌──────────────────────────────────────────────────────────────┐ y=0
* │ ┌ 顶部信息条 ┐ │
* │ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │
* │ │头像│ │K K │ │K K │ │头像│ │ y≈120
* │ └────┘ │ 大│ │ 大│ └────┘ │
* │ └────┘ └────┘ │
* │ LEFT 258,120 RIGHT 1022,120 │
* │ overlapFrom='right' overlapFrom='left' │
* │ (左右镜像:同参数,堆叠朝向相反) │
* │ │
* │ ┌────┐ │
* │ │K K │ ← SELF 650,265 │ y≈265
* │ │ 庄│ overlapFrom='left' │
* │ ┌──┴────┘ │
* │ │拖拉机│ ← 牌型标签,贴该区首张牌 bottomLeft │
* │ └──────┘ │
* │ │
* │ ┌──────────── 自己手牌区(Layer 102)────────────┐ │ y≈455
* └──────────────────────────────────────────────────────────────┘ y=720
*
* 单个出牌区的内部结构(以自己为例):
*
* PLAY_SELF_1(1300) 起自左,逐张右叠(fan 压缩,最多 28 张)
* ↓
* ┌────┬────┬──────┐
* │ K │ K │ K │ 每张牌【右上角】可再叠一个角标:
* │ ♦ │ ♦ │ ♦ ⟨庄⟩│ MARK_BANKER_CORNER(572) 28×28「庄」橙色斜标
* └────┴────┴──────┘ MARK_JOKER_BIG(573) 34×34「大/小」王圆标
* ┌──────┐ —— 贴的是运行时才确定的某一张牌,故
* │ 拖拉机│ EQW_Layout.PLAY_CARD_CORNER_MARK 只给模板
* └──────┘ (corner/offset),target/w/h 由调用方注入
* ↑ PLAY_SELF_TYPE_BG(1328) + PLAY_SELF_TYPE_TEXT(1329)
* EQW_Layout.PLAY_TYPE_LABEL: attach 首张牌 bottomLeft, offsetY=-24, 76×24
* 首槽是【固定】精灵(PLAY_SELF_1 / PLAY_LEFT_1 / PLAY_RIGHT_1),非动态目标
*
* 元素说明:
* - 牌面帧 = cardIdToFrame(id)(§0.4);数据取 chupai1/2/3 的 seat + cards。
* - 牌型标签当前【只出「毙」一种】——EQW_Images.LABEL_CARDTYPE 只做这一帧;
* 数据层仍保留 毙/垫/混合出牌 三种标识以备扩展,但不出图、不显示。
* ⚠ 参考图 出牌2.png 左下角的橙色「拖拉机」标签是设计示意,与当前资源定案(只做「毙」)
* 不一致,实现时以资源注释为准(清单 §7.2 T-11 标签种类以美术稿为准,尚未定案)。
* - 甩牌的真实结构只能读 chupai1.shuai({tractors, pairs, singles}),
* 【不得据 cardtype 反推】(协议 §11 明确警告)。
* - 【时序·一轮结束】maxseat 高亮 → 三家出牌区收牌 → 若有 grade 播捡分飘字
* (OverlayView 的 GRADE_FLOAT)并累加顶部「抓分」列 → 下一轮由 maxseat 先出。
* - 【为什么预置而不复制】号段每家 100 个、容量充裕,且需要叠压 z 序与出牌动画、
* 逐张独立控制,故不使用 SpriteCopyUtils,避免显式清理负担(清单 §5.6a 判据表)。
*
* 资源说明:
* - 牌面: EQW_Images.CARD_FACE_M (502), 60 帧, 单帧 90×155, 整图 900×930
* - 牌型标签底: EQW_Images.LABEL_CARDTYPE (576), 1 帧, 76×24
* - 牌角标: EQW_Images.MARK_BANKER_CORNER (572) 1 帧 28×28 /
* EQW_Images.MARK_JOKER_BIG (573) 2 帧 34×34(帧1=大王 帧2=小王)
*
* 精灵ID分配: 1300–1329(自己)/ 1400–1429(左上家)/ 1500–1529(右上家)
*
* @see docs_dev/二七王-UI资源与精灵清单.md §2.3 已出牌区 / §1.7 出牌对局 / §5.3 / §6.7
* @see docs_dev/uiref/出牌.png
* @see docs_dev/uiref/出牌2.png
*/
//三家已出牌区:自己/左上家/右上家 各 28 张牌 + 牌型标签底 + 标签文字(清单 §5.3,Layer 103 群组 212/213/214)
EQW_Sprites.PlayAreaView = {
Layer: EQW_Layers.TABLE_CARDS, //103