教學:製作附加包/方塊

出自Minecraft基岩版开发Wiki
方塊
系列教學
所屬系列
難易度
中級
前置知識
適用版本
國際版
≥ 1.12.0
實踐裝置
Windows
所需軟體

歡迎你來閱讀本篇自訂方塊教學!Minecraft是由無窮無盡的方塊所組成的,因此在遊戲模組以及地圖製作中,將難免遇到各種各樣新的方塊需求。本篇教學將帶你入門基岩版自訂方塊,了解如何在基岩版加入一個富有特色的方塊。

在閱讀本篇教學之前,請確保你已經能夠建立一個行為包和資源包,若還不能,請先閱讀開始之前;包的構建;執行、除錯與匯出頁面以學習行為包的基礎製作。此外,為簡化本篇的篇幅,請先提前閱讀Tutorial:製作附加包/物品以熟悉自訂內容的一些必要工具和思路。本教學將假設你已經了解了自訂物品的製作方法。

引言[編輯]

不同版本之間的差異[編輯]

自訂方塊亦有三個分水嶺版本存在:

  • 1.10,加入了對自訂方塊的支援;
  • 1.16.100,加入了非常多全新的方塊元件,然而它們都是實驗性的;
  • 1.19.X,令一些實用的方塊走出了實驗性玩法,並加入了一些新特性。

請按照自己的需求選擇需要的版本。我們推薦你使用穩定的版本和穩定的方塊元件,1.19.70之後的元件已趨於穩定。

1.10至1.16.100的自訂方塊編寫[編輯]

你需要首先建立一個行為包和資源包,建立方法不過多贅述。

行為包部分[編輯]

在行為包目錄下,建立一個名為blocks的資料夾,並在該資料夾下建立一個檔案my_custom_block.block.json。你可以看到,這步驟和自訂物品是大同小異的。

  • 行為包名稱或其內部ID
    • blocks
      • my_custom_block.block.json
    • manifest.json
    • pack_icon.png

我們也可以照葫蘆畫瓢地給出一個最基礎的自訂方塊的定義:

{
  "format_version": "1.16.0",
  "minecraft:block": {
    "description": {
      "identifier": "test:my_custom_block"
    }
  }
}

相信如果你已經學會了自訂物品的話,理解這段程式碼對你來說應該不是什麼難事。這裡需要指出的一點是,Mojang在1.15時曾對方塊元件做出過更新並修改了方塊元件所能接受的值。本教學基於1.16.0。如果你需要1.15以前的寫法可以參考以下內容:

現在我們不妨直入主題來為我們的方塊加入自訂元件吧!當然,舊版本的自訂方塊的元件也非常的少,但你已經可以用它們來實現最基礎的效果了。舊版本的方塊元件有以下幾個可用:

例如,如果我們希望自訂方塊的光照等級是15,並且在被挖掉之後掉落釣魚的戰利品,我們可以寫成:

{
  "format_version": "1.16.0",
  "minecraft:block": {
    "description": {
      "identifier": "test:my_custom_block"
    },
    "components": {
      "minecraft:block_light_emission": 1.0, // 旧版本下该值的范围为0.0-1.0
      "minecraft:loot": "loot_tables/gameplay/fishing.json"
    }
  }
}

以下是這段程式碼的解釋:

  • minecraft:block_light_emission方塊光照強度,它支援一個0.0-1.0的浮點數,值越大則光照越強。
  • minecraft:loot戰利品表,當該方塊被挖掘後,呼叫其指定的戰利品表。

資源包部分[編輯]

自訂方塊的資源包部分比較複雜。你可能需要以下檔案(即粗體部分),請先提前建立:

  • 資源包名稱或其內部ID
    • texts
      • en_US.lang
      • zh_CN.lang
    • textures
      • blocks
        • (方塊貼圖1).png
        • (方塊貼圖2).png
        • ...
      • terrain_texture.json(連結短ID和貼圖)
      • flipbook_textures.json(當你需要一個要涉及到動態貼圖的方塊時建立,例如海燈籠)
    • blocks.json(連結ID和短ID)
    • manifest.json
    • pack_icon.png

block.json[編輯]

我們先從blocks.json入手。需要注意一點,自訂方塊有三種顯示模式:六面全同分頂面底面和側面分頂底東西南北。舉兩個簡單的例子,我們知道泥土六個面是完全一樣的,這是利用了最簡單的六面全同模式;草地的頂面是綠色的草貼圖,底面是泥土貼圖,而側面是覆蓋了一層草的貼圖,這就是分頂底側面。在入手之前請先想好自己的方塊應該是什麼樣的,再動手。下面是blocks.json的基本格式和三個模式的方塊指定方法:

{
  "方块ID": { "textures": "短ID", "sound": "音效" }, // 六面全同
  "方块ID": { "textures": { "down": "短ID1", "side": "短ID2", "up": "短ID3" }, "sound": "音效" }, // 分顶底侧面
  "方块ID": { "textures": { "down": "短ID1", "up": "短ID2", "north": "短ID3", "south": "短ID4", "west": "短ID5", "east": "短ID6" }, "sound": "音效" } // 分顶底东西南北
}

其中音效可以是原版的方塊音效,在被放置、被踩踏以及被破壞後將播放對應方塊的音效,你可以檢視原版的blocks.json來檢視有哪些內容是能夠允許的。以下是幾種比較常用的音效:

  • stone:石頭質音效(例如石頭、混凝土);
  • glass:玻璃質音效(例如玻璃、螢光石);
  • gravel:泥質音效(例如泥土、礫石);
  • wood:木質音效(例如木材、木塊);
  • cloth:布質音效(例如羊毛、地毯);
  • grass:草質音效(例如草地、樹葉);
  • metal:金屬質音效(例如鐵方塊、黃金方塊)。

舉個例子,如果我希望加入一種新的木材,它應該是六面全同,使用木質音效的,因此可以寫為:

{
  "test:my_custom_block": { "textures": "my_custom_block", "sound": "wood" }
}

terrain_texture.json[編輯]

接著我們來看terrain_texture.json。我們在blocks.json中指定了短ID,該檔案就是將短ID和實際的貼圖檔案連結起來的。假設我們已經在textures/blocks資料夾裡面放入了一個my_custom_planks.png的檔案,我們便可以如此指代:

{
  "resource_pack_name": "vanilla",
  "texture_name": "atlas.terrain",
  "padding": 8,
  "num_mip_levels": 4,
  "texture_data": {
    "my_custom_block": { "textures": [ "textures/blocks/my_custom_planks" ] },
    "短ID": { "textures": [ "贴图路径" ] },
    ...
  }
}

其中前4行是什麼你並不需要關心,你需要關心的只是其中的texture_data。它的一般格式也在上面的程式碼中提出,你可以看到短ID就是如此連結到實際貼圖的。

動態貼圖[編輯]

如果你的方塊需要用到動態貼圖,你可能需要用到flipbook_texture.json。動態貼圖的用法可自行參考原版寫法。

翻譯文字[編輯]

和自訂物品類似,你也需要一個翻譯檔案來指定它們顯示出的名字。開啟en_US.lang,輸入以下內容:

tile.test:my_custom_block.name=My Custom Block

如你所見,方塊的翻譯文字格式為tile.方块ID.name。同理地,在zh_CN.lang輸入以下內容:

tile.test:my_custom_block.name=我的自定义方块

至此,你的方塊編寫就大功告成啦!當然了,本教學也會介紹新版本元件的簡單應用,詳見下文。

1.19.60及更高版本的自訂方塊編寫[編輯]

行為包部分[編輯]

1.19.60版本後又進一步的開放了部分元件。和高版本物品元件是幾乎全新不同,高版本的方塊元件是基於低版本元件的。1.19.60之後有下列元件可以不開啟實驗性玩法使用:

同時,舊版元件大多數都經過了重新命名,這裡不再詳述。

資源包部分[編輯]

高版本方塊的流程和低版本方塊的流程可以說是幾乎完全相同的。但特別地,當你指定了minecraft:material_instancetexture參數時,寫法可能會有一些小變化。在下面的範例中你就可以知道了。

