iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 8
1
Software Development

[Minecraft - 當個創世神] 從玩遊戲到設計遊戲系列 第 8

[Day8] Minecraft版的俄羅斯娃娃(中)

昨天穿著鑽石裝的殭屍參考程式碼:

@SubscribeEvent
public void giveArmor(EntityJoinWorldEvent event) {
    if(event.entity instanceof EntityZombie) {
        event.entity.setCurrentItemOrArmor(0, new ItemStack(Items.diamond_sword));
        event.entity.setCurrentItemOrArmor(1, new ItemStack(Items.diamond_chestplate));
        event.entity.setCurrentItemOrArmor(2, new ItemStack(Items.diamond_leggings));
        event.entity.setCurrentItemOrArmor(3, new ItemStack(Items.diamond_boots));
        event.entity.setCurrentItemOrArmor(4, new ItemStack(Items.diamond_helmet));
    }
}

回到正題,我們繼續完成前天未完成的課題 - 俄羅斯娃娃

今天我們需要再重新思考一次整個流程:

透過建立新的豬實體,產生另外一個縮小比例的豬實體

  1. 進入點確定是EntityJoinWorldEvent,所以我們先建立一個新的事件類別PigDoll_v2,並且加上EntityJoinWorldEvent事件
    public class PigDoll_v2 {
        @SubscribeEvent
        public void pigDoll(EntityJoinWorldEvent event) {
        }
    }
    
  2. 還記得昨天說的BoundingBox嗎?在官方網站其中文翻作碰撞箱。關於碰撞箱的一些介紹,有興趣的朋友可以點連結看一下,我們這邊的重點要放在另外一件事

實體的初始化與變更大小影響的是碰撞箱範圍,而不是真實在畫面看到的樣子
根據以上的描述,我們接下來會需要處理兩塊:一個是碰撞箱的縮小、另一個是真實畫面渲染的縮小

  1. 首先,先在com.ithome.mymod下加入一個新的package名為entities,並且加入二個類別,EntityScalePig、RenderScalePig
    • EntityScalePig:自定義可以變更大小的豬實體類別 (實際是碰撞箱大小)
    • RenderScalePig:自定義可以變更渲染大小的豬 (實際是畫面看到的大小)
      https://ithelp.ithome.com.tw/upload/images/20190923/201158232bNHs6nYd6.png
  2. 當遊戲啟動的時候,Minecraft會嘗試載入所有的物件;我們新增加的實體需要註冊到Minecraft內。請回到主程式,在我們的init()方法前面加入另一個preInit()方法,告訴Minecraft這個是在初始化前需要先做的事情 (我們的實體註冊需要在初始化之前完成)
    @EventHandler
    public void preInit(FMLPreInitializationEvent event) {
        Set ids = EntityList.idToClassMapping.keySet();
        int availableId = 1;
        while (EntityList.getClassFromID(availableId) != null) {
            availableId++;
        }
        EntityRegistry.registerGlobalEntityID(EntityScalePig.class, EntityScalePig.name, availableId);
    }
    
    這裡的FMLPreInitializationEvent是Forge在初始化前會執行的事件。我們在這邊透過EntityRegistry的registerGlobalEntityID方法來註冊一個global的實體;其中
    • 第一個參數是我們要註冊的類別
    • 第二個參數是要註冊的名字,這邊會有紅字沒關係,我們等會再修正
    • 第三個參數是實體的唯一ID,我們透過EntityList來找可以用的ID
  3. 回到EntityScalePig類別,加上下面的程式碼
    public class EntityScalePig extends EntityPig {
    
        public static final String name = "MyPig";
    
        public EntityScalePig(World worldIn) {
            super(worldIn);
        }
    
        public void scale(float scale) {
            this.setSize(width * scale, height * scale);
        }
    }
    
    這裡我們透過extends關鍵字來擴展實體豬類別EntityPig,並且定義剛剛在主程式用到的name,注意:這個名字也必須要唯一。另外,因為這個類別需要能夠控制大小,我們額外加了一個scale(float scale)方法來定義這個實體的大小。
  4. 在RenderScalePig類別內,加上下面的程式碼
    @SideOnly(Side.CLIENT)
    public class RenderScalePig extends RenderLiving {
    
        private static final ResourceLocation textures = new ResourceLocation("textures/entity/pig/pig.png");
    
        private float scale = 1.0f;
    
        public RenderScalePig(RenderManager renderManager, ModelBase modelBase, float shadowSize)
        {
            super(renderManager, modelBase, shadowSize);
        }
    
        public void setScale(float scale) {
            this.scale = scale;
        }
    
        protected void preRenderCallback(EntityLivingBase entityLivingBase, float tickTime)
        {
            GlStateManager.scale(this.scale, this.scale, this.scale);
        }
    
        @Override
        protected ResourceLocation getEntityTexture(Entity entity)
        {
           return textures;
        }
    }
    
    這裡我們一步一步來說明:
    • 我們在最前面用上@SideOnly(Side.CLIENT)來指名這個類別只能被客戶端的邏輯呼叫。因為這個類別是屬於渲染畫面的類別,不需要在伺服器端執行,因此我們加上這段來確保這個類別不會被意外呼叫。
    • 這個類別extends的類別是RenderLiving,一個用來渲染生物的基礎類別;在RenderLiving的開頭也可以看到@SideOnly的註釋說明渲染只需要使用在客戶端。
    • 我們宣告一個ResourceLocation,指定內建的豬實體資源。這樣我們就不用再自行畫一個豬的圖片。
    • setScale(float scale)的方法,一樣提供一個可以改變渲染大小的方法。
    • 在preRenderCallback()的方法內可以看到我們在前天使用GLStateManager來改變大小的方法;這個方法會由Minecraft內部呼叫,我們只需要改變它實際執行的行為是變更我們渲染的大小。
    • 最後複寫這個類別需要實作的方法,回傳我們實體的資源(texture)

好了,今天就先到這邊,我們明天會再繼續將PigDoll_v2類別的程式碼完成。

關於今天的程式碼內容,不是很了解沒關係,但還是希望有興趣的朋友們可以照順序也自己完成一次,這樣我們後面在說明模組的處理流程會有比較清楚的概念。

這個模組目前似乎還沒有人做出來過...若是有概念不清楚的地方歡迎提問,我會就我所理解的盡可能地回答~


上一篇
[Day7] Minecraft Forge的事件註冊
下一篇
[Day9] Minecraft版的俄羅斯娃娃(下)
系列文
[Minecraft - 當個創世神] 從玩遊戲到設計遊戲30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言