iT邦幫忙

0

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

圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友回答

立即登入回答