方塊狀態的設定[編輯]

方塊狀態(Block States)是指定方塊所處狀態的一種重要手段,例如半磚是上半磚還是下半磚、羊毛的顏色、按鈕的朝向等等,這些方塊都有相同的ID,但是它們所處的狀態不一樣。在自訂方塊中你可以利用description中的states指定方塊所處的方塊狀態,並利用permutations來另行指代不同方塊狀態下採用的不同元件。以下是微軟文件中給出的一個方塊狀態與置換的範例:

{
  "format_version": "1.19.40",
  "minecraft:block": {
    "description": {
      "identifier": "custom:lamp_block",
      "states": {
        "custom:is_lit": [ true, false ]
      }
    },
    "permutations": [
      {
        "condition": "query.block_state('custom:is_lit') == true",
        "components": {
          "minecraft:light_emission": 15
        }
      },
      {
        "condition": "query.block_state('custom:is_lit') == false",
        "components": {
          "minecraft:light_emission": 0
        }
      }
    ],
    "components": {
      "minecraft:friction": 0.6,
      "minecraft:map_color": "#00ff00" 
    }
  }
}

對這段程式碼做一些必要的解釋:

  • states方塊狀態,指定方塊可能具有的狀態。在這裡,該方塊被指定了具有custom:is_lit的方塊狀態,並支援兩個值,分別為truefalse
  • permutations方塊置換,指定在滿足特定的條件(condition)下該方塊所具有的元件。我們可以看到,condition的檢測條件為query.block_state('custom:is_lit') == true,這是用於檢測該方塊所處狀態的Molang,當custom:is_lit方塊狀態為true時將使用元件"minecraft:light_emission": 15,即光照亮度為15級。下面的條目也是同理的。
  • components方塊元件,指定方塊所具有的通用特性。

你可以使用指令/setblock/fill來放置這些具有自訂特性的方塊。

關於方塊狀態和置換,你可以檢視更加詳細的微軟文件

方塊性狀的設定[編輯]

一些範例[編輯]

無法被破壞和炸毀的泥土[編輯]

如果你希望泥土不再能被破壞,何不以假亂真來做一個新方塊呢?請記住,原版物品和方塊都是不能變更的,因此如果你希望變更原版方塊,請立即放棄這種想法,自己做個新方塊才是更好的選擇。

要實現這點很簡單,我們的核心要素在於「無法破壞」和「無法炸毀」兩點,這分別可以用minecraft:destructible_by_miningminecraft:destructible_by_explosion來解決。因此可以用下面的行為包程式碼:

行為包/blocks/dirt.block.json
{
    "format_version": "1.19.40",
    "minecraft:block": {
        "description": {
            "identifier": "wiki:dirt"
        },
        "components": {
            "minecraft:destructible_by_explosion": false,
            "minecraft:destructible_by_mining": false
        }
    }
}

資源包方面,我們可以偷個懶,直接呼叫原版的方塊路徑:

資源包/blocks.json
{
  "wiki:dirt": { "textures": "dirt", "sound": "gravel" }
}

可以呼叫原版的貼圖有一個條件,就是原版的這個對應短ID不能連結到多個紋理,一旦連結到有多個紋理的短ID,就會出現紫黑塊貼圖錯誤。如果不能直接偷懶用原版的短ID,就需要再用terrain_texture.json來連結到貼圖上(當然這個貼圖也是可以直接連結原版的)。最後搞定翻譯即可:

資源包/texts/en_US.lang
tile.wiki:dirt.name=Dirt
資源包/texts/zh_CN.lang
tile.wiki:dirt.name=泥土

然後,你就可以獲得一個以假亂真,但是怎麼炸也炸不壞的泥土了!

會發光的玻璃[編輯]

想不想要一種可以自發光的玻璃?我們當然可以實現!想想玻璃的一些需求要素:

因此,行為包程式碼也就呼之欲出了。

