iT邦幫忙

1

minecraft模組製作遇到BUG

  • 分享至 

  • xImage

我想做一個minecraft1.18.2-40.3.0(forge)的模組,其中有一個檔案(ClientEvent.java)一直出錯,AI也找不出原因,所以想來求救,以下為程式碼:

package com.alex.cultivationera.events;

import com.alex.cultivationera.CultivationEra;
import com.alex.cultivationera.common.capability.PlayerDataProvider;
import com.alex.cultivationera.common.systems.RealmData;
import com.alex.cultivationera.core.init.AttributeInit;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiComponent;
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
import net.minecraftforge.api.distmarker.Dist;
// 導入新的事件類
import net.minecraftforge.client.event.RenderGuiEvent;
import net.minecraftforge.client.event.RenderGuiOverlayEvent;
// 導入新的 Overlay 標識
import net.minecraftforge.client.gui.overlay.VanillaGuiOverlay;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

@Mod.EventBusSubscriber(modid = CultivationEra.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE, value = Dist.CLIENT)
public class ClientEvents {

@SubscribeEvent
public static void onRenderGuiOverlayPre(RenderGuiOverlayEvent.Pre event) {
    // 使用新的 Overlay 標識 (id) 來判斷,並取消原版 HUD 元素
    var id = event.getOverlay().id();
    if (id.equals(VanillaGuiOverlay.PLAYER_HEALTH.id())
            || id.equals(VanillaGuiOverlay.ARMOR_LEVEL.id())
            || id.equals(VanillaGuiOverlay.FOOD_LEVEL.id())
            || id.equals(VanillaGuiOverlay.EXPERIENCE_BAR.id())
            // (可選) 根據 GPT-5 建議,一併取消其他元素
            || id.equals(VanillaGuiOverlay.AIR_LEVEL.id())
            || id.equals(VanillaGuiOverlay.MOUNT_HEALTH.id())
            || id.equals(VanillaGuiOverlay.JUMP_BAR.id())
    ) {
        event.setCanceled(true);
    }
}

// 使用 RenderGuiEvent.Post 在所有元素繪製完畢後執行,繪製自訂 HUD
@SubscribeEvent
public static void onRenderGuiPost(RenderGuiEvent.Post event) {
    Minecraft mc = Minecraft.getInstance();
    if (mc.player == null) return;

    // 從 RenderGuiEvent.Post 中獲取 PoseStack
    PoseStack poseStack = event.getPoseStack();
    // 直接從 Minecraft 實例獲取視窗寬度
    int screenWidth = mc.getWindow().getGuiScaledWidth();

    mc.player.getCapability(PlayerDataProvider.PLAYER_DATA).ifPresent(data -> {
        AttributeInstance qixueAttr = mc.player.getAttribute(AttributeInit.QIXUE.get());
        double currentQixue = qixueAttr != null ? qixueAttr.getValue() : 0;
        // *** 注意:maxQixue 應取 BaseValue,代表基礎值,而非 getValue() ***
        double maxQixue = qixueAttr != null ? qixueAttr.getBaseValue() : 1;

        double currentMana = data.getMana();
        AttributeInstance intelAttr = mc.player.getAttribute(AttributeInit.INTELLIGENCE.get());
        // *** 注意:maxMana 應取 BaseValue ***
        double maxMana = intelAttr != null ? intelAttr.getBaseValue() * 10 : 1;

        double currentCultivation = data.getCultivation();
        RealmData.RealmInfo realmInfo = RealmData.getRealmInfo(data.getRealmLevel());
        double maxCultivation = (realmInfo != null && realmInfo.getCultivationNeeded() > 0) ? realmInfo.getCultivationNeeded() : 1;
        String realmName = realmInfo != null ? realmInfo.getName() : "未知境界";

        // --- 開始繪製 HUD ---
        drawBar(poseStack, mc.font, 5, 5, 120, 10, 0x99C0C0C0, 0xFFFFFF00, currentCultivation, maxCultivation, "修為");
        drawBar(poseStack, mc.font, 5, 18, 120, 10, 0x99800000, 0xFFFF0000, currentQixue, maxQixue, "氣血");
        drawBar(poseStack, mc.font, 5, 31, 120, 10, 0x99000080, 0xFF0000FF, currentMana, maxMana, "法力");

        int realmNameWidth = mc.font.width(realmName);
        // 使用 drawShadow 繪製境界名稱,效果更佳
        mc.font.drawShadow(poseStack, realmName, screenWidth - realmNameWidth - 5, 5, 0xFFFFFFE0);
    });
}

// drawBar 方法保持不變 (已修正為使用 font.drawShadow)
private static void drawBar(PoseStack poseStack, Font font, int x, int y, int width, int height, int bgColor, int fgColor, double current, double max, String prefix) {
    GuiComponent.fill(poseStack, x, y, x + width, y + height, bgColor);
    double ratio = max > 0 ? Math.min(Math.max(current / max, 0), 1) : 0; // 確保比例在 0-1
    int fgWidth = (int) (ratio * width);
    if (fgWidth > 0) {
        GuiComponent.fill(poseStack, x, y, x + fgWidth, y + height, fgColor);
    }
    String text = String.format("%s: %.0f / %.0f", prefix, current, max);
    int textWidth = font.width(text);
    font.drawShadow(poseStack, text, x + (width - textWidth) / 2f, y + 1, 0xFFFFFFFF);
}

}

