小地图叠加层渲染

基本信息

属性 值
事件处理器 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() 只在初始化时读一次)

相关条目