Minecraft 1.12.2 Mod開發筆記——前期准備


總目錄:Minecraft 1.12.2 開發筆記

Forge是什么

  • Minecraft是商業軟件,源代碼不公開
  • MCP項目反編譯了Minecraft,為我們提供了Minecraft的“源代碼”,即便並不是Mojang工作室寫的那樣
  • Forge是MinecraftForge和Forge Mod Loader(FML)的總稱。MinecraftForge基於MCP,提供了Minecraft中的各種機制的實現接口,如事件系統,物品注冊等等。而FML,顧名思義,Mod加載器,開始游戲加載界面右下角不斷敲打的鐵砧就是它了。

Side

Minecraft擁有雙客戶端/服務端的結構,具體來說,就是:

  • Minecraft有顯然的物理客戶端,即我們運行的Minecraft本體,還有顯然的物理服務端,即多人服務器運行的server.jar。
  • 在每一個物理客戶端內部,還有所謂的邏輯客戶端和邏輯服務端,比如,所有的游戲邏輯放在邏輯服務端,而實體渲染等放在邏輯客戶端。

事件

和 Java 中 AWT 和 Swing 類似,Minecraft 中的行為也是事件驅動的,我們需要為事件掛載事件監聽器,當相應事件觸發時,對應的監聽器中的代碼就會執行。

Mod開發中有兩大類事件:

  1. FML事件(FML 生命周期)

    主要分為 preinit,init 和 postinit 等,顧名思義,就是加載 Mod 的三個階段,通常來講,preinit 階段進行物品、方塊等的注冊,init 階段進行合成表的注冊,postinit 進行 Mod 之間的關聯處理。

  2. Forge事件

    Forge 事件需要掛載到事件總線上,主要有:

    • 一般事件總線(MinecraftForge.EVENT_BUS)
    • 礦物生成總線(MinecraftForge.ORE_GEN_BUS)
    • 地形生成總線(MinecraftForge.TERRAIN_GEN_BUS)

    掛載方法:

    EventListener 類

    @SubscribeEvent
    public static void onSomeEventHappened(AEvent event) {
        // 當然這個 AEvent 要換成某個存在的事件。
    }
    // 注冊
    MinecraftForge.EVENT_BUS.register(EventListener.class);
    

    或者

    @SubscribeEvent
    public void onSomeEventHappened(AEvent event) {
        // 當然這個 AEvent 要換成某個存在的事件。
    }
    // 注冊
    MinecraftForge.EVENT_BUS.register(new EventListener());
    

    有沒有感覺很熟悉呢?

    public void actionPerformed(ActionEvent e){
        // TODO
    }
    new JButton().addActionListener(this);
    

    個人認為,Minecraft Forge 的事件系統就可以類比 AWT/Swing 里的監聽器來理解。

    其中,注解 @SubscribeEvent 表明下面的方法是一個事件監聽器,也就是說監聽器方法的名字不是固定的,監聽的事件由參數指定。

    此外,也可以這么寫,用於將事件直接注冊到 EVENT_BUS 上:

    // 這個注解的意思是“將這個類注冊到事件總線中去,該事件監聽器屬於 mymod 這個 Mod”
    // 它相當於 MinecraftForge.EVENT_BUS.register(MyEventListener.class)
    @Mod.EventBusSubscriber(modid = "mymod")
    public final class MyEventListener {
        @SubscribeEvent
        public static void onEventFired(ACertainEvent event) {
    
        }
    }
    

Mod的基本框架

  1. 首先,在src/main/java/目錄下新建項目所在包,比如 moonfan.mymod

  2. 在mymod包內新建Java類,建議類名即Mod名的駝峰命名形式,這就是Mod的主類了,這里就是 MyMod.java 。

  3. 復制以下代碼,包名和modid自行修改。

    MyMod.java

     @Mod(modid = MyMod.MODID, name = MyMod.NAME, version = MyMod.VERSION, acceptedMinecraftVersions = "1.12.2")
     public class MyMod {
         public static final String MODID = "mymod";
         public static final String NAME = "My Mod";
         public static final String VERSION = "1.0.0";
    
         @Mod.Instance(MyMod.MODID)
         public static MyMod instance;
    
         @SidedProxy(clientSide = "moonfan.mymod.client.ClientProxy",
                 serverSide = "moonfan.mymod.common.CommonProxy")
         public static CommonProxy proxy;
    
         @Mod.EventHandler
         public void preInit(FMLPreInitializationEvent event) {
             proxy.preInit(event);
         }
         @Mod.EventHandler
         public void init(FMLInitializationEvent event) {
             proxy.init(event);
         }
         @Mod.EventHandler
         public void postInit(FMLPostInitializationEvent event) {
             proxy.postInit(event);
         }
     }
    
  • @Mod 和 @Mod.Instance 注解對mod信息進行引用
  • 前面介紹了Forge中的Side概念,@SidedProxy即為對Common(Server)和Client的引用,這是之后要創建的兩個類。
  • 前面介紹了Forge的事件系統,@Mod.EventHandler 則標識了三個FML事件,三個方法分別對應三個事件,調用proxy的對應方法。
  1. 新建 moonfan.mymod.common.CommonProxymoonfan.mymod.client.ClientProxy 類,且ClientProxy繼承自CommonProxy:

    CommonProxy.java

     public class CommonProxy {
         @Mod.EventHandler
         public void preInit(FMLPreInitializationEvent event) {
             // TODO
         }
         @Mod.EventHandler
         public void init(FMLInitializationEvent event) {
             // TODO
         }
         @Mod.EventHandler
         public void postInit(FMLPostInitializationEvent event) {
             // TODO
         }
     }
    

    ClientProxy.java

     public class ClientProxy extends CommonProxy {
         @Override
         public void preInit(FMLPreInitializationEvent event) {
             super.preInit(event);
         }
         @Override
         public void init(FMLInitializationEvent event) {
             super.init(event);
         }
         @Override
         public void postInit(FMLPostInitializationEvent event) {
             super.postInit(event);
         }
     }
    

這樣,Mod的基本框架完成了。


免責聲明!

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



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