行為包/blocks/glass.block.json
{
    "format_version": "1.19.40",
    "minecraft:block": {
        "description": {
            "identifier": "wiki:scene_block_glass"
        },
        "components": {
            "minecraft:material_instances": { "*": { "render_method": "blend" } },
            "minecraft:destructible_by_explosion": { "explosion_resistance": 0.3 },
            "minecraft:destructible_by_mining": { "seconds_to_destroy": 0.3 },
            "minecraft:light_dampening": 0,
            "minecraft:light_emission": 15,
            "minecraft:loot": "loot_tables/empty.json"
        }
    }
}

一些基本解釋:

  • minecraft:material_instance:令方塊為透明繪製。*代表所有面都按照透明的方式繪製。
  • minecraft:light_dampening:對於透明繪製的方塊而言,如果不設定這個值,它本質上是不透明方塊,一是會導致草地的變化,二是會導致方塊與方塊之間在底面出現很重的陰影,對於「發光玻璃」而言,這並不是我們希望的結果。

資源包不做過多解釋,這是很簡單的。

能貫穿又摸不到的假方塊[編輯]

假方塊!在很久以前,基岩版的按鈕錯誤導致其在某個特殊值下會顯示為整個方塊,而其又沒有碰撞箱,是可以穿過的,因此稱之為假方塊。雖然這是一個錯誤,但今天我們卻能實打實的做一個真正的假方塊出來了!要想實現假方塊,我們只需要考慮碰撞箱和擊中箱的問題。這可以利用minecraft:collision_boxminecraft:selection_box來解決。我們只需要完全取消掉它的碰撞箱,就可以讓它是可被穿過的:

行為包/blocks/fake_oak_planks.block.json
{
    "format_version": "1.19.60",
    "minecraft:block": {
        "description": {
            "identifier": "wiki:fake_oak_planks"
        },
        "components": {
            "minecraft:collision_box": false
        }
    }
}

這將停用它的碰撞箱,成為可穿過的方塊;而如果再引入一個擊中箱:

行為包/blocks/fake_oak_planks.block.json
{
    "format_version": "1.19.60",
    "minecraft:block": {
        "description": {
            "identifier": "wiki:fake_oak_planks"
        },
        "components": {
            "minecraft:collision_box": false,
            "minecraft:selection_box": false
        }
    }
}

這甚至會讓玩家無法選中這個方塊(包括創造模式玩家)!如果放到了錯誤的地方,你就需要用/setblock來解決啦。

自訂半磚[編輯]

假設我們在抗爆泥土上再進一步,要實現不可破壞的半磚,顯然這是一種不完整方塊。對於半磚,我們需要考慮以下幾點:

  • 方塊不是完整方塊,必須使用特定的方塊模型。方塊模型需要在Blockbench裡自行繪製,假設我們現在已經擁有了geometry.slab_upgeometry.slab_down兩個模型。指定模型可以由minecraft:geometry來承擔。
  • 其碰撞箱和擊中箱都必須是普通方塊的一半;
  • 因為呼叫了自訂模型,這個方塊的面的表達已經不再能用普通的三種情況來代替,必須使用minecraft:material_instance來選擇性地指定面的貼圖。

基於這樣的考慮,我們給出以下參考程式碼:

行為包/blocks/cobblestone_slab_up.block.json
{
    "format_version": "1.19.60",
    "minecraft:block": {
        "description": {
            "identifier": "wiki:cobblestone_slab_up"
        },
        "components": {
            "minecraft:destructible_by_explosion": false,
            "minecraft:destructible_by_mining": false,
            "minecraft:collision_box": { "origin": [ -8, 8, -8 ], "size": [ 16, 8, 16 ] },
            "minecraft:selection_box": { "origin": [ -8, 8, -8 ], "size": [ 16, 8, 16 ] },
            "minecraft:geometry": { "identifier": "geometry.slab_up" },
            "minecraft:material_instances": { "*": { "texture": "cobblestone" } }
        }
    }
}

關於碰撞箱和選擇箱的寫法,見對應條目。如果我們需要把兩種半磚合在一起寫,就可以利用前面的方塊狀態的設定的內容來合併:

