refactor(hud): 引入 measure 阶段并让组件声明背景几何 - #168
Closed
gaoyu06 wants to merge 1 commit into
Closed
Conversation
组件的 width/height 一直是在 draw() 内部赋值的,而下列路径全部在 draw() 之前 读取它们:锚点定位(getRealPosition)、hover 检测、拖拽边界钳制、blur 蒙版。 结果是所有组件的这些行为都滞后一帧 —— FPS 从 99fps 跳到 100fps 时右对齐组件的 右边缘会抖,进世界第一帧 width 还是 0,右对齐组件会闪现在屏幕最右缘。 新增 Component.measure()(默认空实现,未迁移的组件保持原状),由 ComponentsManager.measureAll() 在 GlobalListener 每帧开头统一调用一次, 早于 blur 蒙版与绘制两个 pass。 背景几何声明:新增 Component.backgroundShape(ShapeSink, originX, originY), drawBlurMask 据此生成蒙版而不再猜。此前蒙版假设「每个组件都是位于 (rX-2, rY)、 尺寸 width×height 的单个矩形」,这对约三分之二的组件成立,其余要么原点不同 (Keystrokes、PotionDisplay),要么画的是多个互不相连的方块(ArmorDisplay), 于是模糊会从缝隙里透出来或整体偏 2px。 - Keystrokes 声明每个键位框,并把 spacing 布局计算从 draw() 移到 measure(), 使蒙版拿到当帧偏移;键宽抽成 Key.renderWidth() 供 render 与 shape 共用, 避免空格键在两处算出不同宽度 - ArmorDisplay 声明 4 个槽位方块,槽位偏移抽成 slotOffset() 共用。顺带修复 该偏移此前未乘 scale —— 放大 HUD 时槽位会互相重叠 抽出 TextComponent:九个组件重复着逐字符相同的四行(量文字、定高、画框、画字), 差异只有字号、padding、框高、文字偏移。改为模板方法后每个降到 3-5 行,并自动 获得正确的 measure 时序。已迁移 FPS/CPS/Combo/Reach/Coords/Ping/Clock/PlayTime/ ServerAddress。 其中三个组件各自持有一份逐字符相同的 getLabel(),且都在 draw() 里对设置调用 setValue 写回默认值 —— 那会触发 EventValueChange 进而存盘,位于渲染路径上。 统一为 TextComponent.resolveLabel() 并去掉写回:设置为空时每帧重新解析即可, 显示结果不变。 同时补上几处缺失的 null 检查(CoordsDisplay/PingDisplay 此前直接解引用 mc.thePlayer),并让 TextComponent 在无内容时把尺寸归零,避免留下过期尺寸 让蒙版画出一个已经不存在的面板。 Co-Authored-By: Claude <noreply@anthropic.com>
Member
Author
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.
问题
组件的
width/height一直是在draw()内部赋值的,而下列路径全部在draw()之前读取它们:getRealPosition()(RT/RB/CT 分支都用 width/height 算偏移)所以所有组件的这些行为都滞后一帧。可观察到的表现:FPS 从
99fps跳到100fps时右对齐组件的右边缘抖一下;进世界第一帧width还是 0,右对齐组件闪现在屏幕最右缘。另一个问题是 blur 蒙版在猜几何:它假设每个组件都是位于
(rX-2, rY)、尺寸width × height的单个矩形。这对约三分之二的组件成立,其余要么原点不同(Keystrokes、PotionDisplay),要么画的是多个互不相连的方块(ArmorDisplay)——于是模糊从缝隙里透出来,或整体偏 2px。这是 #164 review 里遗留的那一项。改动
measure 阶段
新增
Component.measure(),默认空实现所以未迁移的组件保持原状。由ComponentsManager.measureAll()在GlobalListener每帧开头统一调用一次,早于 blur 蒙版和绘制两个 pass。背景几何声明
新增
Component.backgroundShape(ShapeSink, originX, originY),drawBlurMask据此生成蒙版。组件声明什么,蒙版就画什么——不再有猜测空间。Keystrokes声明每个键位框,并把 spacing 布局计算从draw()移到measure(),使蒙版拿到当帧偏移。键宽抽成Key.renderWidth()供render()与backgroundShape()共用,避免空格键在两处算出不同宽度ArmorDisplay声明 4 个槽位方块,偏移抽成slotOffset()共用。顺带修复该偏移此前未乘scale——放大 HUD 时槽位会互相重叠抽出 TextComponent
九个组件重复着逐字符相同的四行(量文字、定高、画框、画字),差异只有字号、padding、框高、文字偏移。改为模板方法后每个降到 3-5 行,并自动获得正确的 measure 时序。
已迁移:FPSDisplay、CPSDisplay、ComboDisplay、ReachDisplay、CoordsDisplay、PingDisplay、ClockDisplay、PlayTime、ServerAddressDisplay。
去掉渲染路径上的配置写入
ClockDisplay/PlayTime/ServerAddressDisplay各自持有一份逐字符相同的getLabel(),且都在draw()里对设置调用setValue写回默认值——那会触发EventValueChange进而存盘,位于渲染路径上。统一为TextComponent.resolveLabel()并去掉写回:设置为空时每帧重新解析即可,显示结果不变。其他
CoordsDisplay/PingDisplay缺失的mc.thePlayernull 检查(此前直接解引用)TextComponent在无内容时把尺寸归零,避免留下过期尺寸让蒙版画出一个已经不存在的面板兼容性
measure()默认空实现,13 个尚未迁移的组件行为完全不变,可以后续逐个迁移。已迁移组件的字号/padding/框高/文字偏移逐一核对过与原版一致(ComboDisplay的框高 16、文字偏移 4,Clock/PlayTime/ServerAddress的 padding 8、偏移 (2,3),其余用基类默认)。一处刻意的行为修正:文字偏移现在乘
scale,此前不乘,导致放大后文字相对背景框位置偏上。🤖 Generated with Claude Code