【乾貨】《我的世界》Mod開發教程05:創造模式物品欄


3樓貓 發佈時間:2024-12-20 13:24:15 作者:甄別 Language

【乾貨】《我的世界》Mod開發教程05:創造模式物品欄-第0張

在這一期教程中,我們將介紹Forge的事件系統以及之前提到的創造模式物品欄。首先,我們可以用一個微波爐的比喻來理解事件系統。就像使用微波爐加熱食物一樣,在關注加熱完成的時間時,會留意微波爐是否發出“滴滴滴”的聲音,這就是監聽事件。一旦聽到聲音,你會對微波爐做出相應處理,比如檢查食物是否熱了,需要繼續加熱等。這一系列的操作就是事件處理,而事件發生則是指微波爐發出響聲。這就是事件系統的基本原理。

【乾貨】《我的世界》Mod開發教程05:創造模式物品欄-第1張

在遊戲中也存在許多事件,比如方塊放置、摧毀、物品丟棄、動物成長等都是事件。為了對這些關鍵事件做出反應,我們需要監聽這些事件並進行相應處理。事件大致可以分為兩類:一種是在Forge內部的事件,管理遊戲內發生的事件;另一種是在FML(Forge Mod Loader)下的事件,主要管理遊戲生命週期中的事件,與遊戲內內容無關,例如遊戲啟動時的方塊和物品註冊、配置文件加載等。

要了解Forge提供了哪些事件,可以在net.minecraft.forge包中查找。通過查看clientEV等類,可以找到各種事件。在代碼中展開查找用法,瞭解事件的具體應用及範圍,進而選擇合適的事件來使用。

【乾貨】《我的世界》Mod開發教程05:創造模式物品欄-第2張

在本期教程中,我們將註冊創造模式的物品欄,可以利用構建創造模式物品欄的事件來實現這一功能。

在使用事件時需要注意,事件分為兩種:一種是Forge事件,另一種是FML事件。要判斷一個事件屬於哪種類型,可以觀察其後綴。實現了mod bus EV接口的事件屬於FML事件。比如我們上次註冊物品時使用的是正一句,這個語句實際上獲取了FML事件總線,也就是mod事件。通過編寫事件處理函數並註冊即可使用事件。

假設我們編寫一個public void addCreativeTab函數,並將其註冊進去。在該函數中,參數event包含各種有用信息。例如,如果想將物品添加到某個欄位(比如functional blocks),可以查看Minecraft類中的creative mode tips等變量。通過event.getTab()來獲取creative mod tab對象,然後創建resource key對象或者使用getTypeKey方法來獲取資源鍵。接著在event.accept(myBlock)後將事件註冊即可。

【乾貨】《我的世界》Mod開發教程05:創造模式物品欄-第3張

通過bus.addListener(this::addCreativeTab)來註冊事件,這樣我們的函數就會被調用。啟動遊戲後,打開創造模式物品欄,應該能看到我們剛才註冊的functional block,這樣就實現了功能方塊的展示。

除了以上的方式外,還有其他註冊事件的方式。可以使用@SubscribeEvent註解和bus.register(this.getClass())的方式進行註冊,也可以註冊其他類如testMod.getClass()。這樣FML就會識別所有帶有@SubscribeEvent註解的方法並全部註冊。這種方式適用於需要註冊多個函數的情況,避免重複寫長串的@Listener。

【乾貨】《我的世界》Mod開發教程05:創造模式物品欄-第3張

需要注意的是,如果註冊的是一個類,而不是靜態方法,那麼註冊的方法必須是靜態的。非靜態方法只能在創建實例時調用,而靜態方法可以直接通過類來調用。因此,當註冊一個類時,必須將註冊方法改為靜態方法。

另一種方式是使用純註解的方式。可以將之前的方法註釋掉,然後創建一個公共靜態類,命名為EventListener,並將函數移到這個類中。在這個類的上方加上@EventSubscriber註解,指定bus等於mod id,即我們的mod id。同樣,這裡的方法也必須是靜態的。

【乾貨】《我的世界》Mod開發教程05:創造模式物品欄-第3張

還有一種方法是將代碼寫到一個新的類裡面。例如,新建一個包event,在其中新建一個Java類,命名為EventListener。將之前的代碼複製到這個類中,無需添加static關鍵字。導入mod id和myBlock,並修改名稱。這種方式也是可行的。

接著,我們可以在代碼中繼續編寫,例如添加if event.getTab()等於creative mod tabs的條件,將物品放入tools欄位,並通過event.accept(myItem)來實現。進入遊戲驗證後,確保功能方塊中有售貨機,工具欄中有兌換券,驗證註冊成功。

【乾貨】《我的世界》Mod開發教程05:創造模式物品欄-第3張

退出遊戲後回到代碼中,如果將bus後面的參數改成forge,那麼註冊的就是Forge事件。可以嘗試查找一個Forge事件,如實體或玩家內的某個boil event。將其改為ModEventListener,並再創建一個名為BusEventListener的類,使用@EventSubscriber註解,設置mod id為當前mod id,bus為forge,進行導入操作。

如果想要使骨粉對西瓜和南瓜等帶有"gourd"標籤的作物無效,可以編寫一個preventSteam方法,並將其中的事件類型改為BlockEvent。接著查看該事件可以獲取的參數,如level(方塊生長階段)、blockPos(方塊位置)、blockState(方塊狀態)和world(世界對象)。首先需要獲取方塊信息,可以通過getBlock()方法獲取到一個blockState對象,然後再根據需求獲取具體方塊信息。

【乾貨】《我的世界》Mod開發教程05:創造模式物品欄-第3張

在判斷方塊類型成功後,可以使用setCancelled(true)來取消事件。這樣一來,當我們用骨粉對西瓜種子進行操作時,發現骨粉完全無效,甚至手勢也沒有變化,說明事件被成功取消了。不過,其他作物如土豆是可以正常生長的。

如果需要修改方塊而不是取消事件,可以先存儲方塊信息到一個變量中,然後通過一系列操作來修改方塊狀態。比如可以設置方塊年齡或者讓其轉變成其他方塊,在原版代碼基礎上進行適當的更改即可。

【乾貨】《我的世界》Mod開發教程05:創造模式物品欄-第3張

最後別忘了將事件再次取消掉,通過event.setCancelled(true)實現。這樣就可以用自定義的方法替代原本的行為,實現特定功能的定製化。

接著進行測試,每次操作只會讓作物生長一格,注意到了嗎?但是當作物生長到最大階段後,遊戲崩潰了。這是因為最大的生長階段是七,我們設置了一個更高的值,導致遊戲崩潰。這個問題留給大家自行解決。

另外要提及的是,如果每個Mod都將註冊內容放在原版的註冊表中,那麼最終原版註冊表中將會有很多內容,難以找到對應的註冊項。解決方法是創建一個私有的靜態不可變DeferredRegister對象,命名為creativeTab,並將其與DeferredRegister.create結合使用。如果使用Forge Registry時找不到CreativeTab,可以使用原版的Registry.CreativeModTab。

【乾貨】《我的世界》Mod開發教程05:創造模式物品欄-第3張

然後再聲明一個公共的靜態不可變RegistryObject類型的CreativeModTab對象,並通過creativeMotabs.register方法來註冊自定義標籤。在這之後,可以使用CreativeModTab.Builder來添加標題和圖標等信息。創建一個兌換券的設計,設置DecayItems參數,並通過Output.accept方法添加自定義方塊和兌換券。最後,通過CreativeModTips.registerBus註冊事件總線,查看效果。

【乾貨】《我的世界》Mod開發教程05:創造模式物品欄-第3張

驗證效果後,發現頁面上有翻頁並且出現了Test Mod,成功添加了我們的內容。自定義創造模式的物品欄也已經設置完成。本期就講到這裡關於事件系統的內容,無需太複雜,一旦需要使用,可以再次調用。雖然事件系統還有很多內容可以探索,但沒必要全部講解,因為有些用法我本身也無法想象怎麼使用。只要在實際使用中遇到問題再去查看即可。所示例的用法例如難度更改等,你們應該能很容易地想到如何應用。查看參數並修改、獲取它們等都是可以的。

好了,這期教程就到這裡為止。


© 2022 3樓貓 下載APP 站點地圖 廣告合作:asmrly666@gmail.com