小地图叠加层渲染
基本信息
| 属性 | 值 |
|---|---|
| 事件处理器 | journeymap.client.forge.event.MiniMapOverlayHandler(MiniMapOverlayHandler.java:39) |
| 事件总线 | MinecraftForgeBus(getBus(),:56-60) |
| 事件 | RenderGameOverlayEvent(:105-106) |
| 事件优先级 | EventPriority.NORMAL(两个处理器均是) |
| 绘制调用 | UIManager.getInstance().drawMiniMap(event.partialTicks)(:120) |
| Profiler 段名 | journeymap(:118、:122) |
| 注册位置 | EventHandlerManager.registerGuiHandlers()(EventHandlerManager.java:42) |
功能
小地图不是一个 GuiScreen,而是挂在 Forge 的 RenderGameOverlayEvent 上直接绘制到 HUD 层。这样它可以出现在任何界面之上,且不需要打断游戏循环。
两个处理器
MiniMapOverlayHandler 注册了两个 @SubscribeEvent 方法:
| 方法 | 事件类型 | 条件 | 行为 |
|---|---|---|---|
onRenderOverlayDebug |
RenderGameOverlayEvent.Text |
mc.gameSettings.showDebugInfo(F3 调试屏) |
往 event.left 追加制图统计行(:62-98) |
onRenderOverlay |
RenderGameOverlayEvent(基类) |
event.type == EVENT_TYPE && event.isCancelable() == EVENT_PRE |
绘制小地图本体(:105-130) |
渲染时机控制
渲染挂在哪个阶段由两个非 @Config 字段决定(CoreProperties.java:145-146):
| 字段 | 初值 | 作用 |
|---|---|---|
renderOverlayEventTypeName |
RenderGameOverlayEvent.ElementType.ALL.name() |
目标叠加层类型,经 getRenderOverlayEventType() 解析为枚举(CoreProperties.java:168-171) |
renderOverlayPreEvent |
true |
true = 在 PRE 阶段绘制,false = 在 POST 阶段绘制 |
checkEventConfig()(MiniMapOverlayHandler.java:50-54)把这两个值读入静态字段 EVENT_TYPE / EVENT_PRE:
EVENT_TYPE = JourneymapClient.getCoreProperties().getRenderOverlayEventType();
EVENT_PRE = JourneymapClient.getCoreProperties().renderOverlayPreEvent.get();
event.isCancelable() == EVENT_PRE 这个判断(:110)把"当前事件是 PRE 还是 POST"与配置对齐——RenderGameOverlayEvent.isCancelable() 在 PRE 阶段返回 true、POST 阶段返回 false,因此改 renderOverlayPreEvent 就能决定 JourneyMap 画在其他模组叠加层的前面还是后面。
制图状态耦合
onRenderOverlay() 的绘制条件是(:116):
if (jm.isMapping() || !JourneymapClient.getCoreProperties().mappingEnabled.get())
即:正在制图时,或制图总开关被关闭时才画小地图。反过来,制图已开启且当前空闲时不画——避免与其它 HUD 元素争抢。
jm 字段懒加载(:112-115)。
F3 调试屏输出
onRenderOverlayDebug()(:62-98)在 F3 打开时输出:
- 制图已启用:遍历
MapPlayerTask.getDebugStats(),每行加DEBUG_PREFIX(§b[JM] §r,:41)前缀(:70-76) - 制图已禁用:输出
Constants.getString("jm.common.enable_mapping_false_text")(:79) - 另在
mc.gameSettings.showDebugProfilerChart打开时,每 3000 ms 抓一次StatTimer.getReportByTotalTime()并追加(:82-96),用statTimerCheck做节流
两个处理器都用 catch (Throwable t) 包住全部逻辑,异常走 JMLogger.logOnce() 只记一次(:99-102、:126-129),不会让小地图崩溃游戏。
11 个客户端事件处理器
EventHandlerManager 把事件处理分成两组(forge/event/EventHandlerManager.java):
| 组 | 方法 | 注册的处理器 |
|---|---|---|
| 通用 | registerGeneralHandlers()(:28-38) |
ChatEventHandler、StateTickHandler、WorldEventHandler、ChunkUpdateHandler、WaypointBeaconHandler、TextureAtlasHandler、WorldInfoHandler(7 个) |
| GUI | registerGuiHandlers()(:40-45) |
MiniMapOverlayHandler、KeyEventHandler(2 个) |
加上服务端 JourneymapServer 侧的 ForgeEvents,全 mod 共 12 个 @SubscribeEvent 方法(客户端 11 + 服务端 1)。两个注册方法在 JourneymapClient.postInitialize() 中调用(JourneymapClient.java:298-299)。
数值
| 数值名 | 值 |
|---|---|
本类 @SubscribeEvent 数 |
2 |
| 事件优先级 | NORMAL(两个均是) |
| 调试统计刷新间隔 | 3000 ms(:84) |
| 默认渲染阶段 | PRE(renderOverlayPreEvent 默认 true) |
| 默认目标叠加层 | ElementType.ALL |
| Profiler 段名 | journeymap |
| 通用事件处理器数 | 7 |
| GUI 事件处理器数 | 2 |
全 mod @SubscribeEvent 总数 |
12 |
交互
| 触发 | 行为 |
|---|---|
| 每帧渲染 HUD | 满足条件时 drawMiniMap(partialTicks) |
| 按 F3 | 叠加制图统计与(若开启)性能计时报告 |
mappingEnabled 关闭 |
仍绘制小地图(显示上次已渲染的地图) |
| 正在制图 | 绘制小地图,实时反映新渲染的区块 |
| 收到雷达禁用控制码 | UIManager.reset() 后小地图不再显示实体标记 |
| 切换渲染阶段配置 | 需重启游戏(checkEventConfig() 只在初始化时读一次) |