iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 18
2

https://ithelp.ithome.com.tw/upload/images/20191002/201158232P0vWzgrQM.png

今天開始來說說配方(recipe)的功能。在Minecraft世界內,有三種不同類型的配方:

  1. 合成(Crafting):分為有形配方(shaped)與無形配方(shapeless),用來產生新的物品或方塊
  2. 燒煉(Smelting):將一個物品或方塊變成另一個物品或方塊
  3. 釀造(Brewing):用來製作藥水

我們先從合成開始吧!

合成

合成是在Minecraft世界中要生存一定要學會的技能。我們在[第二天]有提到樹木可以用來合成工作台,而合成得到的工作台就是利用配方(其實是有形配方)並且使用合成類型

我們這邊就從工作台的配方來說明我們要如何製作新的合成配方。

在Forge的原始程式碼內,net.minecraft.item.crafting套件下有一個RecipesCrafting類別,這裡定義了一些基礎的合成配方,在其中有一個工作台的合成配方程式碼:

p_77589_1_.addRecipe(
    new ItemStack(Blocks.crafting_table),
    new Object[] {"##", "##", '#', Blocks.planks}
);

p_77589_1_代表的是CraftingManager物件,不是重點我們先不要管它。
我們看addRecipe()提供的兩個參數:

  1. ItemStack:由這個配方所產生的物品堆(ItemStack),這邊定義了這個合成配方所摻生的物品是什麼(只會有一個物品,但可以是複數);我們這邊定義這個配方產生的東西是Blocks.crafting_table,即工作台方塊這個物件。

  2. recipeComponents:配方定義的內容。這邊會使用一個Java物件陣列包裝,這個物件陣列的內容格式我用Regex正則表達式來說明:

    第一部分:(\".{1,3}\"){1,3}
    第二部分:\'\S\'
    第三部分:Item、Block或ItemStack物件
    

    a. 第一部分用來描述這個合成配方會使用的位置對應,規定每一個字串都需要用雙引號"包起來。舉例來說:

    • "XXX", "XXX", "XXX" : 表示合成需要三列,並且每一列都是填滿指定物品
      https://ithelp.ithome.com.tw/upload/images/20191001/20115823YC4BvekUnm.png
    • "X X", "XXX", "X X" (注意有空白) : 表示合成需要三列,第一與第三列的中間行是空的,其他地方填滿指定物品
      https://ithelp.ithome.com.tw/upload/images/20191001/20115823j8dEsLEkOM.png
    • "XX ", "XX " (注意有空白) : 表示合成需要連續兩列,這兩列都必須是首兩行有指定物品
      https://ithelp.ithome.com.tw/upload/images/20191001/20115823FIC5qIql0M.png or https://ithelp.ithome.com.tw/upload/images/20191001/20115823J4AqeUNVO6.png
    • "XX" : 表示合成需要任意一列,這一列需要連續兩行有指定物品 (下面幾種都合配方規則)
      https://ithelp.ithome.com.tw/upload/images/20191001/20115823DizT3Nx8eF.png or https://ithelp.ithome.com.tw/upload/images/20191001/2011582335iLm1g4M3.png or https://ithelp.ithome.com.tw/upload/images/20191001/20115823IXizs6WtLS.png or https://ithelp.ithome.com.tw/upload/images/20191001/20115823MOegxyrjL3.png

    b. 第二部分與第三部分是一組的,這裡規定第二部分的字元都需要用單引號'包起來。用來描述合成配方中的字元代表是什麼物品。舉例來說:

    • 'X', Blocks.sand : 表示描述配方中的X這個字元代表是這個方塊
    • '#', Items.apple : 表示描述配方中的#這個字元代表是蘋果這個物品
    • 'A', Blocks.glass, 'B', new ItemStack(Items.diamond_sword) : 表示描述配方中的A這個字元代表是玻璃這個方塊,而B這個字元代表是鑽石劍這個物品

回到一開始的工作台合成配方:

addRecipe(
    new ItemStack(Blocks.crafting_table),
    new Object[] {"##", "##", '#', Blocks.planks}
);

這裡就可以很清楚知道它的製作方式:

需要連續兩列,並且連續兩行都是使用任意類型的木材

合成 (有形配方)

我們這邊先使用有形配方合成我們前幾天新增加的終界方塊:透過擺放泥土方塊成一個"X"字形可以獲得。

  1. 到主程式內,在我們前幾天使用的FMLInitializationEvent事件方法內,加上下面這段程式碼:
    @EventHandler
    public void init(FMLInitializationEvent event) {
        GameRegistry.addRecipe(
            new ItemStack(enderBlock),
            "X X",
            " X ",
            "X X",
            'X',
            Blocks.dirt
        );
    }
    
    這裡細心的邦友可能會發現:為什麼這裡我們沒有用new Object[] {}的方式敘述參數內容,而是直接一個一個參數用逗號分開呢?
    我們前面有說過,第二個參數是Java的物件陣列,但實際上這個參數的定義是(Object... params),這個在Java內稱之為Arbitrary Number of Arguments,也就是參數內容接受一個到多個的Object變數,或是直接給一個Object陣列。這裡如果你用物件陣列的方式寫,Intellij也會提示你這裡可以直接使用多個參數,不用額外宣告一個物件陣列。
  2. 存檔進入遊戲,把泥土擺到你的工作台內合成一個終界方塊吧!
    https://ithelp.ithome.com.tw/upload/images/20191002/20115823LKG1XcymEW.png

合成 (無形配方)

無形配方與有形配方只有一個差別:無形配方不行定義內容。
可以這樣思考:有形配方通常是有一個"聯想"的方式,由配方內容與擺放位置來得到合成的物品(如四個木材可以合成四方形的工作台);而無形配方就沒有任何形狀可以想像。

我們這裡就加一個無形配方,讓1個終界方塊可以直接建立9個白色藥丸。

  1. 一樣回到主程式,在前面加的有形配方後面,再加上我們的無形配方程式碼:

    @EventHandler
     public void init(FMLInitializationEvent event) {
    
         // 有形配方
         GameRegistry.addShapedRecipe(
                 new ItemStack(enderBlock),
                 "Z Z",
                 " Z ",
                 "Z Z",
                 'Z',
                 Blocks.dirt);
    
         // 無形配方
         GameRegistry.addShapelessRecipe(
                 new ItemStack(pillItem, 9),
                 enderBlock
         );
    

    無形配方只需要兩個參數:

    • 第一個是要透過合成產生的ItemStack物件,這裡我們產生9個藥丸物品。
    • 第二個參數可以是一個到多個,表示這個合成配方的來源物品(Item, Block或ItemStack)是哪些;這裡我們只要1個終界方塊當作我們的配方來源
  2. 存檔進入遊戲,現在可以將終界方塊產生9個加速小藥丸了!以後看到苦力怕再也不會怕怕了!
    https://ithelp.ithome.com.tw/upload/images/20191002/20115823aF8snmyD8a.png
    注意這裡的終界方塊不管放哪裡都可以產生藥丸物品喔,有興趣的人可以試看看。


上一篇
[Day17] 創造獨一無二的物品
下一篇
[Day19] 燒煉與釀造
系列文
[Minecraft - 當個創世神] 從玩遊戲到設計遊戲30

1 則留言

0
Capillary J
iT邦新手 5 級 ‧ 2019-10-03 10:41:05

原來合成程式碼regex長這樣XD

這是我根據原始碼去推斷的,原本程式碼並沒有這樣的正則表達式喔XD

這部分倒是提示我表達式好像有點問題...我再來修改一下

我要留言

立即登入留言