Minecraft 1.12.2 Mod開發筆記——新的GUI(待完成)/HUD


總目錄:Minecraft 1.12.2 Mod開發筆記

目錄

新的GUI(施工中...)

從 Gui 類的繼承關系上,大概就是下面這樣:

Gui
|- GuiButton 等小組件
|- HUD 組件
|- GuiScreen 
    |- GuiCreateWorld 等幾乎所有游戲界面
    |- GuiContainer 
        |- GuiChest 等各種帶有物品欄的東西,也就是游戲內彈出的各種用於交互的游戲GUI

新的GUI

ustc-zzzz的教程 里已經很詳細了,這里就簡單總結一下。

Minecraft的GUI大概分為

  • 顯示層,如GuiScreen/GuiContainer的子類,用於顯示
  • 邏輯處理,Container類,負責邏輯處理
  • 物品槽,slot,對應着顯示層中的一個物品槽
  • 管理類,IGuiHandler接口,負責協調調用

在界面中添加各種東西

  • 重寫GuiContainer.drawGuiContainerBackgroundLayer()用於畫背景圖
  • 重寫GuiContainer.initGui()方法用於初始化各種界面組件
  • 重寫GuiContainer.drawGuiContainerForegroundLayer()用於畫文字、物品等
  • 在Container構造器中使用addSlotToContainer()添加物品槽

GuiButton

最常見的按鈕,GuiContainer里使用一個buttonList來管理所有的按鈕。添加一個按鈕:

this.buttonList.add(new GuiButton(0, 0, 0, "my button"));

參數分別為按鈕ID、坐標x/y,按鈕文字。還有一個重載用於規定長寬。按鈕默認大小(200x20)與mc主界面的“單人游戲”等按鈕相同。

文字

文字使用FontRenderer對象的drawString(字符串,x,y,16進制顏色)方法來繪制,FontRenderer可通過this.fontRenderer獲得。其中16進制顏色不支持壓縮表示,6位為RGB,8位為aRGB。但據說某些情況下有一些顏色不匹配的問題,需要使用GlStateManager.color()來設置顏色。

線段

使用this.drawHorizontalLine(x1,x2,y,color)等系列方法繪制,方法和參數名通俗易懂。

文本框

文本框的添加稍微復雜,需要同時在initGui()updateScreen()mouseClicked()keyTyped()drawGuiContainerBackgroundLayer()中添加代碼才能得到一個正常的文本框,關鍵代碼見下:

public class MyGUI extends GuiContainer {
    GuiTextField textField;
    public void initGui() {
        super.initGui();    
        textField = new GuiTextField(1,this.fontRenderer,50,50,200,20); // 初始化
    }
    public void updateScreen() {
        super.updateScreen();
        textField.updateCursorCounter();
    }
    protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
        super.mouseClicked(mouseX, mouseY, mouseButton);
        textField.mouseClicked(mouseX,mouseY,mouseButton); // 打開文本框點擊獲得焦點的功能
    }
    protected void keyTyped(char typedChar, int keyCode) throws IOException {
        super.keyTyped(typedChar, keyCode);
        textField.textboxKeyTyped(typedChar,keyCode); // 打開文本框輸入功能
    }
    protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
        this.drawDefaultBackground();
        this.textField.drawTextBox(); // 繪制文本框
    }
}

物品槽

界面交互

物品槽交互

界面交互通常使用重寫匿名內部類方法的形式,以下列舉幾個常用的

this.addSlotToContainer(new SlotItemHandler(items,0,0,0){
    {
        // 構造器內
        this.putStack(new ItemStack(Items.APPLE, 5));         // 比如初始物品什么的
    }
    public int getItemStackLimit(@Nonnull ItemStack stack) {} // 最大數量
    public boolean canTakeStack(EntityPlayer playerIn) {}     // 是否能取出
    public boolean isItemValid(@Nonnull ItemStack stack) {}   // 是否能放入
    public void onSlotChanged() {}                            // 當前物品槽內發生變化時
});

按鈕交互

在GuiContainer中重寫actionPerformed()實現按鈕交互:

@Override
protected void actionPerformed(GuiButton button) throws IOException {
    if (button == myButton){}
}

新的HUD

HUD(Head Up Display),簡單來說就是游戲界面上方實時顯示的各種面板,比如經驗條、血條、物品欄、十字准星等等。下面舉個例子,在游戲界面兩側各顯示一張圖片。通常會把多張圖片組合成一張圖片,使用代碼來控制顯示圖片的哪些區域。在這里圖片大小是128x64。

HUD界面

新建 MyHUD.java 繼承Gui類。Gui類已經實現了一些繪制方法。原版的 HUD 在 GuiIngame 類中定義,可供參考。

public class MyHUD extends Gui {
    // 材質圖
    public static final ResourceLocation hud = new ResourceLocation(MyMod.MODID,"textures/gui/my_hud.png");
    // mc 實例,方便使用
    private Minecraft mc;

    public MyHUD() {
        this.mc = Minecraft.getMinecraft();
    }

    public void render() {
        ScaledResolution r = new ScaledResolution(this.mc);
        this.mc.getTextureManager().bindTexture(hud);
        int win_w = r.getScaledWidth();
        int win_h = r.getScaledHeight();
        // 分別畫左右兩邊的圖
        drawModalRectWithCustomSizedTexture(win_w/3-32, win_h/2-32, 0, 0, 64, 64, 128, 64);
        drawModalRectWithCustomSizedTexture(win_w/3*2-32, win_h/2-32, 64, 0, 64, 64, 128, 64);
    }
}
  • ScaledResolution 類用於獲取Minecraft游戲窗口的真實大小,不知道為什么,minecraft實例的displayWidth/displayHeight並不是真實窗口大小。
  • 自定義render()方法來繪制HUD界面
  • drawModalRectWithCustomSizedTexture(x,y,u,v,w,h,textureWidth,textureHeight) 方法表示:將材質圖縮放為(textureWidth,textureHeight)大小,然后取材質圖上的區域(u,v,u+w,v+h),畫到屏幕上的區域(x,y,x+w,y+h)。Gui類中還有很多 draw 系列方法可供使用。

加載HUD

Minecraft 中提供了 RenderGameOverlayEvent 事件來管理HUD的加載,它還有 PrePost 等子事件可供使用

public static final MyHUD hud = new MyHUD();

@SubscribeEvent
public static void onHUDRender(RenderGameOverlayEvent event){
    if (event.getType() != RenderGameOverlayEvent.ElementType.ALL) {
        return;
    }
    // other code
    hud.render();
}
  • 枚舉 RenderGameOverlayEvent.ElementType 中規定了一些原版中特殊的HUD,可以通過這個來控制原版HUD的顯示,event.setCanceled(true);后,相應的HUD不再繪制。
  • 調用剛才寫的渲染方法 render() 來繪制HUD
  • RenderGameOverlayEvent 類也有一個 ScaledResolution 成員可供使用

最終效果如下,暫時不清楚如何正確顯示透明區域。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM