本帖最后由 快乐小方 于 2022-6-10 14:29 编辑
从零开始制作一个矿石作物 Addon
本篇教程并不是完整的附加包开发教程,仅包括了与完成“矿石作物”这个目标相关的内容,学习更多内容请访问官方文档
本文中提到的一些内容在你阅读的时候可能已经过时,请以官方文档为准
本文若有错误,欢迎在评论区指出,不胜感激
你将学到...
一切开始前...
准备就绪
开始的开始
你可以按照下面的目录树创建这些在后续需要用到的文件夹
BP是行为包(Behavior Pack)的缩写,\BP 目录则是我们的行为包部分
RP是资源包(Resource Pack)的缩写,\RP 目录则是我们的资源包部分
复制代码
清单文件 manifest.json
首先我们需要在 \BP 与 \RP 目录下分别创建一个名叫 manifest.json 文件
复制代码
manifest.json 的基本构成
header
header 所需要包含的头部信息:
我们直接把包名设置为 Ore Crops 好了,后面加上 BP、RP 加以区分(事实上不这么做也可以)
描述中我们可以写上作者信息之类的东西
版本号设置成 0.0.1 <sup>[注意:若要将附加包上传至基岩版市场,a 值需要大于 0]</sup>
uuid 将作为区分附加包的标识,我们需要设置一个独一无二的,你可以在这个网站在线生成 uuid
modules
modules 所需要包含的内容:
我们需要分别为 \BP\manifest.json 和 \RP\manifest.json 添加行为包模块(data)与资源包模块(resources)
dependencies
dependencies所需要包含的内容:
为了将行为包与资源包关联起来,我们需要将他们添加到对方的 dependencies 中
现在,我们的清单文件应该是这样的:
\BP\manifest.json :
复制代码
\BP\manifest.json :
复制代码
图标文件 pack_icon.png
别忘了设置一个图标!
在 \BP 和 \RP 目录下放置 pack_icon.png 即可
完成了这些,我们可以正式开始开发工作了 ——
第一个物品
添加物品
首先你需要在 \BP\items 目录下创建一个 .json 文件,文件名随意,这里使用 coal_seed.json 作为“煤炭种子”的物品 json 文件。
物品 json 文件的基本格式如下
复制代码
description 的基本结构如下:
首先是 identifier,命名空间一般为 addon 的名称,这里“煤炭种子”可以设置为 orecrops:coal_seed
category 的可选值有:equipment(装备), items(物品), natural(自然), block(建筑), commands(不可通过命令获取)。这里我们选择 natural
is_experimental将决定物品是否需开启实验性玩法才可获得,默认值为 false
现在,你的 \BP\items\coal_seed.json 应该是这样子的:
复制代码
至此,你已经成功添加了你的第一个物品!
但是它还缺少纹理、名字等等一些必要属性,下面我们为它定义一个纹理
定义纹理与物品名称
定义纹理
转到 \RP\textures\items 目录,在这里放置你的物品纹理
回到 \RP\textures 目录,在这里新建一个名为 item_texture.json 的文件,在里面输入下面的内容来定义物品纹理
复制代码
物品名称
我们在 \RP\texts 目录下新建一个 zh_CN.lang, 在里面输入:
复制代码
我们在 zh_CN.lang 中输入的这一行“等式”定义了在简体中文语言下 item.orecrops:coal_seed.name 键所对应的文本,以这种方式设置物品名称将方便我们后续进行本地化,与本地化相关的内容我们会在最后学习
到这里你可能会很疑惑,为什么我的物品还是没有纹理?
我们成功添加了一个物品并定义了他的纹理,下面我们将使用组件赋予它名字、纹理与一些作为物品该有的基本属性
物品组件
我们将使用到下表中的组件,更多组件请查阅文档
minecraft:creative_category
复制代码
我们使用这个组件将“煤炭种子”归入“种子”分组
minecraft:display_name
复制代码
在上一节我们定义了“煤炭种子”的本地化键名(item.orecrops:coal_seed.name),直接填进去即可
minecraft:icon
复制代码
在上一节我们定义了“煤炭种子”的纹理名称(coal_seed),直接填进去即可
minecraft:max_stack_size
复制代码
堆叠上限是一个大于等于 1 小于等于 64 的整数型值
我们设置为 64
现在,我们的 coal_seed.json 应该是这样的:
复制代码
现在,你的第一个物品已经有了名字、纹理,下面我们来完成你的第一个方块
第一个方块
添加方块
在 \BP\blocks 目录创建一个名为 coal_crops.json 的文件作为“煤炭作物”的作物方块
方块 json 文件的基本格式如下
复制代码
方块的描述部分与物品稍有不同:
identifier 我们设置为 orecrops:coal_crop
properties 在下一章将具体学习
is_experimental 与物品相同,默认值为 false
现在,你的\BP\blocks\coal_crop.json 应该是这样的:
复制代码
定义纹理
将作物的不同生长状态的纹理放进 \RP\textures\blocks 中,本教程中我为作物设置了 8 个不同生长阶段
回到 \RP\textures 目录,新建 terrain_texture.json,在里面输入:
复制代码
我们还需要在资源包中为方块指定纹理,回到 \RP 目录
创建 blocks.json,为我们的作物方块指定纹理和音效
复制代码
textures 的值也可以是一个对象,用来设置方块不同面的纹理,例如这样:
复制代码
现在他是一个有纹理的方块了,但是看起来一点都不像一个作物该有的样子
打开 Blockbench,为他制作一个模型(更多 Blockbench 的用法,请查阅此教程)

选择新建 Bedrock Model

设置好后点击 Confirm

制作出想要的模型(新建两个 cube,将 Size 的第三个值设置成 0 就成薄片状了)

将导出的模型放在 \RP\models\entity 中,之后我们就可以通过组件为方块设置模型和必要属性了
方块组件
我们将使用到下表中的组件,更多组件请查阅文档
minecraft:collision_box
复制代码
以上是 minecraft:collision_box 组件的不同写法,当布尔值写法的数据值设置为 false 时则禁用碰撞箱,也就是说下面两种写法是等价的
复制代码
在原版中的作物方块实体是可以自由穿过的,这里我们可以直接将 minecraft:collision_box 的数据值设置为 false 禁用碰撞箱
minecraft:geometry
复制代码
还记得你在上一节设置的 Model Identifier 吗?将它填进去就好
minecraft:placement_filter
复制代码
我们的作物方块只可以放置在耕地方块的上面,block_filter 设置为 ["farmland"],allowed_faces 设置为 ["up"]
另:allowed_faces 可选的值有 up(顶面)、down(底面)、north(北面)、south(南面)、east(东面)、west(西面)、side(侧面)、all(所有面)
现在我们的 coal_crops.json 应该是这样的:
复制代码
种子、作物
种子
我们将使用 minecraft:block_placer 组件让“煤炭种子”拥有放置方块的能力,在放置方块的同时将使用一个物品
复制代码
写好后应该长这样:
复制代码
大功告成!物品这一部分我们已经彻底完成了 ——
复制代码
作物
不同生长状态
为了实现不同生长状态,我们首先需要在方块的描述中为方块定义一个属性(properties),它们类似“变量”,一个方块可以拥有多个属性,属性的值可以是数字、布尔值或字符串
我们先为作物方块定义一个 orecrops:growth 属性,来储存它的不同生长阶段
复制代码
为了让作物方块在不同生长阶段拥有不同的纹理,我们需要使用置换(permutations)
在置换部分我们要接触到 Molang 了!
下面是 permutations 的格式,你可以设置不同条件对应不同欲被替换的组件
复制代码
条件部分我们可以使用 Molang,在这里我们通常使用 Molang 的逻辑运算符对值进行判断
我们需要判断此前设置的 orecrops:growth 的值是否为特定值,所以选用等于运算符 ==
若要获取 orecrops:growth 还需要用到查询函数 query.block_property(),这个函数需要传入一个参数,参数则是要查询的属性名称
我们的煤炭作物生长第一阶段的“条件”是:query.block_property('orecrops:growth') == 0
我们共需要设置 8 个这样的置换,来做到 8 个生长状态:
复制代码
生长
我们在上一节已经完整了作物的不同生长阶段,下面我们使用触发器组件与自定义事件完成作物的自然生长与骨粉催熟
我们先来设置事件,先来一个生长事件:
复制代码
set_block_property 中我们使用了 Molang 让 orecrops:growth 增加
这里我们用到了 Molang 的三元条件运算符 ?::当问号左边的表达式为真,则将问号与冒号中间表达式的值作为整个表达式的取值,反之则将冒号后面表达式的值作为整个表达式的取值。
翻译成人话就是:若 orecrops:growth 小于 7 让 orecrops:growth + 1,否则设置 orecrops:growth 为 7
下面我们来完成骨粉催熟事件
复制代码
完成事件后我们还需要使用触发器组件来触发这些事件
复制代码
现在我们的 coal_crop.json 是这个样子的:
复制代码
现在,一个可生长的作物已经初步成型了,等等——破坏掉它没有掉落物?!
收获
战利品表
我们需要使用战利品表自定义作物的掉落物
在 \BP\loot_tables 目录新建 coal_seed.json 文件作为物品还未成熟时的掉落物的战利品表
复制代码
在 \BP\loot_tables 目录新建 coal_crop.json 文件作为物品已经成熟时的掉落物的战利品表
复制代码
回到方块的 json 文件,使用 minecraft:loot 组件设置战利品表
我们为未成熟的作物方块设置 coal_seed.json 战利品
为成熟的作物方块设置 coal_crop.json 战利品
收获事件
为了在作物成熟的时候右键即可收获,且一株作物可以多次结果矿物,我们可以新增一个自定义事件 harvest_event
复制代码
我们还需要在 orecrops:growth 为 7 时的置换中置换 minecraft:on_interact 事件和 minecraft:loot 事件
复制代码
最终,我们的 coal_crop.json 是这样的:
复制代码
至此,种子与作物方块已经全部完成了,下面一章我们将学习使用自定义合成配方
合成种子
有序合成配方的基本结构
复制代码
pattern:有序合成的物品摆放样式
key:使用字符代表物品,用在 pattern 中
复制代码
在 \BP\recipes 目录新建一个 coal_seed.json
看看下面 coal_seed.json 的例子就懂了
复制代码
向世界推广你的 Addon
为了适配不同语言的游戏,我们在很早就做好了本地化的准备。现在,如果你想增加一门语言的支持,只需要在 \RP\texts 目录新建一个 语言代号.lang,例如 en_US.lang
在这些语言文件中增加两行:
复制代码
修改你的包名和描述为 pack.name 和 pack.description
再新建一个文件 languages.json,输入:
复制代码
这样就可以做到预读取语言文件,在不同语言下附加包的名称与描述都会变为与对应语言文件中对应的文本
完
参考与引用
本文在撰写过程中参考或引用了来自以下网站的文本
致谢
感谢以下组织、个人、网站、软件在教程编写过程中对本人提供的帮助
来自群组: Uncode Studio
目录
|
本篇教程并不是完整的附加包开发教程,仅包括了与完成“矿石作物”这个目标相关的内容,学习更多内容请访问官方文档
本文中提到的一些内容在你阅读的时候可能已经过时,请以官方文档为准
本文若有错误,欢迎在评论区指出,不胜感激
你将学到...
- 自定义物品
- 自定义方块
- 自定义合成配方
- 自定义战利品表
- 本地化
- 一点点 Molang
一切开始前...
- 准备需要使用到的纹理(图标、种子的纹理、作物方块不同生长阶段的纹理等)
- 准备一个文本编辑器
- 安装 Blockbench,你可以在这里下载
- 别忘了最重要的 —— Minecraft 基岩版
准备就绪
开始的开始
你可以按照下面的目录树创建这些在后续需要用到的文件夹
BP是行为包(Behavior Pack)的缩写,\BP 目录则是我们的行为包部分
RP是资源包(Resource Pack)的缩写,\RP 目录则是我们的资源包部分
- HelloWorld
- ├─BP
- │ ├─blocks
- │ ├─items
- │ ├─loot_tables
- │ └─recipes
- └─RP
- ├─models
- │ └─entity
- ├─texts
- └─textures
- ├─blocks
- └─items
清单文件 manifest.json
首先我们需要在 \BP 与 \RP 目录下分别创建一个名叫 manifest.json 文件
- HelloWorld
- ├─BP
- │ ├─...
- │ └─manifest.json
- └─RP
- ├─...
- └─manifest.json
manifest.json 的基本构成
名称 | 描述 |
format_version | 告诉 Minecraft 需要用什么版本来解析这个 Json |
header | 清单的头部信息 |
modules | 此附加包所拥有的模块 |
dependencies | 此附加包的依赖项 |
header
header 所需要包含的头部信息:
名称 | 数据类型 | 描述 |
name | 字符串 | 此附加包的名称 |
version | 数组 [a, b, c] | 此附加包的版本号 |
min_engine_version | 数组 [a, b, c] | 此附加包所兼容的 Minecraft 的最低版本 |
uuid | 字符串 | 此附加包的标识 |
我们直接把包名设置为 Ore Crops 好了,后面加上 BP、RP 加以区分(事实上不这么做也可以)
描述中我们可以写上作者信息之类的东西
版本号设置成 0.0.1 <sup>[注意:若要将附加包上传至基岩版市场,a 值需要大于 0]</sup>
uuid 将作为区分附加包的标识,我们需要设置一个独一无二的,你可以在这个网站在线生成 uuid
modules
modules 所需要包含的内容:
名称 | 数据类型 | 描述 |
type | 字符串 | 模块的类型 |
description | 字符串 | 模块的描述 |
version | 数组 [a, b, c] | 模块的版本 |
uuid | 字符串 | 模块的标识 |
我们需要分别为 \BP\manifest.json 和 \RP\manifest.json 添加行为包模块(data)与资源包模块(resources)
dependencies
dependencies所需要包含的内容:
名称 | 数据类型 | 描述 |
uuid | 字符串 | 所依赖的附加包的 uuid |
version | 数组 [a, b, c] | 所依赖的附加包的版本 |
为了将行为包与资源包关联起来,我们需要将他们添加到对方的 dependencies 中
现在,我们的清单文件应该是这样的:
\BP\manifest.json :
- {
- "format_version":2,
- "header":{
- "name":"Ore Crops (BP)",
- "description":"Ore Crops behavior pack",
- "uuid":"c5960d44-cfa8-457d-83e4-ccc56fbc22e4",
- "version":[0,0,1],
- "min_engine_version":[1,18,10]
- },
- "modules":[
- {
- "type":"data",
- "description":"Ore Crops behavior pack",
- "uuid":"713b3a86-1a48-c1b2-26f8-4416db5b876b",
- "version":[0,0,1]
- }
- ],
- "dependencies":[
- {
- "uuid":"330199b2-ea33-da59-8cb9-c412055d23e9",
- "version":[0,0,1]
- }
- ]
- }
\BP\manifest.json :
- {
- "format_version":2,
- "header":{
- "name":"Ore Crops (RP)",
- "description":"Ore Crops resource pack",
- "uuid":"330199b2-ea33-da59-8cb9-c412055d23e9",
- "version":[0,0,1],
- "min_engine_version":[1,18,10]
- },
- "modules":[
- {
- "type":"resources",
- "description":"Ore Crops resource pack",
- "uuid":"0e262f01-38dc-b893-0902-cb0140885a43",
- "version":[0,0,1]
- }
- ],
- "dependencies":[
- {
- "uuid":"c5960d44-cfa8-457d-83e4-ccc56fbc22e4",
- "version":[0,0,1]
- }
- ]
- }
图标文件 pack_icon.png
别忘了设置一个图标!
在 \BP 和 \RP 目录下放置 pack_icon.png 即可
完成了这些,我们可以正式开始开发工作了 ——
第一个物品
添加物品
首先你需要在 \BP\items 目录下创建一个 .json 文件,文件名随意,这里使用 coal_seed.json 作为“煤炭种子”的物品 json 文件。
物品 json 文件的基本格式如下
- {
- "format_version":"1.18.0", // 游戏版本号
- "minecraft:item":{
- "description":{
- // 物品的基本信息
- },
- "components":{
- // 物品的组件
- },
- "events":{
- // 物品的事件
- }
- }
- }
description 的基本结构如下:
名称 | 数据类型 | 描述 |
identifier | 字符串 | 物品的命名空间与物品名构成的标识 |
category | 字符串 | 物品在创造模式物品栏的分类 |
is_experimental | 布尔值 | 物品是否为实验性物品 |
首先是 identifier,命名空间一般为 addon 的名称,这里“煤炭种子”可以设置为 orecrops:coal_seed
category 的可选值有:equipment(装备), items(物品), natural(自然), block(建筑), commands(不可通过命令获取)。这里我们选择 natural
is_experimental将决定物品是否需开启实验性玩法才可获得,默认值为 false
现在,你的 \BP\items\coal_seed.json 应该是这样子的:
- {
- "format_version":"1.18.0",
- "minecraft:item":{
- "description":{
- "identifier":"orecrops:coal_seed",
- "category":"natural"
- }
- }
- }
至此,你已经成功添加了你的第一个物品!
但是它还缺少纹理、名字等等一些必要属性,下面我们为它定义一个纹理
定义纹理与物品名称
定义纹理
转到 \RP\textures\items 目录,在这里放置你的物品纹理
回到 \RP\textures 目录,在这里新建一个名为 item_texture.json 的文件,在里面输入下面的内容来定义物品纹理
- {
- "resource_pack_name":"Ore Crops resource pack",
- "texture_name":"atlas.items",
- "texture_data":{
- "coal_seed":{
- "textures":"textures/items/fang/coal_seed"
- }
- }
- }
名称 | 描述 |
resource_pack_name | 资源包的名称,可填vanilla或其他名称<sup>[存疑]</sup>。 |
texture_name | 请填为 atlas.item <sup>[存疑]</sup> |
texture_data | 纹理资源 "纹理名称":{"textures":"纹理路径"} |
物品名称
我们在 \RP\texts 目录下新建一个 zh_CN.lang, 在里面输入:
- item.orecrops:coal_seed.name=煤炭种子
我们在 zh_CN.lang 中输入的这一行“等式”定义了在简体中文语言下 item.orecrops:coal_seed.name 键所对应的文本,以这种方式设置物品名称将方便我们后续进行本地化,与本地化相关的内容我们会在最后学习
到这里你可能会很疑惑,为什么我的物品还是没有纹理?
我们成功添加了一个物品并定义了他的纹理,下面我们将使用组件赋予它名字、纹理与一些作为物品该有的基本属性
物品组件
我们将使用到下表中的组件,更多组件请查阅文档
组件名称 | 描述 |
minecraft:creative_category | 注册物品到创造模式物品栏的指定分类、分组 |
minecraft:display_name | 设置物品显示的名称(可使用本地化键名) |
minecraft:icon | 设置物品显示的纹理 |
minecraft:max_stack_size | 设置物品的最大堆叠数量 |
minecraft:creative_category
- "minecraft:creative_category": {
- "parent": "分组"
- }
分组大全
我们使用这个组件将“煤炭种子”归入“种子”分组
minecraft:display_name
- "minecraft:display_name": {
- "name":"名称或本地化键名"
- }
在上一节我们定义了“煤炭种子”的本地化键名(item.orecrops:coal_seed.name),直接填进去即可
minecraft:icon
- "minecraft:icon": {
- "texture":"纹理名称"
- }
在上一节我们定义了“煤炭种子”的纹理名称(coal_seed),直接填进去即可
minecraft:max_stack_size
- "minecraft:max_stack_size": 堆叠上限
堆叠上限是一个大于等于 1 小于等于 64 的整数型值
我们设置为 64
现在,我们的 coal_seed.json 应该是这样的:
- {
- "format_version":"1.18.0",
- "minecraft:item":{
- "description":{
- "identifier":"orecrops:coal_seed",
- "category":"nature"
- },
- "components":{
- "minecraft:display_name":{
- "value":"item.orecrops:coal_seed.name"
- },
- "minecraft:creative_category":{
- "parent":"itemGroup.name.seed"
- },
- "minecraft:max_stack_size":64,
- "minecraft:icon":{
- "texture":"coal_seed"
- }
- }
- }
- }
现在,你的第一个物品已经有了名字、纹理,下面我们来完成你的第一个方块
第一个方块
添加方块
在 \BP\blocks 目录创建一个名为 coal_crops.json 的文件作为“煤炭作物”的作物方块
方块 json 文件的基本格式如下
- {
- "format_version": "1.18.0", // 游戏版本
- "minecraft:block": {
- "description": {
- // 描述
- },
- "components": {
- // 组件
- },
- "events": {
- // 事件
- },
- "permutations": [
- //置换
- ]
- }
- }
方块的描述部分与物品稍有不同:
名称 | 数据类型 | 描述 |
identifier | 字符串 | 方块的命名空间与物品名构成的标识 |
properties | 对象 | 方块的属性 |
is_experimental | 布尔值 | 方块是否为实验性方块 |
identifier 我们设置为 orecrops:coal_crop
properties 在下一章将具体学习
is_experimental 与物品相同,默认值为 false
现在,你的\BP\blocks\coal_crop.json 应该是这样的:
- {
- "format_version":"1.18.0",
- "minecraft:block":{
- "description":{
- "identifier":"orecrops:coal_crop"
- }
- }
- }
定义纹理
将作物的不同生长状态的纹理放进 \RP\textures\blocks 中,本教程中我为作物设置了 8 个不同生长阶段
回到 \RP\textures 目录,新建 terrain_texture.json,在里面输入:
- {
- "resource_pack_name":"Ore Crops resource pack",
- "texture_name":"atlas.terrain",
- "num_mip_levels":4,
- "padding":8,
- "texture_data":{
- "coal_crop_0":{
- "textures":"textures/blocks/fang/crop_stage_0"
- },
- "coal_crop_1":{
- "textures":"textures/blocks/fang/crop_stage_1"
- },
- "coal_crop_2":{
- "textures":"textures/blocks/fang/crop_stage_2"
- },
- "coal_crop_3":{
- "textures":"textures/blocks/fang/crop_stage_3"
- },
- "coal_crop_4":{
- "textures":"textures/blocks/fang/crop_stage_4"
- },
- "coal_crop_5":{
- "textures":"textures/blocks/fang/coal_stage_5"
- },
- "coal_crop_6":{
- "textures":"textures/blocks/fang/coal_stage_6"
- },
- "coal_crop_7":{
- "textures":"textures/blocks/fang/coal_stage_7"
- }
- }
- }
我们还需要在资源包中为方块指定纹理,回到 \RP 目录
创建 blocks.json,为我们的作物方块指定纹理和音效
- {
- "format_version":"1.18.0",
- "orecrops:coal_crop":{
- "textures":"coal_crop_0",
- "sound":"grass"
- }
- }
textures 的值也可以是一个对象,用来设置方块不同面的纹理,例如这样:
- "textures":{
- "down" : "log_end",
- "side" : "log_side",
- "up" : "log_end"
- }
现在他是一个有纹理的方块了,但是看起来一点都不像一个作物该有的样子
打开 Blockbench,为他制作一个模型(更多 Blockbench 的用法,请查阅此教程)