行為包/blocks/cobblestone_slab.block.json
{
    "format_version": "1.19.70",
    "minecraft:block": {
        "description": {
            "identifier": "wiki:cobblestone_slab",
            "states": { "vertical_half": [ "top", "bottom" ] }
        },
        "components": {
            "minecraft:destructible_by_explosion": false,
            "minecraft:destructible_by_mining": false,
            "minecraft:material_instances": { "*": { "texture": "cobblestone" } }
        },
        "permutations": [
            {
                "condition": "query.block_state('vertical_half') == 'top'",
                "components": {
                    "minecraft:collision_box": { "origin": [ -8, 8, -8 ], "size": [ 16, 8, 16 ] },
                    "minecraft:selection_box": { "origin": [ -8, 8, -8 ], "size": [ 16, 8, 16 ] },
                    "minecraft:geometry": { "identifier": "geometry.slab_up" }
                }
            },
            {
                "condition": "query.block_state('vertical_half') == 'bottom'",
                "components": {
                    "minecraft:collision_box": { "origin": [ -8, 0, -8 ], "size": [ 16, 8, 16 ] },
                    "minecraft:selection_box": { "origin": [ -8, 0, -8 ], "size": [ 16, 8, 16 ] },
                    "minecraft:geometry": { "identifier": "geometry.slab_down" }
                }
            }
        ]
    }
}

最後利用/setblock等指令對方塊狀態進行控制。是不是很有意思?

關於資源包的問題,事實上你看到了minecraft:material_instances這個元件指定了texture,這其實就是blocks.json中的那個短ID,在方塊中也是存在短ID遷移到行為包中的現象的。因此,blocks.json就可以進行簡化:

資源包/blocks.json
{
  "wiki:cobblestone_slab": { "sound": "stone" }
}

即忽略掉texture參數。至於terrain_texture.json,其實行為包程式碼也偷了個懶,直接呼叫了原版的cobblestone紋理,因此根本無需再次變更!

這就是自訂方塊,自訂方塊要稍微比自訂物品複雜一些,但本教學已經儘可能將這些內容講的完整了。期待這些能對你有所幫助。如果需要更詳細的文件,請查閱微軟文件的自訂方塊文件

本教學預設讀者已掌握附加包的基本構架。教學為自訂方塊的基礎教學,關於自訂方塊的更多內容請檢視進階教學頁面。

概述[編輯]

自訂方塊是在基岩版beta 1.12.0.2中的新增內容。在基岩版1.16.100.56及之後的部分版本更新中, Mojang 為自訂方塊提供了大量的介面,這使得自訂方塊的功能大大增加,不過現在仍有絕大多數的介面未被開放。

透過自訂方塊,創作者可以在遊戲中創造出屬於您的全新方塊,並透過加入屬性、元件和事件等內容賦予它許多有趣的特性。

加入方塊[編輯]

加入自訂方塊首先需要了解一下自訂方塊行為部分的基本結構。

自訂方塊組態檔儲存在行為包中的 blocks資料夾下,其資料結構如下:

{
  "format_version": "1.16.100",
  "minecraft:block": {
    "description": {
    }, //描述
    "components": {
    }, //组件
    "events": {
    }, //事件
    "permutations": [
    ] //置换
  }
}

如上,方塊組態檔由描述、元件、事件與置換四部分內容構成。下面對上述四種基本內容進行了簡要闡述:

描述[編輯]

描述 (description) 物件儲存了用於描述該方塊的基礎資訊,其資料結構如下:

屬性名稱 資料型別 描述
identifier 字串 設定此方塊的識別碼。須包含命名空間但不得使用minecraft:作為命名空間。(除非所編輯的方塊為原版方塊)
is_experimental 布林值 (可選)決定了該方塊是否為實驗性方塊。預設值為 false 。若此屬性值為 true ,則該方塊需開啟實驗性玩法才可獲得。
properties 物件 設定此方塊所具有的一個或多個屬性。例如:"test:block_property": [ 0, 1, 2, 3 ],其中test:block_property為屬性名稱,陣列中的參數為該方塊此屬性可能擁有的值(遊戲預設該方塊初始屬性為所有屬性陣列中的第一個參數)。陣列的參數型別可以為整數、小數、布林值或字串。
register_to_creative_menu 布林值 設定此方塊是否出現在創造模式物品欄。(基岩版1.15.0至今由於不明原因導致此API失效,待修復)

