麻将 UI 层可观察行为(UI_BEHAVIOR)
第0条(基线)本文件语义以产品源码与 UI 脚本为权威源;引用只允许以文件与符号(函数、控件路径、纹理名)给出;行号引用前必须复核现码。
第1章 面板清单
第1条(主牌桌根窗口)
- 根窗口
mahjong_main_panel;其余面板均为独立根窗口,不是其子窗口。 - 初始化
_InitOnce必须:幂等守卫;挂载全部方法到窗口对象;预创建 4×13 牌墙实例;强制选项动画可见;清空牌桌;绑定按钮;订阅核心事件;注册实际显示、实际隐藏与聊天事件。 - 显示时机:打开函数执行
Show(true),不得 BringToTop(Z 序防护);房间信息事件中有房间则打开,无房间则关闭。 - 隐藏时机:退房事件关闭;最小化先发挂机请求再关闭并广播 UI 隐藏;强制退房在无房号时直接关闭、对局中弹确认框;被踢与重登关闭;等待阶段且无房间关闭。
- 实际显示处理:重建临界区保留定时器;释放动画与退出锁;重建阶段倒计时 200 毫秒定时器;非等待装载且非活跃游戏才清桌;刷新全部;状态大于 0 时检查阶段;换三张阶段恢复骰子;广播面板显示事件;置顶。
- 实际隐藏处理:杀阶段倒计时定时器;置自动决策标记防隐藏期间自动动作;隐藏出牌箭头;广播面板隐藏事件。
- 聊天事件:跨服与娱乐房频道消息显示气泡。
- 核心事件订阅(经订阅桥接):
| 事件 | UI 行为 |
|---|---|
| 游戏状态 | 刷新全部并检查阶段 |
| 行动通知 | 本家:选项显示操作按钮;暗杠补杠显示杠与过;可自摸显示胡与过;非本家隐藏 |
| 行动广播 | 出牌:语音加弃牌加箭头;摸牌:语音;碰:语音加动画并刷新;杠:类型语音降级链;胡与自摸:语音加动画加胡牌卡加点炮特效;过:语音;统一刷新并检查阶段 |
| 定时器 | 归零执行自动动作:响应阶段胡、杠、碰、过;回合阶段暗杠、补杠、推荐、autoplay、第一张 |
| 定缺 | 进入定缺阶段 |
| 对局结束 | 清交互态;写结算结果与待显示标记;刷新渲染终局;查花猪与大叫语音;显示胡牌视图或消息框;流局语音与提示;结算语音;打开结算面板 |
| 错误 | 退出、准备、换三张、定缺失败释放锁;消息提示错误文本 |
| 玩家同步 | 刷新玩家信息、补缺门、释放准备锁、刷新桌皮与气泡皮肤 |
| 玩家胡牌 | 显示胡牌徽章(座位与胡序) |
| 即时结算 | 血战即时结算:写结果或按旧协议重构后打开结算面板 |
| 挂机取消 | 刷新操作 |
| 房间信息 | 开或关面板;等待装载只刷玩家信息、箭头、缺门;否则刷新全部并检查阶段、播放加入语音 |
| 玩家挂机 | 刷新玩家信息 |
| 崩溃 | 弹消息框;等待装载时自动退房 |
| 退房 | 全量清理全局状态(定时器、锁、动画表)并关闭 |
| 破产 | 弹江湖令不足消息框 |
| 回合等待 | 刷新全部并检查阶段 |
| 踢人成功与失败 | 消息框提示 |
| 房间重连 | 可见:释放锁、清标记、刷新、检查阶段、重建倒计时;不可见:不打开(公式系统入口) |
| 新局准备 | 清桌;隐藏按钮;检查阶段;重建换三张与定缺倒计时;自动准备 200 毫秒后执行 |
- 按钮绑定:碰、杠、胡、过在执行前必须有可见性守卫;准备按钮播放语音并发送、带 15 秒防抖;设置、规则、统计、流水按钮打开对应面板;最小化、退出、关闭走对应处理;批量购买打开畅玩阁面板;托管与购买按钮发取消挂机请求。
- 阶段切换:换三张在动画总时长耗尽后直接进入,未开始则播开局动画链(开始、骰子、换三张);定缺隐藏换牌面板并恢复或进入定缺;进行中与等待响应退出特殊阶段并进入行牌。
- 换三张:隐藏骰子与定缺选项、四家换牌中状态、手牌选择事件绑定、显示换牌面板与确认按钮、倒计时归零自动补全 3 张发送、自动预选推荐 3 张。
- 定缺:显示三花色选择、推荐定缺标记、点击发送并隐藏、倒计时归零自动推荐花色。
- 行牌:绑定手牌与摸牌点击。
- 手牌点击:单张选中;双击已选牌出牌并将牌透明加清事件;失焦 100 毫秒回落;选中显示听牌提示。
- 摸牌点击:索引 0 与手牌共享选中态;双击出牌。
- 倒计时:全局倒计时 1 秒自续(面板不可见也执行自动出牌兜底);阶段倒计时 200 毫秒自续(阶段文字与倒计时显示、托管自动胡提前量)。
第2条(本局流水面板)
- 窗口
mahjong_current_panel;加载即关闭。 - 打开函数显示并置顶,由主面板流水按钮触发。
- 显示时全量重建并置顶;隐藏时仅清空。
- 事件:退房关闭;游戏状态在可见时增量追加。
- 行模板含名字、金额、玩家列;自摸合并多行;总分为金额列。
第3条(结算面板)
- 窗口
mahjong_result_panel;打开函数内部自检窗口、数据、玩家数与座位。 - 触发点:对局结束与即时结算。
- 实际显示置顶。
- 关键行为:本家头像、段位、分数、本局;其他三家头像;流水列表(胡牌流水、杠分、赔付补偿、每玩家净得分);行悬停提示;头像纹理。
第4条(设置面板)
- 窗口
mahjong_setting_panel;打开显示置顶并默认选中第一页签,由主面板设置按钮触发;关闭按钮关闭。 - 三页签(桌皮、语音、出牌特效):切换显隐;页签按钮与页从模板创建;个性化变更事件刷新;隐藏时清列表并重置初始化标志。
第5条(规则面板)
- 窗口
mahjong_rules_panel;加载即初始化;主面板规则按钮打开。 - 显示选中第一页签并置顶;关闭按钮关闭;切换列表按选中页签显隐规则页。
第6条(统计面板)
- 窗口
mahjong_stats_panel;加载即关闭;打开函数显示、置顶并重建卡片。 - 显示重建卡片并置顶;关闭按钮关闭;弃牌计数更新事件在可见时重建。
- 万、条、筒三区卡片(牌面贴图与剩余数);底部自动打牌复选框(缺、杠、胡)。
第7条(好友邀请面板)
- 窗口
mahjong_friend_invite_panel;打开函数要求房号大于 0,显示并置顶,由主面板邀请按钮触发。 - 实际显示清数据、加载好友树、刷新计数与列表、置顶;实际隐藏全清。
- 好友树:分组展开折叠;好友选中开关;右移加入邀请列表;左移清空;确定发邀请并关闭;取消关闭。
- 可邀请好友结果事件重建树;房间信息事件显示房号。
第8条(畅玩阁玩法注册)注册玩法回调(匹配档次、段位类型、快速匹配、好友同玩);入场条件校验弹框。
第9条(换三张逻辑模块)对外函数:初始化、切换选择、填充选择、取选择、确认、动画重置、隐藏、确认回调、重置。
第2章 行为函数清单
第10条(渲染引擎函数)trace 状态标注:已记录=进入 mock 追踪;缺失=mock 未记录。
| 函数 | 作用 | trace |
|---|---|---|
| FindWindow | 控件树导航,自动解析中间容器 | 已记录 |
| GetTileResPath | 牌值到贴图路径 | 缺失 |
| GetSmallTileResPath | 小牌贴图路径 | 缺失 |
| GetFlowTexturePath | 花猪、退水、大叫贴图 | 缺失 |
| GetRelativeSeat | 绝对座位到相对座位 | 缺失 |
| SetTileAnimate | 牌卡悬停与选中 200 毫秒平滑动画 | 已记录 |
| PlayDiscardAnimate | 出牌飞入弃牌区 | 已记录 |
| InitTable | 4 牌墙×13 固定实例 | 已记录 |
| ClearTemplateDefaults | 全桌清默认 | 已记录 |
| UpdateHand | 手牌渲染(本家牌面、定缺标记、听牌箭头;他家牌背) | 已记录 |
| UpdateGetCard | 摸牌渲染与滑落动画链 | 已记录 |
| BindExchangeGetCard | 换三张摸牌点击 | 已记录 |
| CalcWallTiles | 四墙张数计算 | 缺失 |
| GetInitWallTiles | 初始 56 张分布 | 缺失 |
| UpdateMaPai | 牌墙渲染 | 已记录 |
| AddMeld | 碰、杠、暗杠渲染 | 已记录 |
| AddDiscard | 弃牌追加 | 已记录 |
| ClearView 与 ClearAllViews | 清碰杠区 | 已记录 |
| ClearDiscard 与 ClearAllDiscards | 清弃牌区 | 已记录 |
| UpdateCurrentPlayer | 出牌指示显隐 | 已记录 |
| UpdateDealer | 庄家指示显隐 | 已记录 |
| UpdateDirection | 风向贴图 | 已记录 |
| UpdateTimer | 中央倒计时与阶段文字;超过 99 秒调整字号 | 已记录 |
| StartCountdown | 阶段倒计时 200 毫秒 tick,归零回调 | 已记录 |
| StopCountdown | 停止倒计时 | 已记录 |
| ShowActionButtons | 操作区显示与四按钮显隐 | 已记录 |
| HideActionButtons | 操作区隐藏 | 已记录 |
| GetFanTextureName | 番型到贴图名 | 缺失 |
| ShowHuFanAnimate | 座位番型动画 | 已记录 |
| ShowResult | 常驻结算(美术字倍数与文本兜底) | 已记录 |
| HideResultAll | 隐藏四家结算 | 已记录 |
| ShowActionAnimate | 碰、杠、胡、自摸贴图 | 已记录 |
| GetActionWebp | 方位动画名(特殊番型优先) | 缺失 |
| PlayOptAnimate | 动画播放与完成回调 | 已记录 |
| StopOptAnimate | 停止动画 | 已记录 |
| UpdatePlayerInfo | 头像、昵称、段位、分数、状态贴图;空位显示邀请 | 已记录 |
| UpdateTableSkin | 桌皮贴图 | 已记录 |
| UpdateDiscardEffect | 出牌特效占位 | 缺失 |
| RefreshTuoguan | 托管与购买按钮显隐 | 已记录 |
| UpdateQueSuit | 缺门标识显隐与贴图 | 已记录 |
| ClearTable | 全桌清空并按等待装载保留,重置阶段标记 | 已记录 |
| ShowDice 与 HideDice 与 ResetDiceAnimation 与 UpdateDice | 骰子动画、隐藏(定庄时间窗守卫)、重置、首见有效骰子触发 | 已记录 |
| ShowStartGame 与 HideStartGame 与 PlayStartFlow 与 PlayStartFlowAtDice 与 CancelStartFlow | 开局界面与动画链(重连直接骰子;取消杀定时器释放锁) | 已记录 |
| UpdateDiscardArrow 与 HideDiscardArrow | 出牌箭头锚定与隐藏 | 已记录 |
| BringDiscardToTop | 弃牌区置顶 | 已记录 |
| ShowDianpao 与 HideDianpao | 点炮动画显示与隐藏 | 已记录 |
| ShowExchangePhase | 换三张箭头面板显隐 | 已记录 |
| ShowHuView 与 HideHuView 与 GetHuTexture | 中央胡牌类型窗口(默认 5000 毫秒,0 为常驻) | 已记录 |
| ShowExchangePrompt 与 HideExchangePrompt | 换牌提示与确认按钮 | 已记录 |
| ShowFinalCard | 终局明牌(倒牌、胡牌卡、摸牌区清空) | 已记录 |
| GetSettleFanName 与 GetSettleAction | 结算番型名与动作描述 | 缺失 |
| HideBubbleMsg 与 ShowBubbleMsg 与 RefreshBubbleSkin | 聊天气泡显示、隐藏、皮肤重建 | 已记录 |
| ShowHuBadge | 胡牌徽章(序数) | 已记录 |
| StrandRegisterTimer | 定时器注册 | 已记录 |
| BeginRebuild | 重建临界区(杀定时器、释放锁、清气泡) | 已记录 |
| BeginAnimating 与 EndAnimating | 动画锁引用计数,解锁后补刷新 | 缺失 |
第11条(公共行为函数)
| 函数 | 作用 |
|---|---|
| OpenMahjongTablePanel | 显示主面板(幂等初始化) |
| CloseMahjongTablePanel 与 CloseAllMahjongPanels | 关主面板 |
| MahjongUI_MessageDialog | 确认框(带唯一键) |
| MahjongUI_ShowTip | 居中飘字 |
| ApplyMatch 与 CancelMatch 与 CreateRoom 与 JoinByShareCode | 匹配、建房、分享码加入 |
| SendReady 与 SendStartGame | 准备与开始 |
| OpenSettings | 打开设置 |
| SendExitRoom | 退出房间(无房间直接本地发事件) |
| SendDiscard | 出牌 |
| SendPeng 与 SendGang | 碰与杠(自动选牌) |
| SendHu | 胡(自动判自摸) |
| SendPass | 过 |
| SendExchange 与 SendQueSuit | 换三张与定缺 |
| SendAfk 与 SendNextRound | 托管与下一局 |
| SubscribeEvent 与 FireEvent 与 ClearEventCallbacks | UI 与核心事件桥接 |
| GetRoomInfo 与 GetGameState 与 GetMyPlayerID 与 GetMySeat | 数据查询 |
| GetTingInfo | 听牌列表 |
| GetRankInfo | 段位 |
| GetActionInfo | 可用操作标志 |
| GetAvailableCurrency | 货币余额 |
| RecommendQueSuit | 推荐定缺 |
| GetErrorMsg | 错误码到文本 |
| MahjongSkin_SafeID 与 MahjongSkin_CheckShowCdt | 外观配置工具 |
| 被踢与重登清理 | 事件清理 |
| BEFORE_RESET_UI | 热更前断开桥接并杀定时器 |
第12条(主面板生命周期函数)见第1条;行号见现码。
第3章 几何行为
第13条(未使用的几何 API)SetWindowPos、SetWindowSize、GetWindowPos、GetWindowSize、SetWindowName、SetPos、SetSize 在 UI 目录零调用;mock 的 SetPos 与 SetSize 为 stub。
第14条(实际使用的几何手段)
GetPos()读取仅 4 处,全在动画计算(牌卡动画起点、出牌飞牌起点、弃牌区最后一张目标、弃牌区容器兜底)。GetX、GetY、GetWidth、GetHeight读取用于动画基线与半高计算;mock 的 GetX 与 GetY 返回锚点坐标,宽高恒为 100。SetAnchor为唯一写位置手段,均为九参形式;用于牌卡动画插值、出牌箭头锚定、点炮动画锚定;mock 记录坐标。BringToTop大量使用(面板显示、动画置顶、箭头置顶)。
第15条(mock 支持状态)
| API | mock 状态 |
|---|---|
| GetPos | 已实现,返回锚点坐标并记录 |
| GetX 与 GetY 与 GetWidth 与 GetHeight | 已实现,固定值 100 |
| SetAnchor | 已实现,记录坐标 |
| SetPos 与 SetSize | stub,UI 不调用 |
| SetWindowPos 等窗口级几何 | 完全缺失;断言窗口几何前必须扩展 mock |
第4章 音频
第16条(总则)
- 无背景音乐与音量控制调用。
- 唯一音频引擎调用为
SoundEngine:Play2DSound,经语音模块封装,带防重叠(播完检查、300 毫秒间隔、1 秒清理定时器)。
第17条(主面板语音封装)五封装:按阶段、按行动、按动作、按牌、按胡牌番型,分别转语音模块对应接口。
第18条(播放点)
| 触发 | 语音 |
|---|---|
| 准备按钮与自动准备 | 按行动(准备) |
| 出牌(任何人) | 按行动(出牌)加按牌(本家自打或他家打出) |
| 摸牌 | 按行动(摸牌)加本家按牌(自摸牌) |
| 碰 | 按行动(碰) |
| 杠 | 明、暗、补杠降级链:本家自身、他家、通用 |
| 胡与自摸 | 按胡牌番型 |
| 过 | 按行动(过) |
| 进房与退房 | 按阶段(加入、离开) |
| 结束查花猪 | 按阶段 |
| 结束查大叫(流局未听) | 按阶段 |
| 流局 | 按阶段 |
| 结算 | 按阶段 |
| 开局流程 | 按阶段(开始、掷骰、停骰) |
| 进入与结束换三张 | 按阶段 |
| 进入与结束定缺 | 按阶段 |
| 测试函数 | 按动作 |
第19条(语音模块对外函数):初始化玩家语音、设置语言、设置性别、取语言与性别、取他人性别、按牌、按动作、按气泡、按行动、按游戏阶段、按阶段名、按胡牌番型、设置与清除语音包覆盖、播放中判定、模块初始化。
第20条(音频缺口)
SoundEngine全局 stub 缺失:mock 环境无此对象,语音模块播放函数会空值崩溃;现有测试未触发(外层判空,模块内层无保护)。- 背景音乐与音量接口在 mock 与 UI 均无。
- 控件级声音接口存在但 UI 未用。
- 扩展要求:补
SoundEnginestub,记录播放文件并返回可停止、可释放、可判定播放中的对象,供语音播放点断言。
第5章 Trace 已记录的行为
第21条(控件方法日志)字段为时间、方法、参数;控件自身日志与全局 control_log 事件;路径为从根到自身的全路径;导出格式为时间、路径、方法、参数;覆盖方法为控件系统全部常用方法(完整清单以 framework_ui.lua 现码为准)。
第22条(全局 trace 事件类型)
| 事件 | 来源 | 字段 |
|---|---|---|
| control_log | framework_ui.lua | 客户端、路径、方法、参数 |
| control_create 与 control_auto_create | framework_ui.lua | 客户端、标签、名称、路径、可见性 |
| event_fired | framework_ui.lua | 客户端、路径、事件类型 |
| text_get | framework_ui.lua | 客户端、键 |
| animate | framework.lua | 消息、窗口、时长 |
| ui_focus 与 ui_notify 与 ui_messagebox 与 ui_create_button | framework.lua | 焦点、通知、消息框、按钮 |
| event_fire 与 event_register | loader.lua | 客户端、名称 |
| deliver 与 handle | core.lua | 追踪 ID、来源、目标、协议、详情 |
| state | core.lua | 节点、字段、旧值、新值、上下文 |
| timer | core.lua 与 framework.lua | 创建、关闭、驱动、按类型停止、按房移除 |
| random | framework.lua | 范围与取值 |
| config_get | framework.lua | 表、匹配类型、规则名 |
| player_get | framework.lua | 玩家 ID、作用域 |
| module_event | framework.lua | 事件类型 |
| chat_channel | framework.lua | 参数 |
第23条(导出与断言工具)导出:文本、JSON、清空。断言工具:可见、文本、透明度断言、点击、控件日志导出。现有断言调用点:基础 UI 测试与对局 UI 测试。
第6章 行为断言清单
第24条(现有能力内可断言)
- 匹配成功后面板显示;无房间房间信息关闭面板。
- 换三张阶段:换牌面板可见并置顶;定缺选择隐藏;骰子隐藏。
- 换三张四家状态贴图为换牌中。
- 换三张倒计时文本为秒格式。
- 换三张进入后预选 3 张且手牌弹起动画至少 3 次。
- 点击确认:面板隐藏并发出换三张协议。
- 倒计时归零:自动补全 3 张发送并隐藏面板。
- 定缺阶段:选择面板可见、换牌面板隐藏、推荐花色标记可见。
- 点击定缺:面板隐藏、发出定缺协议、播放结束语音。
- 定缺归零:自动发送推荐花色并进入行牌。
- 行动通知本家:操作区可见且四按钮按标志显隐;非本家隐藏操作区。
- 出牌广播:弃牌区追加 1 子牌且箭头可见。
- 碰广播:动画可见且播放 trace 1 次、碰牌区追加 1 张。
- 杠广播:语音播放 trace 走降级链、杠牌区追加。
- 胡与自摸广播:胡牌区可见、动画可见、按番型语音。
- 点炮胡:点炮动画可见且播放。
- 结束(自摸):胡牌视图贴图为自摸且打开结算面板。
- 结束(流局):贴图为流局、流局语音、消息提示。
- 结算面板:名字、段位、金额带正负号;头像纹理有记录。
- 结算流水:列表行数不少于每玩家净得分行数。
- 退房:主面板关闭、离开语音、阶段语音记录清空。
- 最小化:面板关闭、发挂机请求、广播 UI 隐藏。
- 对局中退出:消息框(确定与取消)trace、退出标记置位。
- 实际隐藏:出牌箭头隐藏、广播面板隐藏。
- 托管态:托管标识与购买按钮可见;点击购买发取消挂机。
- 聊天消息:气泡列表有子项且内容为消息文本;到时自动隐藏。
- 中央倒计时:文本每秒递减,0 到 99 时字号 24;阶段文字为阶段字符串。
- 手牌渲染:子牌数等于手牌数、每牌纹理由设置、他家仅牌背可见。
- 摸牌渲染:摸牌区有子牌且位移动画至少 1 次。
- 阶段语音防重:同房间同阶段只播放一次。
- 牌墙渲染:子牌数 13 且按消耗状态控制透明度。
- 听牌提示:选中手牌后提示区可见且含倍数与数量文本。
- 语音断言(需先补 SoundEngine stub):出牌后播放文件路径按上下文偏移。