选择新建 Bedrock Model

设置好后点击 Confirm

制作出想要的模型(新建两个 cube,将 Size 的第三个值设置成 0 就成薄片状了)

将导出的模型放在 \RP\models\entity 中,之后我们就可以通过组件为方块设置模型和必要属性了
方块组件
我们将使用到下表中的组件,更多组件请查阅文档
名称 | 描述 |
minecraft:collision_box | 设置方块的碰撞箱 |
minecraft:geometry | 设置方块的模型 |
minecraft:placement_filter | 设置方块被放置时的条件 |
minecraft:collision_box
- // 对象写法
- "minecraft:collision_box":{
- "origin": 锚点,
- "size": 尺寸
- }
- // 布尔值写法
- "minecraft:collision_box": 布尔值
以上是 minecraft:collision_box 组件的不同写法,当布尔值写法的数据值设置为 false 时则禁用碰撞箱,也就是说下面两种写法是等价的
- // 对象写法
- "minecraft:collision_box":{
- "origin": [0, 0, 0],
- "size": [0, 0, 0]
- }
- // 布尔值写法
- "minecraft:collision_box": false
在原版中的作物方块实体是可以自由穿过的,这里我们可以直接将 minecraft:collision_box 的数据值设置为 false 禁用碰撞箱
minecraft:geometry
- "minecraft:geometry": "几何模型"
还记得你在上一节设置的 Model Identifier 吗?将它填进去就好
minecraft:placement_filter
- "minecraft:placement_filter": {
- "conditions": [ // 条件可以设置多个
- {
- "block_filter": 方块数组,
- "allowed_faces": 面数组
- }
- ]
- }
我们的作物方块只可以放置在耕地方块的上面,block_filter 设置为 ["farmland"],allowed_faces 设置为 ["up"]
另:allowed_faces 可选的值有 up(顶面)、down(底面)、north(北面)、south(南面)、east(东面)、west(西面)、side(侧面)、all(所有面)
现在我们的 coal_crops.json 应该是这样的:
- {
- "format_version":"1.18.0",
- "minecraft:block":{
- "description":{
- "identifier":"orecrops:coal_crop"
- },
- "components":{
- "minecraft:collision_box":false,
- "minecraft:geometry":"geometry.crop",
- "minecraft:placement_filter":{
- "conditions":[
- {
- "block_filter":["farmland"],
- "allowed_faces":["up"]
- }
- ]
- }
- }
- }
- }
种子、作物
种子
我们将使用 minecraft:block_placer 组件让“煤炭种子”拥有放置方块的能力,在放置方块的同时将使用一个物品
- "minecraft:block_placer":{
- "block": "方块的标识",
- "use_on": 可以在何种方块上使用(数组)
- }
写好后应该长这样:
- "minecraft:block_placer":{
- "block": "orecrops:coal_crop",
- "use_on": ["farmland"]
- }
大功告成!物品这一部分我们已经彻底完成了 ——
- {
- "format_version":"1.18.0",
- "minecraft:item":{
- "description":{
- "identifier":"orecrops:coal_seed",
- "category":"nature"
- },
- "components":{
- "minecraft:display_name":{
- "value":"item.orecrops:coal_seed.name"
- },
- "minecraft:creative_category":{
- "parent":"itemGroup.name.seed"
- },
- "minecraft:max_stack_size":64,
- "minecraft:icon":{
- "texture":"coal_seed"
- },
- "minecraft:block_placer":{
- "block":"orecrops:coal_crop",
- "use_on":["farmland"]
- }
- }
- }
- }
作物
不同生长状态
为了实现不同生长状态,我们首先需要在方块的描述中为方块定义一个属性(properties),它们类似“变量”,一个方块可以拥有多个属性,属性的值可以是数字、布尔值或字符串
我们先为作物方块定义一个 orecrops:growth 属性,来储存它的不同生长阶段
- "properties":{
- "orecrops:growth":[0, 1, 2, 3, 4, 5, 6, 7]
- }
为了让作物方块在不同生长阶段拥有不同的纹理,我们需要使用置换(permutations)
在置换部分我们要接触到 Molang 了!
下面是 permutations 的格式,你可以设置不同条件对应不同欲被替换的组件
- {
- "condition":"条件",
- "components": 欲被替换的组件
- }
条件部分我们可以使用 Molang,在这里我们通常使用 Molang 的逻辑运算符对值进行判断
运算符 | 描述 | 示例 |
! | 逻辑非运算符。使一个表达式的结果从 true 变为 false ,从 false 变为 true。 | !query.can_fly |
&& | 逻辑与运算符。只有当两个表达式都为true 时,整个表达式的结果才为true。 | query.can_walk == 1 && query.can_climb == 1 |
|| | 逻辑或运算符。只要其中任意一个表达式为 true 整个表达式都为 true。 | `query.can_walk == 1 |
< | 小于运算符。比较左右两边表达式数值的大小,若左边小于右边即为 true,反之则为 false。 | query.total_particle_count < 5 |
<= | 小于等于运算符。用于比较左右两边表达式数值的大小,若左边小于或等于右边即为 true,反之则为 false。 | query.trade_tier <= 2 |
>= | 大于等于运算符。用于比较左右两边表达式数值的大小,若左边大于或等于右边即为 true,反之则为 false。 | query.health >= 5 |
> | 大于运算符。用于比较左右两边表达式数值的大小,若左边大于右边即为 true,反之则为 false。 | query.day > 7 |
== | 等于运算符。若左边与右边表达式的结果相等时即为 true,反之则为 false。 | query.block_face == query.cardinal_player_facing |
!= | 不等于运算符。若左边与右边表达式的结果不相等时即为 true,反之则为 false。 | query.body_x_rotation != query.body_y_rotation |
我们需要判断此前设置的 orecrops:growth 的值是否为特定值,所以选用等于运算符 ==
若要获取 orecrops:growth 还需要用到查询函数 query.block_property(),这个函数需要传入一个参数,参数则是要查询的属性名称
我们的煤炭作物生长第一阶段的“条件”是:query.block_property('orecrops:growth') == 0
我们共需要设置 8 个这样的置换,来做到 8 个生长状态:
- "permutations": [
- {
- "condition":"query.block_property('orecrops:growth') == 0",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"crop_0",
- "render_method":"alpha_test"
- }
- }
- }
- },
- {
- "condition":"query.block_property('orecrops:growth') == 1",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"coal_crop_1",
- "render_method":"alpha_test"
- }
- }
- }
- },
- {
- "condition":"query.block_property('orecrops:growth') == 2",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"coal_crop_2",
- "render_method":"alpha_test"
- }
- }
- }
- },
- {
- "condition":"query.block_property('orecrops:growth') == 3",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"coal_crop_3",
- "render_method":"alpha_test"
- }
- }
- }
- },
- {
- "condition":"query.block_property('orecrops:growth') == 4",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"coal_crop_4",
- "render_method":"alpha_test"
- }
- }
- }
- },
- {
- "condition":"query.block_property('orecrops:growth') == 5",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"coal_crop_5",
- "render_method":"alpha_test"
- }
- }
- }
- },
- {
- "condition":"query.block_property('orecrops:growth') == 6",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"coal_crop_6",
- "render_method":"alpha_test"
- }
- }
- }
- },
- {
- "condition":"query.block_property('orecrops:growth') == 7",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"coal_crop_7",
- "render_method":"alpha_test"
- }
- }
- }
- }
- ]
生长
我们在上一节已经完整了作物的不同生长阶段,下面我们使用触发器组件与自定义事件完成作物的自然生长与骨粉催熟
我们先来设置事件,先来一个生长事件:
- "grow_event":{ // 自定义事件名
- "randomize":[ // 随机执行一个事件组
- {
- "weight":1 // 权重,如果随机到这里什么都不会发生
- },
- {
- "weight":1, // 权重
- "set_block_property":{ // 设置方块的属性的值
- "orecrops:growth":"(query.block_property('orecrops:growth')<7) ? query.block_property('orecrops:growth') + 1 : 7" // 在下方详细解释
- }
- }
- ]
- }
set_block_property 中我们使用了 Molang 让 orecrops:growth 增加
这里我们用到了 Molang 的三元条件运算符 ?::当问号左边的表达式为真,则将问号与冒号中间表达式的值作为整个表达式的取值,反之则将冒号后面表达式的值作为整个表达式的取值。
翻译成人话就是:若 orecrops:growth 小于 7 让 orecrops:growth + 1,否则设置 orecrops:growth 为 7
下面我们来完成骨粉催熟事件
- "usebonemeal_event": { // 自定义事件名
- "sequence":[ // 执行下面的所有事件
- {
- "decrement_stack":{ // 减少一个手持的物品
- "ignore_game_mode":false // 是否忽略游戏模式
- }
- },
- {
- "run_command":{ // 执行命令
- "command":[ // 命令(数组)
- "particle minecraft:crop_growth_emitter ~ ~ ~" // 在方块处生成 crop_growth_emitter 粒子
- ]
- }
- },
- {
- "trigger":{
- "event":"grow_event" // 执行自定义事件“grow_event”
- }
- }
- ]
- }
完成事件后我们还需要使用触发器组件来触发这些事件
- "minecraft:on_interact": { // 右键触发器组件
- "condition":"query.get_equipped_item_name('main_hand') == 'bone_meal'", // 触发条件是拿着骨粉右键
- "event":"usebonemeal_event" // 触发拿着骨粉右键将触发 usebonemeal_event 事件
- },
- "minecraft:random_ticking": { // 随机刻组件
- "on_tick":{ // 触发器
- "event":"grow_event" // 触发 grow_event 事件
- }
- }
现在我们的 coal_crop.json 是这个样子的:
- {
- "format_version":"1.18.0",
- "minecraft:block":{
- "description":{
- "identifier":"orecrops:coal_crop",
- "properties":{
- "orecrops:growth":[0, 1, 2, 3, 4, 5, 6, 7]
- }
- },
- "components":{
- "minecraft:geometry":"geometry.crop",
- "minecraft:collision_box":false,
- "minecraft:placement_filter":{
- "conditions":[
- {
- "block_filter":["farmland"],
- "allowed_faces":["up"]
- }
- ]
- },
- "minecraft:on_interact":{
- "condition":"query.get_equipped_item_name('main_hand') == 'bone_meal'",
- "event":"usebonemeal_event"
- },
- "minecraft:random_ticking":{
- "on_tick":{
- "event":"grow_event"
- }
- }
- },
- "events":{
- "grow_event":{
- "randomize":[
- {
- "weight":1
- },
- {
- "weight":1,
- "set_block_property":{
- "orecrops:growth":"(query.block_property('orecrops:growth')<7) ? query.block_property('orecrops:growth') + 1 : 7"
- }
- }
- ]
- },
- "usebonemeal_event":{
- "sequence":[
- {
- "decrement_stack":{
- "ignore_game_mode":false
- }
- },
- {
- "run_command":{
- "command":[
- "particle minecraft:crop_growth_emitter ~ ~ ~"
- ]
- }
- },
- {
- "trigger":{
- "event":"grow_event"
- }
- }
- ]
- }
- },
- "permutations":[
- {
- "condition":"query.block_property('orecrops:growth') == 0",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"coal_crop_0",
- "render_method":"alpha_test"
- }
- }
- }
- },
- {
- "condition":"query.block_property('orecrops:growth') == 1",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"coal_crop_1",
- "render_method":"alpha_test"
- }
- }
- }
- },
- {
- "condition":"query.block_property('orecrops:growth') == 2",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"coal_crop_2",
- "render_method":"alpha_test"
- }
- }
- }
- },
- {
- "condition":"query.block_property('orecrops:growth') == 3",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"coal_crop_3",
- "render_method":"alpha_test"
- }
- }
- }
- },
- {
- "condition":"query.block_property('orecrops:growth') == 4",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"coal_crop_4",
- "render_method":"alpha_test"
- }
- }
- }
- },
- {
- "condition":"query.block_property('orecrops:growth') == 5",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"coal_crop_5",
- "render_method":"alpha_test"
- }
- }
- }
- },
- {
- "condition":"query.block_property('orecrops:growth') == 6",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"coal_crop_6",
- "render_method":"alpha_test"
- }
- }
- }
- },
- {
- "condition":"query.block_property('orecrops:growth') == 7",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"coal_crop_7",
- "render_method":"alpha_test"
- }
- }
- }
- }
- ]
- }
- }
现在,一个可生长的作物已经初步成型了,等等——破坏掉它没有掉落物?!
收获
战利品表
我们需要使用战利品表自定义作物的掉落物
在 \BP\loot_tables 目录新建 coal_seed.json 文件作为物品还未成熟时的掉落物的战利品表
- {
- "pools":[ // 随机池列表
- {
- "rolls":1, // 此随机池中的抽取次数
- "entries":[
- {
- "weight":1, // 权重
- "type":"item", // 战利品的类型
- "name":"orecrops:coal_seed", // 战利品的标识
- "functions":[ // 函数列表
- {
- "function":"set_count", // 函数名(设置战利品的数量)
- "count":1 // 数量为 1
- }
- ]
- }
- ]
- }
- ]
- }
在 \BP\loot_tables 目录新建 coal_crop.json 文件作为物品已经成熟时的掉落物的战利品表
- {
- "pools":[
- {
- "rolls":1,
- "entries":[
- {
- "weight":1,
- "type":"item",
- "name":"orecrops:coal_seed",
- "functions":[
- {
- "function":"set_count",
- "count":{
- "min":0, // 随机 0~2 个战利品
- "max":2
- }
- }
- ]
- }
- ]
- },
- {
- "rolls":1,
- "entries":[
- {
- "weight":1,
- "type":"item",
- "name":"minecraft:coal",
- "functions":[
- {
- "function":"set_count",
- "count":{
- "min":1, // 随机 1~3 个战利品
- "max":3
- }
- }
- ]
- }
- ]
- }
- ]
- }
回到方块的 json 文件,使用 minecraft:loot 组件设置战利品表
我们为未成熟的作物方块设置 coal_seed.json 战利品
为成熟的作物方块设置 coal_crop.json 战利品
收获事件
为了在作物成熟的时候右键即可收获,且一株作物可以多次结
- "harvest_event":{
- "spawn_loot":{ // 生成战利品表
- "table":"loot_tables/coal_crop.json"
- },
- "set_block_property":{ // 设置 orecrops:growth 为 5
- "orecrops:growth":"5"
- }
- }
我们还需要在 orecrops:growth 为 7 时的置换中置换 minecraft:on_interact 事件和 minecraft:loot 事件
- {
- "condition":"query.block_property('orecrops:growth') == 7",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"coal_crop_7",
- "render_method":"alpha_test"
- }
- },
- "minecraft:loot":"loot_tables/coal_crop.json",
- "minecraft:on_interact":{
- "event":"harvest_event"
- }
- }
- }
最终,我们的 coal_crop.json 是这样的:
- {
- "format_version":"1.18.0",
- "minecraft:block":{
- "description":{
- "identifier":"orecrops:coal_crop",
- "properties":{
- "orecrops:growth":[0, 1, 2, 3, 4, 5, 6, 7]
- }
- },
- "components":{
- "minecraft:loot":"loot_tables/coal_seed.json",
- "minecraft:geometry":"geometry.crop",
- "minecraft:collision_box":false,
- "minecraft:placement_filter":{
- "conditions":[
- {
- "block_filter":["farmland"],
- "allowed_faces":["up"]
- }
- ]
- },
- "minecraft:on_interact":{
- "condition":"query.get_equipped_item_name('main_hand') == 'bone_meal'",
- "event":"usebonemeal_event"
- },
- "minecraft:random_ticking":{
- "on_tick":{
- "event":"grow_event"
- }
- }
- },
- "events":{
- "grow_event":{
- "randomize":[
- {
- "weight":1
- },
- {
- "weight":1,
- "set_block_property":{
- "orecrops:growth":"(query.block_property('orecrops:growth')<7) ? query.block_property('orecrops:growth') + 1 : 7"
- }
- }
- ]
- },
- "harvest_event":{
- "spawn_loot":{
- "table":"loot_tables/coal_crop.json"
- },
- "set_block_property":{
- "orecrops:growth":"5"
- }
- },
- "usebonemeal_event":{
- "sequence":[
- {
- "decrement_stack":{
- "ignore_game_mode":false
- }
- },
- {
- "run_command":{
- "command":[
- "particle minecraft:crop_growth_emitter ~ ~ ~"
- ]
- }
- },
- {
- "trigger":{
- "event":"grow_event"
- }
- }
- ]
- }
- },
- "permutations":[
- {
- "condition":"query.block_property('orecrops:growth') == 0",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"coal_crop_0",
- "render_method":"alpha_test"
- }
- },
- "minecraft:loot":"loot_tables/coal_seed.json"
- }
- },
- {
- "condition":"query.block_property('orecrops:growth') == 1",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"coal_crop_1",
- "render_method":"alpha_test"
- }
- },
- "minecraft:loot":"loot_tables/coal_seed.json"
- }
- },
- {
- "condition":"query.block_property('orecrops:growth') == 2",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"coal_crop_2",
- "render_method":"alpha_test"
- }
- },
- "minecraft:loot":"loot_tables/coal_seed.json"
- }
- },
- {
- "condition":"query.block_property('orecrops:growth') == 3",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"coal_crop_3",
- "render_method":"alpha_test"
- }
- },
- "minecraft:loot":"loot_tables/coal_seed.json"
- }
- },
- {
- "condition":"query.block_property('orecrops:growth') == 4",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"coal_crop_4",
- "render_method":"alpha_test"
- }
- },
- "minecraft:loot":"loot_tables/coal_seed.json"
- }
- },
- {
- "condition":"query.block_property('orecrops:growth') == 5",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"coal_crop_5",
- "render_method":"alpha_test"
- }
- },
- "minecraft:loot":"loot_tables/coal_seed.json"
- }
- },
- {
- "condition":"query.block_property('orecrops:growth') == 6",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"coal_crop_6",
- "render_method":"alpha_test"
- }
- },
- "minecraft:loot":"loot_tables/coal_seed.json"
- }
- },
- {
- "condition":"query.block_property('orecrops:growth') == 7",
- "components":{
- "minecraft:material_instances":{
- "*":{
- "texture":"coal_crop_7",
- "render_method":"alpha_test"
- }
- },
- "minecraft:loot":"loot_tables/coal_crop.json",
- "minecraft:on_interact":{
- "event":"harvest_event"
- }
- }
- }
- ]
- }
- }
至此,种子与作物方块已经全部完成了,下面一章我们将学习使用自定义合成配方
合成种子
有序合成配方的基本结构
- {
- "format_version":"1.12",
- "minecraft:recipe_shaped":{
- "description":{
- // 描述
- },
- "tags":[
- // 类别
- ],
- "pattern":[
- // 样式
- ],
- "key":{
- // 材料
- },
- "result":{
- // 成品
- }
- }
- }
pattern:有序合成的物品摆放样式
key:使用字符代表物品,用在 pattern 中
- // 写法1
- "字符":"物品的标识"
- //写法2
- "字符":{
- "item": "物品的标识",
- "data": "物品的特殊值(支持 Molang)"
- }
在 \BP\recipes 目录新建一个 coal_seed.json
看看下面 coal_seed.json 的例子就懂了
- {
- "format_version":"1.18.0",
- "minecraft:recipe_shaped": {
- "description":{
- "identifier": "orecrops:coal_seed"
- },
- "tags": ["crafting_table"],
- "pattern": [
- "OOO",
- "OSO",
- "OOO"
- ],
- "key": {
- "O": {
- "item": "minecraft:coal"
- },
- "S": {
- "item": "minecraft:wheat_seeds"
- }
- },
- "result":{
- "item": "orecrops:coal_seed"
- }
- }
- }
向世界推广你的 Addon
为了适配不同语言的游戏,我们在很早就做好了本地化的准备。现在,如果你想增加一门语言的支持,只需要在 \RP\texts 目录新建一个 语言代号.lang,例如 en_US.lang
在这些语言文件中增加两行:
- pack.description=资源包的描述
- pack.name=矿石作物
修改你的包名和描述为 pack.name 和 pack.description
再新建一个文件 languages.json,输入:
- [
- "zh_CN",
- "en_US"
- ]
这样就可以做到预读取语言文件,在不同语言下附加包的名称与描述都会变为与对应语言文件中对应的文本
完
参考与引用
本文在撰写过程中参考或引用了来自以下网站的文本
- Minecraft: Bedrock Edition Creator Documentation | Microsoft Docs
- Bedrock Wiki
- bedrock.dev
- 中文Minecraft Wiki镜像 - 最详细的Minecraft百科_BWIKI_哔哩哔哩
致谢
感谢以下组织、个人、网站、软件在教程编写过程中对本人提供的帮助
- 感谢 RarityEG's Plugin Dev Tutorial 给予本人教程编写模式的灵感
- 感谢 Typora 的开发者制作了这么棒的 Markdown 编辑器
- 感谢 ustc-zzzz (Yanbing Zhao) 开发的 MCBBS Markdown To BBCode Converter 提供 Markdown 转 BBCode 服务
- 感谢阅读至此的你
来自群组: Uncode Studio
稍微有亿些复杂qwq
感谢大佬的分享! 又是学费的一天
这是神迹吗..!
楼主太帅了~
收藏了,回头好好研究下molang
收藏了,回头好好研究下molang
wwwwwwwwwwww
望着望着 发表于 2022-4-22 06:49
wwwwwwwwwwww
aasasasasasasasa
望着望着 发表于 2022-4-22 06:50
aasasasasasasasa
sdsdsdsdsddsdsd
望着望着 发表于 2022-4-22 06:50
sdsdsdsdsddsdsd
ssssssssssssssssssss
哇!学到了学到了!
e,看不懂
我是**完全看不懂
liujinsong48 发表于 2022-4-21 14:00
稍微有亿些复杂qwq
我是看不懂
好复杂 做个矿石不容易啊
物品名称
我们在 \RP\texts 目录下新建一个 zh_CN.json, 在里面输入:
item.orecrops:coal_seed.name=煤炭种子
我们在 zh_CN.json 中输入的这一行“等式”定义了在简体中文语言下 item.orecrops:coal_seed.name 键所对应的文本,以这种方式设置物品名称将方便我们后续进行本地化,与本地化相关的内容我们会在最后学习
这里是不是zh_CN.lang
眼睛:我学会了 大脑:不,你不会
大佬nb
脑子:我学会了
手:不,你没学会
脑子:我学会了
手:不,你没学会
看不太懂啊
mc大佬还是多的,看的我一脸懵
这都是人话吗
lq467 发表于 2022-4-27 12:45
这都是人话吗
emmmm...
采用这种设定一个目标,在完成目标的过程中学习的教程编写模式,就是为了避免看不懂(
后续教程中会更加注重语言组织的,尽量做到通俗易懂且不丢失重要信息
好多啊,都看不过来
好东西要分享阿啊啊啊啊
跟听天书似的
望着望着 发表于 2022-4-22 06:49
wwwwwwwwwwww
eeeeeedfgdg
不容易啊
第一页的大佬直接指出错误太厉害了
看着都会,做的时候要么什么都没有,要么贴图错qwq
感谢大佬的帮助
帮了大忙了
这么厉害,你可以帮帮我吗??
膜拜大佬,跪拜
教程很棒,支持一下qwq
不得不说做的都确实不错
太厉害了 好好学习一下
大佬牛逼 这是嘛啊 我眼睛说学会了 脑袋手 说我放屁
牛批6666666666666666666666666
6666666666666
弱弱的问一句 mod用java编吗
玩了很久MC手记住了,脑子却啥也不懂

完全看不懂 不亏是大佬
什么鬼完全看不懂啊
看懂了唉,看懂了唉(没
好复杂,感觉我这辈子也写不出来qwq
头皮发麻的感觉
每天一好评,快乐你我他
只能说强
确实看不懂 但是大佬确实牛