元件[編輯]

元件(components)物件決定了該方塊的功能屬性,您可選擇並加入您需要的元件屬性。

元件分為一般元件和觸發器。一般元件用於定義該方塊的屬性,觸發器用於在特定條件下使方塊觸發事件。

事件[編輯]

事件(events)物件儲存了該方塊可能用到的所有事件。

透過在一個事件下直接加入多個事件或使用序列間接加入多個事件可以使一個觸發器同時觸發多個事件:

範例:

"events": {
  "test_event": { //事件名称
    "set_block_property": { //第一个事件
      "minecraft:direction": 1
    },
    "run_command": { //第二个事件
      "command": "say Hello world"
    }
  }
}

置換[編輯]

置換(permutations)陣列儲存了該方塊在對應條件下會置換或新增的對應所有元件。一般使用 query.block_property[注 1] 來取得方塊屬性並以此作為置換條件。

範例[編輯]

現在仿照下面的範例,透過建立一個方塊的JSON行為檔案來向遊戲中加入一個簡單的自訂方塊:

{
  "format_version": "1.16.100",
  "minecraft:block": {
    "description": {
      "identifier": "example:test_block"
    },
    "components": {
      "minecraft:destroy_time": 1.0,
      "minecraft:explosion_resistance": 2.5,
      "minecraft:friction": 0.6,
      "minecraft:map_color": "#FFFFFF",
      "minecraft:block_light_absorption": 0,
      "minecraft:block_light_emission": 0
      }
  }
}

資源定義[編輯]

主條目:資源定義
建立完自訂方塊後,還需要對其增添紋理、音效等內容來改變其外觀表現。首先需要對加入的紋理進行定義。

定義紋理[編輯]

準備好兩張PNG格式的圖片,這裡以自訂類似原版原木的方塊作為範例:

Tutorial Block Texture
custom_log_end.png —— 「原木」頂部和底部的圖片
Tutorial Block Texture
custom_log_side.png —— 「原木」側面的圖片

將這兩張圖片分別命名並放到資源包的<RP>/textures/blocks/路徑下,這裡分別命名為「custom_log_end.png」和「custom_log_side.png」。

現在準備好了圖片,還需要對這兩張圖片進行定義。建立一個名為「terrain_texture.json」的檔案到<RP>/textures/路徑下,然後向其中加入如下內容:

{
  "resource_pack_name": "tutorial_pack", //这里填写任意名称
  "num_mip_levels": 4,
  "padding": 8,
  "texture_name": "atlas.terrain",
  "texture_data": {
    "log_end": { //定义后的名称
      "textures": "textures/blocks/custom_log_end"  //图片文件的路径
    },
    "log_side": {
      "textures": "textures/blocks/custom_log_side"
    }
  }
}

這樣就將剛剛的custom_log_end.pngcustom_log_side.png兩張圖片分別定義為了「log_end」和「log_side」這兩個名稱。

每加入一張新的圖片都需要在terrain_texture.json中定義一次,定義後的名稱將用於在以後給各種檔案或元件呼叫。

blocks.json[編輯]

定義完了圖片,現在需要將這兩張圖片應用到剛剛的自訂方塊上,並且為它加入音效。

首先建立一個名為「blocks.json」的檔案到資源包根目錄下,然後向其中加入如下內容:

{
  "format_version": [ 1, 1, 0 ],
  "example:test_block": { //刚刚创建的自定义方块的标识符
    "sound" : "wood", //使用木头的音效
    "textures" : {
      "down" : "log_end", //刚刚定义的图片名称,下同
      "side" : "log_side", 
      "up" : "log_end"
    }
  }
}

現在儲存檔案並進入遊戲,將附加包加入進一個世界並進入世界,輸入如下指令: /give @s example:test_block 就可以取得剛剛加入的自訂方塊了。

Tutorial Test Customer Block
自訂「原木」被成功加入到了遊戲

  1. query.block_property 是Molang中的一項查詢功能。

< 物品 | 配方 >