refactor(hud): 公共设置改由 Trait 声明式注册,并修复 HUD 缩放失效 - #167
Merged
Conversation
HUD 的公共外观设置(Background/Round/RoundRadius/BackgroundColor/BetterFont/ FontShadow/Spacing)由基类 Component.drawRect / drawString 消费,注册却留在 子类手写,两边没有任何机制保证一致,结果严重分叉: - Keystrokes 一个都没注册,但组件实际读了其中 5 个 —— 背景色、圆角、间距 在 ClickGUI 里既看不到也改不了,永远锁死默认值且不进配置文件 - ModsList / BlockIndicator 漏注册 rounded / roundRadius / fontShadow,同样不可见 - 8 个模块把 rounded 传了两次,而 addSettings 不去重 —— ClickGUI 渲染两个 一模一样的开关,指向同一个值 - Sprint / ToggleSneak / TargetDisplay 不画背景,但 bg 字段默认 true, 开启 blur 后会在文字后面糊出一块它们根本没画的背景框,用户无从关闭 现在 InterfaceModule 用 Trait(BACKGROUND/TEXT/SPACING) 声明能力,由 ModuleManager.init() 在所有模块构造完成后统一调用 registerCommonSettings() 追加(放在末尾以保持「模块自有设置在前、公共外观在后」的原有 UI 顺序)。 Trait 同时具备行为语义:Component.hasBackground() 检查 Trait.BACKGROUND, 所以无背景模块不会再被画 blur 蒙版。addSettings 改为按引用去重。 修复 scale 失效:22 个组件全部 allowScale=true,滚轮能滚、值会存进配置, 但这 4 个的 draw() 里 scale 一次都没出现 —— - Scoreboard / TargetHUD / PlayerDisplay 绕过 drawRect/drawString 直接调 Rects.* 和 fontManager.sXX,导致 scale 及 bg/rounded/betterFont/fontShadow 全部失效。改回基类绘制路径,位置偏移按约定显式乘 scale - MiniMap 的 FBO 尺寸与背景贴图未乘 scale - PlayerDisplay 原本硬编码 Color(0,0,0,60),改用 backgroundColor 的同时在 构造器里覆盖该设置的默认值,外观不变但可调 - TargetHUD 的血条与头像保持裸绘制(它们是内容不是装饰,不应被 Background 开关关掉),仅显式缩放 其他修复: - getRealPosition 的 RT/LB/RB 分支用裸 width/height 定位,而 drawRect、hover 检测、拖拽钳制、blur 蒙版都用 width*scale —— 同一个类里两套约定,放大后的 右对齐组件会溢出屏幕 width*(scale-1) - ComponentsManager 两处 catch 把异常对象整个丢弃,只打一行固定字符串 × 每秒 60 帧。加 ClientLogger.error(String, Throwable) 重载,前 3 次带堆栈、 之后按 2 的幂降频,连续失败 60 帧自动禁用该组件,并在 catch 里复位 scissor/stencil/blend 防止污染后续渲染 - PotionDisplay 的 scissor 与 Keystrokes 的 stencil 改 try/finally。此前中途 抛异常会让 GL_SCISSOR_TEST 一直开着,整个游戏画面被裁到药水条的矩形内 - InterfaceHandler 对 getComponent(MiniMap.class) 加 null 检查,MiniMap 模块 未注册时该调用返回 null 会直接 NPE Co-Authored-By: Claude <noreply@anthropic.com>
This was referenced Jul 31, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
HUD 的公共外观设置由基类
Component.drawRect/drawString消费,注册却留在子类手写,两边没有任何机制保证一致。这是一个必须手动同步的重复,随时间必然分叉——而且子类手写注册其实零自由度:写不写都不影响行为(基类照读字段),只影响用户能不能在 UI 里看到,纯负担。实测分叉情况:
Keystrokes的背景色/圆角/间距在 ClickGUI 里看不到也改不了,锁死默认值且不进配置ModsList/BlockIndicator漏了rounded/roundRadius/fontShadowrounded传两次,addSettings不去重 → 渲染两个一样的开关Sprint/ToggleSneak/TargetDisplay不画背景,但bg默认true,开 blur 后糊出一块不存在的背景框改造后各模块的公共设置数完全由 Trait 决定,不再有分叉(
Keystrokes0→7、ModsList/BlockIndicator4→6、Sprint/ToggleSneak→2、MiniMap→0)。主要改动
Trait 声明式注册
InterfaceModule新增Trait{BACKGROUND, TEXT, SPACING},由ModuleManager.init()在所有模块构造完成后统一调用registerCommonSettings()追加。放在末尾是为了保持「模块自有设置在前、公共外观在后」的原有 UI 顺序。Trait 同时具备行为语义而不只是 UI 语义——
Component.hasBackground()检查Trait.BACKGROUND,所以无背景模块不会再被画 blur 蒙版。光靠「不注册」解决不了这个问题,因为bg字段永远存在且默认true。修复 scale 失效
22 个组件全部
allowScale = true,滚轮能滚、值会存进配置,但这 4 个的draw()里scale一次都没出现:Scoreboard/TargetHUD/PlayerDisplay— 绕过drawRect/drawString直接调Rects.*和fontManager.sXX,导致scale及bg/rounded/betterFont/fontShadow全部失效MiniMap— FBO 尺寸与背景贴图未乘scale按基类约定(位置偏移由调用方乘
scale,尺寸/字号由基类乘)改回基类路径。两处刻意保留裸绘制:TargetHUD的血条和玩家头像是内容而非装饰,不应被 Background 开关关掉,仅显式缩放。其他修复
getRealPosition的 RT/LB/RB 分支用裸width/height定位,而drawRect、hover 检测、拖拽钳制、blur 蒙版都用width * scale——同一个类里两套约定,放大后的右对齐组件溢出屏幕width * (scale - 1)ComponentsManager两处 catch 把异常对象整个丢弃,只打一行固定字符串 × 每秒 60 帧,比不打日志更糟(吞掉了堆栈)。加ClientLogger.error(String, Throwable)重载,前 3 次带堆栈、之后按 2 的幂降频,连续失败 60 帧自动禁用组件,并在 catch 里复位 scissor/stencil/blendPotionDisplay的 scissor 与Keystrokes的 stencil 改try/finally。此前中途抛异常会让GL_SCISSOR_TEST一直开着,整个游戏画面被裁到药水条的矩形内InterfaceHandler对getComponent(MiniMap.class)加 null 检查(该方法按mod.getClass() == clazz精确匹配,MiniMap 模块未注册时返回 null 会直接 NPE)行为变化
Sprint/ToggleSneak/TargetDisplay开启 HUD blur 时不再有多余的背景模糊块Keystrokes/ModsList/BlockIndicator多出若干原本被隐藏的设置项PlayerDisplay的背景色从硬编码变为可调(构造器里覆盖了默认值,外观不变)未验证
MiniMap模块在ModuleManager里是注释掉的状态(// modules.add(new MiniMap())),其 scale 改动为机械修改,未经实机验证。后续
HUD blur 的 stencil mask 几何问题(
drawBlurMask假设背景是位于(rX-2, rY)的单个矩形,对 Keystrokes/ArmorDisplay 等多矩形组件不成立,且因width/height在draw()内赋值而恒差一帧)留待下一个 PR,需要引入measure()阶段并让组件声明背景几何。🤖 Generated with Claude Code