另外有需要我提供其他檔案請告訴我,以下提供錯誤跟資料夾結構截圖:
https://ithelp.ithome.com.tw/upload/images/20251023/20180303U10aPSFT1T.pnghttps://ithelp.ithome.com.tw/upload/images/20251023/201803037ckdLxHCQq.pnghttps://ithelp.ithome.com.tw/upload/images/20251023/20180303AvOopCA9Pt.png

看更多先前的討論...收起先前的討論...
Cavey iT邦新手 5 級 ‧ 2025-10-26 12:00:36 檢舉
可以提供錯誤訊息 大家比較好抓原因
史帝夫 iT邦新手 1 級 ‧ 2025-10-27 10:08:06 檢舉
你所導入新的事件類、Overlay 標識...
在 1.18.2 版本中這些類別已經被移除或替換了,
所以會因為無法導入而報錯。

在使用 AI 工具時,可描述你當下想開發的版本,
以便於它能提供你符合該版本的修正
Hey! I’ve checked through your code, and the main issue likely comes from Forge’s newer event class changes between versions 1.18.2 and 1.19+. Specifically, in Forge 40.3.0 (for Minecraft 1.18.2), the RenderGuiEvent and RenderGuiOverlayEvent systems are structured differently from later versions, so methods like getPoseStack() or getOverlay().id() might not exist or work as expected in your current build.

Here’s what you can do:

✅ 1. Check imports carefully
Make sure the RenderGuiOverlayEvent you’re importing is from the correct package:

import net.minecraftforge.client.event.RenderGameOverlayEvent;


and replace the newer overlay handling with RenderGameOverlayEvent.Pre and RenderGameOverlayEvent.Post. The new RenderGuiOverlayEvent only exists in newer versions of Forge (post 1.19).

✅ 2. Adjust your event usage
Change your event methods to use the proper Forge 1.18.2 classes:

@SubscribeEvent
public static void onRenderOverlay(RenderGameOverlayEvent.Post event) {
PoseStack poseStack = event.getMatrixStack(); // instead of getPoseStack()
...
}


and update your logic accordingly.

✅ 3. Double-check your mod dependencies
Make sure your mappings and Forge version match what your build.gradle specifies — mismatched mappings can also trigger “unknown method” or “cannot resolve symbol” errors.

If youre testing UI overlays, try simplifying your bar rendering in a dummy mod to verify the rendering pipeline works before reintroducing your full logic.

I faced a similar issue when customizing a HUD for a small fan mod project — the behavior was identical to when I was optimizing game overlays for Stick War Legacy mod apk
(available at thestickwarlagacyapk.com). The key was always matching the event hooks with the version-specific Forge methods.

Once you make those event class adjustments, your mod should build and render correctly!
謝謝
我會再試試看
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友回答

立即登入回答