目录结果整理
21
docs/103.4理解Json/0-总览.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# 总览
|
||||
|
||||
JSON是一种轻量级数据交换格式,也是《我的世界》中用于记录数据的主要格式。在前面的教程中,我们自定义实体、物品、方块乃至战利品表等内容。这些内容本质上都是使用JSON存储的。我们只不过是使用了《我的世界》开发控制台的编辑器可视化地编辑了这些JSON文件,实现了自定义。如果你希望,你完全可以直接编辑JSON文件本身,实现更自由更高级的自定义对象。
|
||||
|
||||
具体而言,在本教程中你将学习如下内容:
|
||||
|
||||
- JSON的数据结构
|
||||
- JSON的故障排除
|
||||
- JSON在《我的世界》中的应用
|
||||
- 如何通过JSON编写《我的世界》模组
|
||||
|
||||
## 如何跟上教程
|
||||
|
||||
跟随教程的脚步,按照教程内指导的步骤一步一步操作。在必要时细心思考,善用教程内提供的信息和资料。对于说明性的章节,你可以多读多思考其中的内涵。对于实践性的章节,你需要按照教程一步一步复现,在自己的手中取得进展。这样,你便可以更快更好地学习本教程相关课程!
|
||||
|
||||
本课程包括如下两类内容:
|
||||
|
||||
- 知识性讲解
|
||||
- 实践操作
|
||||
|
||||
现在,我们要开始教程了,请翻到下一课开始阅读吧!
|
||||
103
docs/103.4理解Json/1-JSON在我的世界基岩版中的应用.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# JSON在我的世界基岩版中的应用
|
||||
|
||||
在《我的世界》中,JSON用于提供一切自定义对象的数据。所有使用这种方式自定义的内容都被称为“数据驱动”的内容。我们可以在《我的世界》用数据驱动的方式定义物品、方块、实体、维度、生物群系、状态效果、魔咒、配方、战利品表、交易、音效、书本等各类内容,几乎涵盖了大部分可自定义的内容。
|
||||
|
||||
值得注意的是,数据驱动的方式只能定义一个对象的“初始状态”。如果要在游戏内运行时中动态地更改内容,你还需要脚本的辅助。这不在本教程的教学范围内,你可以参考《我的世界》开发者官网中找到相关内容。
|
||||
|
||||
## 找到JSON文件的位置
|
||||
|
||||

|
||||
|
||||
任意找到一个配置对象,在“资源管理”窗格中找到对应的文件,点击右键,并点击“打开文件所在位置”,便可以在资源管理器中打开相关文件所在的文件夹。
|
||||
|
||||

|
||||
|
||||
文件名后缀为`.json`的文件便是JSON了。这里,我们以钻石苹果的战利品表为例,打开可以看到相关的JSON内容:
|
||||
|
||||
```json
|
||||
{
|
||||
"pools": [
|
||||
{
|
||||
"entries": [
|
||||
{
|
||||
"functions": [
|
||||
{
|
||||
"count": {
|
||||
"max": 1,
|
||||
"min": 1
|
||||
},
|
||||
"function": "set_count"
|
||||
},
|
||||
{
|
||||
"data": 0,
|
||||
"function": "set_data"
|
||||
}
|
||||
],
|
||||
"name": "test:custom_food",
|
||||
"type": "item",
|
||||
"weight": 1
|
||||
}
|
||||
],
|
||||
"rolls": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
这个JSON的效果和之前我们在编辑器中定义过的“100%掉落一个钻石苹果物品”的效果是一致的。准确的说,编辑器的属性窗格的作用就是可视化地编辑该文件。之后,《我的世界》会加载该文件,并实现我们的战利品表效果。
|
||||
|
||||
## 文件结构
|
||||
|
||||
在文件所在位置的周围探索,你会发现有些JSON数据文件位于名为`behavior_pack_xxxx`的文件夹下,而有些位于`resource_pack_xxxx`文件夹下。前者被称为行为包,后者被称为资源包。不管在行为包还是资源包中,JSON数据文件一般都是成组地被分在不同的子文件夹下。比如战利品表就都位于`loot_tables`文件夹内,而网易的自定义方块则位于`netease_blocks`文件夹下。
|
||||
|
||||
这里,我们给出一些常用的文件夹名称及其内容物。
|
||||
|
||||
| 资源包 | 内容 |
|
||||
| ----------------------- | ------------------ |
|
||||
| `textures` | 纹理 |
|
||||
| `sounds` | 音效、音乐 |
|
||||
| `texts` | 语言文件 |
|
||||
| `materials` | 材质 |
|
||||
| `shaders` | 着色器 |
|
||||
| `models` | 模型 |
|
||||
| `entity` | 实体客户端 |
|
||||
| `attachables` | 附着物 |
|
||||
| `animations` | 动画 |
|
||||
| `animation_controllers` | 动画控制器 |
|
||||
| `render_controllers` | 渲染控制器 |
|
||||
| `netease_items_res` | 中国版物品客户端 |
|
||||
| `effects` | 中国版特效(粒子) |
|
||||
| `particles` | 国际版粒子 |
|
||||
| `fog` | 迷雾 |
|
||||
| `ui` | JSON UI |
|
||||
|
||||
| 行为包 | 内容 |
|
||||
| ----------------------------- | -------------------------- |
|
||||
| `entities` | 实体服务端 |
|
||||
| `netease_items_beh` | 中国版物品服务端 |
|
||||
| `netease_blocks` | 中国版方块 |
|
||||
| `netease_dimension` | 中国版维度 |
|
||||
| `netease_biomes` | 中国版地物 |
|
||||
| `netease_features` | 中国版特征(地物) |
|
||||
| `netease_feature_rules` | 中国版特征规则(地物规则) |
|
||||
| `netease_tab` | 中国版物品分类 |
|
||||
| `netease_group` | 中国版物品分组 |
|
||||
| `netease_recipes` | 中国版配方 |
|
||||
| `netease_effects` | 中国版状态效果 |
|
||||
| `netease_enchants` | 中国版魔咒 |
|
||||
| `netease_micro_blocks` | 中国版微缩方块 |
|
||||
| `netease_large_feature_pools` | 中国版拼图结构池 |
|
||||
| `netease_large_feature_rules` | 中国版拼图规则 |
|
||||
| `customBooks` | 中国版书本 |
|
||||
| `customAchievements` | 中国版成就 |
|
||||
| `animations` | 服务端动画 |
|
||||
| `animation_controllers` | 服务端动画控制器 |
|
||||
| `loot_tables` | 战利品表 |
|
||||
| `trading` | 交易表 |
|
||||
| `spawn_rules` | 实体生成规则 |
|
||||
| `structures` | 结构 |
|
||||
| `functions` | 函数 |
|
||||
| `storyline` | 中国版蓝图 |
|
||||
| `config` | 中国版配置 |
|
||||
|
||||
当然,除了文件夹之外,还有一些零散的单独文件,比如不论是资源包还是行为包,都必修具有的最重要的文件`pack_manifest.json`,被称为清单文件。这些零散的文件大家可以自行在附加包中探索,观察具体的结构。
|
||||
9
docs/103.4理解Json/10-课程总结.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# 课程总结
|
||||
|
||||
在本系列课程中,我们一起学习了JSON的文件结构和JSON在《我的世界》中的应用与各类接口。其中,JSON的文件数据结构和《我的世界》中数据驱动的接口是最为重要的内容。
|
||||
|
||||
在完成本课程后,你将掌握或持有如下内容:
|
||||
|
||||
- 了解JSON的数据结构
|
||||
- 了解如何排除JSON编写中的故障
|
||||
- 了解JSON在《我的世界》中的应用与接口,并知道如何编写相关内容
|
||||
27
docs/103.4理解Json/2-JSON编辑工具与有效原则.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# JSON编辑工具与有效原则
|
||||
|
||||
在初步接触了JSON文件之后,大家都会有一个疑问:应该如何查看和编辑JSON文件呢?在本节中,我们一起来了解都有哪些常用的软件支持编辑JSON文件。
|
||||
|
||||
## 编辑工具
|
||||
|
||||
事实上,作为一种常见的数据存储和交换格式,JSON文件被很多种软件工具所支持。接下来,我们列出几种常见的工具。
|
||||
|
||||
### Visual Studio Code
|
||||
|
||||

|
||||
|
||||
Visual Studio Code是微软开发的一款轻量级通用IDE,可以打开各种主流的文本文件类型,自然包括JSON类型的文件。Visual Studio Code有丰富的代码检查和语法高亮功能;在安装对应扩展之后,还可以具备附加包JSON文件的代码补全和定义跳转等多种智能功能。这非常适合附加包内容的编写。
|
||||
|
||||
下载地址:https://code.visualstudio.com/
|
||||
|
||||
### Notepad++
|
||||
|
||||

|
||||
|
||||
Notepad++是一个轻量级的文本编辑软件,支持相当多文本文档格式,具有打开快速、操作简介的特点,同时各类基础功能一应俱全。不过,Notepad++只适合在你充分熟悉接口时使用,因为他并没有任何智能补全和定义跳转等功能。
|
||||
|
||||
下载地址:https://notepad-plus-plus.org/
|
||||
|
||||
## 有效性
|
||||
|
||||
对于JSON数据格式而言,整个文件内容必须满足特定的结构规则,否则文件整体就会失效。失效的文件自然无法再《我的世界》中进行加载。因此,在编写文件时必须时刻注意文件的语法结构没有被破坏。在接下来的两节中,我们将学习JSON的语法结构和常见的故障模式。
|
||||
39
docs/103.4理解Json/3-JSON数据结构/1-数据结构初步.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# 数据结构初步
|
||||
|
||||
在本章中,我们将全面地了解JSON文件的数据结构。JSON是一种用于存储和交换信息的通用格式,也是我们在《我的世界》附加包中最常接触到的一种文件格式。充分了解这种文件格式有助于我们在编写附加包的过程中得到更加轻松的体验,避免因单纯的语法错误导致不必要的时间损失。
|
||||
|
||||
## JSON
|
||||
|
||||
**JSON**全称<strong><u>J</u>ava<u>S</u>cript <u>O</u>bject <u>N</u>otation</strong>,译为**JavaScript对象表示法**或**JavaScript对象简谱**,念作/ˈdʒeɪsən/或/ˈdʒeɪˌsɒn/。最开始,这种文件格式析取自一种名为JavaScript的程序语言,随着人们发现这种数据格式清晰简洁,非常适合作为一种理想的数据交换语言使用,这种文件格式逐渐脱离了JavaScript,成为了在计算机科学的各处各地都得到了广泛应用的一种轻量数据交换格式。
|
||||
|
||||
首先,我们观察一个使用了JSON文件格式的示例。这是一个附加包中最基本的文件——清单文件的示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": 2,
|
||||
"header": {
|
||||
"description": "resourcePack.vanilla.description",
|
||||
"name": "resourcePack.vanilla.name",
|
||||
"uuid": "0575c61f-a5da-4b7f-9961-ffda2908861e",
|
||||
"version": [0, 0, 1],
|
||||
"min_engine_version": [1, 13, 0]
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"description": "resourcePack.vanilla.description",
|
||||
"type": "resources",
|
||||
"uuid": "53644fac-a276-42e5-843f-a3c6f169a9ab",
|
||||
"version": [0, 0, 1]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
我们此时并不考虑该文件的功能,我们仅使用该文件作为JSON格式学习的示例。我们可以看到,该文件有如下基本结构:
|
||||
|
||||
- 整个文本以左花括号`{`开头,以右花括号`}`结尾。
|
||||
- 文本中可以看到典型的`"冒号前一些东西": 冒号后一些东西`的结构,我们称这种结构为一个**字段**(**Field**)。
|
||||
- 有一些字段后面还有一个英文逗号`,`。
|
||||
- 在一个字段中,“冒号前一些东西”我们称之为**键**(**Key**),“冒号后一些东西”我们称之为**值**(**Value**)。每个字段的键都是用英文的直引号`"`括起来的,但是一个字段值是多种多样的,我们可以看到有数字作为值,有和键一样用英文直引号`"`括起来的内容作为值,也有以左花括号`{`开头,中间又是一堆东西,然后以右花括号`}`结尾,或以左方括号`[`开头,中间一些东西,然后以右方括号`]`结尾的内容作为值。
|
||||
|
||||
有了上述观察,我们不免产生一些疑问,花括号`{}`括起来的东西是什么?为什么要用`"键": 值`这种被称为字段的结构?到底哪些字段后面会存在英文逗号`,`,哪些不存在?键和值都遵循什么规则,都允许存在什么样的形式?在后面的章节中,我们来一一解答这些问题。
|
||||
178
docs/103.4理解Json/3-JSON数据结构/2-对象.md
Normal file
@@ -0,0 +1,178 @@
|
||||
# 对象
|
||||
|
||||
正如JSON的名字——“JavaScript对象表示法”所说的那样,JSON是用来表示一个JavaScript对象的文件格式。只不过,严谨地说,JSON的格式比JavaScript的对象格式还要严格一些,所以我们更愿意直接称呼JSON中表示的这种JavaScript对象为“JSON对象”,或直接与JavaScript中一样简称为**对象**(**Object**)。
|
||||
|
||||
一个对象的特征,或者说标志,便是一对**花括号**`{}`。从左花括号`{`开始,中间写入一些内容,到右花括号`}`结束,这一整个内容便是一个对象。正如我们上面示例中看到的那样,一个JSON文件的全部内容便是一整个对象。注意,**花括号必须成对出现**,如果只有单独的一边的花括号,我们便无法确定从哪儿到哪儿才是一个对象,这种格式便是错误的JSON格式,自然也无法被程序正确解析。
|
||||
|
||||
以下便是一个最简单的对象:
|
||||
|
||||
```json
|
||||
{}
|
||||
```
|
||||
|
||||
我们可以看到,这里的最右花括号之间什么内容都没有,这种对象自然被我们称为**空对象**(**Empty Object**)。那么,如果要向对象中填充内容,我们应该采取什么样的格式呢?没错,答案就是我们在之前的示例中观察到的结果——使用**字段**来描述。
|
||||
|
||||
## 字段
|
||||
|
||||
**字段**是用作在对象中描述一对信息的格式,这对信息中有一部分是用来说明该字段是“用于说明什么属性的”,而另一部分是用来说明该字段“在上述说明的属性下给出的值是多少”。以一个人为例,其名字为小明,身高为170cm,体重为60kg。那么如果我们想把小明描述成对象中的字段,便可以按照如下格式来书写:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "小明",
|
||||
"height": 170,
|
||||
"weight": 60
|
||||
}
|
||||
```
|
||||
|
||||
每个字段的中间都存在一个英文冒号`:`,冒号的左侧我们称之为**键**,右侧我们称之为**值**。每两个两个字段之间使用英文逗号`,`分隔,用来代表他们是不同的字段。在上述示例中,`"name"`、`"height"`和`"weight"`都是键,而对应的`"小明"`、`170`和`60`则是它们各自的值。`"name"`字段结尾处的逗号用于分隔`"name"`字段和`"height"`字段,`"height"`字段结尾处的逗号用于分隔`"height"`字段和`"weight"`字段。`"weight"`字段之后没有其他字段了,所以无需再添加任何逗号,正如`"name"`字段之前也没有任何逗号一样。
|
||||
|
||||
逗号并非一定要写在字段的末尾,他们可以在两个字段之间的任何位置,比如下一个字段的开头。事实上,字段与字段之间,甚至键、值、冒号、逗号、花括号等元素之间,都可以存在任意数量的“**空白**(**Whitespace**)字符”,空白字符包括空格符、制表符、换行符、回车符等。也就是说,不仅仅是逗号可以在空白字符中任意移动自己的位置,事实上,上述小明的示例用下面所展示的任意一种写法都是可行且等价的:
|
||||
|
||||
- 完全收紧:
|
||||
|
||||
```json
|
||||
{"name":"小明","height":170,"weight":60}
|
||||
```
|
||||
|
||||
- 适当空格:
|
||||
|
||||
```json
|
||||
{ "name": "小明", "height": 170, "weight": 60 }
|
||||
```
|
||||
|
||||
- 随意空格:
|
||||
|
||||
```json
|
||||
{ "name" : "小明", "height" : 170, "weight": 60 }
|
||||
```
|
||||
|
||||
- 标准换行:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "小明",
|
||||
"height": 170,
|
||||
"weight": 60
|
||||
}
|
||||
```
|
||||
|
||||
- 逗号左移:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "小明"
|
||||
,"height": 170
|
||||
,"weight": 60
|
||||
}
|
||||
```
|
||||
|
||||
- 放飞自我:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "小明" ,
|
||||
"height" : 170
|
||||
,
|
||||
"weight" :
|
||||
60
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
当然,虽然对于计算机来说,上述的写法都会解析为同样的内容,但是对于人类来说,有些写法还是“为时过早”了。从我们自身和其他人在查阅我们的代码时的可读性的角度出发,上述示例中的“**适当空格**”和“**标准换行**”标签页展示的格式分别是在“同一行写”和“换行写”时**最为推荐的格式**。当然,“完全收紧”的格式也不是毫无用处的,人们在网络传输时往往采用完全收紧的方式剔除掉所有的“无关字符”,以保证文件是“最小化”的,从而使消耗的流量降到最低。
|
||||
|
||||
同时,我们注意到了上述的换行书写示例中,我们的三个字段并没有和两个花括号处在同一竖直线上,换句话说,我们在三个字段的开头分别添加了若干空格。这种行为被称为**缩进**(**Indentation**)。适当的缩进可以使我们的代码更加规范和可读,同时也方便我们检查文件格式有没有出现错误。比如,在上述示例中,我们将一个对象的内容缩进之后,内容中的各字段在同一个竖直线上对齐,对象两侧的花括号在另一个竖直线上互相对齐,这不仅可以快速帮我们定位到该对象的字段,帮助我们快速观察到字段的数目和各自的值,同时也可以帮助我们检查该对象的两个花括号是否成对,有没有“落单”的括号出现等内容,因此,良好的缩进习惯是一个优秀的开发者养成具备习惯之一,否则,如果最后的代码真的写成了上述示例中“放飞自我”的格式,如并非故意,那可真要贻笑大方了。
|
||||
|
||||
一般而言,我们可以使用多种字符充当缩进用的空白字符,但是一旦选择某种字符,便推荐将其在全文统一。常用的缩进用空白字符有单个制表符(即1个TAB),2个、3个或4个空格,当然,你选择其他数量的空格或制表符也是可行的,毕竟这并不违背JSON文件的规范。
|
||||
|
||||
- 1个制表符:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": 2,
|
||||
"header": {
|
||||
"description": "resourcePack.vanilla.description",
|
||||
"name": "resourcePack.vanilla.name",
|
||||
"uuid": "0575c61f-a5da-4b7f-9961-ffda2908861e",
|
||||
"version": [0, 0, 1],
|
||||
"min_engine_version": [1, 13, 0]
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"description": "resourcePack.vanilla.description",
|
||||
"type": "resources",
|
||||
"uuid": "53644fac-a276-42e5-843f-a3c6f169a9ab",
|
||||
"version": [0, 0, 1]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- 2个空格:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": 2,
|
||||
"header": {
|
||||
"description": "resourcePack.vanilla.description",
|
||||
"name": "resourcePack.vanilla.name",
|
||||
"uuid": "0575c61f-a5da-4b7f-9961-ffda2908861e",
|
||||
"version": [0, 0, 1],
|
||||
"min_engine_version": [1, 13, 0]
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"description": "resourcePack.vanilla.description",
|
||||
"type": "resources",
|
||||
"uuid": "53644fac-a276-42e5-843f-a3c6f169a9ab",
|
||||
"version": [0, 0, 1]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- 3个空格:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": 2,
|
||||
"header": {
|
||||
"description": "resourcePack.vanilla.description",
|
||||
"name": "resourcePack.vanilla.name",
|
||||
"uuid": "0575c61f-a5da-4b7f-9961-ffda2908861e",
|
||||
"version": [0, 0, 1],
|
||||
"min_engine_version": [1, 13, 0]
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"description": "resourcePack.vanilla.description",
|
||||
"type": "resources",
|
||||
"uuid": "53644fac-a276-42e5-843f-a3c6f169a9ab",
|
||||
"version": [0, 0, 1]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- 4个空格:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": 2,
|
||||
"header": {
|
||||
"description": "resourcePack.vanilla.description",
|
||||
"name": "resourcePack.vanilla.name",
|
||||
"uuid": "0575c61f-a5da-4b7f-9961-ffda2908861e",
|
||||
"version": [0, 0, 1],
|
||||
"min_engine_version": [1, 13, 0]
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"description": "resourcePack.vanilla.description",
|
||||
"type": "resources",
|
||||
"uuid": "53644fac-a276-42e5-843f-a3c6f169a9ab",
|
||||
"version": [0, 0, 1]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
160
docs/103.4理解Json/3-JSON数据结构/3-数据格式.md
Normal file
@@ -0,0 +1,160 @@
|
||||
# 数据格式
|
||||
|
||||
看到这里,你一定对JSON中的对象具有一定的了解了,但是,我们依旧尚未关注对象中字段的值都允许什么样的类型。我们将目光看向上面的“缩进示例”所描述的文件。如果记忆力不错的话,你一定还记得我们说过这是附加包的清单文件。我们就再次来以这个清单文件为例,学习JSON中的值所允许的数据类型,或者说,数据格式。
|
||||
|
||||
## 数字
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": 2,
|
||||
"header": {
|
||||
},
|
||||
"modules": [
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
JSON中的值允许使用**数字**(**Number**),例如上述的`"format_version": 2`中的值`2`。当然,数字未必是整数,JSON中允许**整数**(**Integer**,**int**)和**浮点数**(**Floating Number**,**float**)两种数字形式。浮点数即我们平常所说的“小数”,或者说“实数”,不过虽然可能会被称为“实数”或“实型”,但是事实上显然是只能接受“有理数”的输入,或者更准确地说,有限小数的输入。以下示例都属于数字数据格式:
|
||||
|
||||
```json
|
||||
{
|
||||
"height": 170,
|
||||
"weight": 60.5,
|
||||
"chest": 90.95,
|
||||
"waist": 62.05,
|
||||
"hip": 96.05
|
||||
}
|
||||
```
|
||||
|
||||
## 对象
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": 2,
|
||||
"header": {
|
||||
"description": "resourcePack.vanilla.description",
|
||||
"name": "resourcePack.vanilla.name",
|
||||
"uuid": "0575c61f-a5da-4b7f-9961-ffda2908861e",
|
||||
"version": [0, 0, 1],
|
||||
"min_engine_version": [1, 13, 0]
|
||||
},
|
||||
"modules": [
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
JSON中字段的值也可以是一个完整的对象,就比如这里`"header"`字段的值即是一个对象,这个对象中又含有`description"`等五个新的字段。对象常用来表达属性之间的包含关系。最外面的对象,在上述示例中也就是第一行和最后一行的花括号所括住的对象,被我们称为该JSON的**根对象**(**Root Object**)。
|
||||
|
||||
## 字符串
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": 2,
|
||||
"header": {
|
||||
"description": "resourcePack.vanilla.description",
|
||||
"name": "resourcePack.vanilla.name",
|
||||
"uuid": "0575c61f-a5da-4b7f-9961-ffda2908861e",
|
||||
"version": [0, 0, 1],
|
||||
"min_engine_version": [1, 13, 0]
|
||||
},
|
||||
"modules": [
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
除了数字和对象之外,JSON中也有一种用于表示“一段文本”的数据格式,那便是**字符串**(**String**)。顾名思义,字符串就是一列字符“串”在一起,即“一段文本”,为了能够使计算机正确解析字符串,正确“认识到”这是一个字符串,我们需要使用**英文直引号**`"`将字符串的两侧括住。以下便是一些字符串的示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "小明",
|
||||
"gender": "",
|
||||
"height": "170cm",
|
||||
"weight": "60.5kg",
|
||||
"chest": "90.95cm",
|
||||
"waist": "62.05cm",
|
||||
"hip": "96.05cm"
|
||||
}
|
||||
```
|
||||
|
||||
由于小明是我虚构的人物,而我并不想擅自假定小明的性别,所以我在`"gender"`字段里留了空,相邻的两个引号`""`也是一种字符串,这种字符串被称为**空字符串**(**Empty String**)。我们可以看到,除了字段的值可以是字符串之外, 字段的键也都是使用英文直引号`"`括起来的形式。虽然并不建议这么理解,但是如果你想的话,你也可以理解为“无论字段的值如何,**字段的键都必须要是字符串的形式**,只不过,字段的键不可以是空字符串”。
|
||||
|
||||
## 数组
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": 2,
|
||||
"header": {
|
||||
"description": "resourcePack.vanilla.description",
|
||||
"name": "resourcePack.vanilla.name",
|
||||
"uuid": "0575c61f-a5da-4b7f-9961-ffda2908861e",
|
||||
"version": [0, 0, 1],
|
||||
"min_engine_version": [1, 13, 0]
|
||||
},
|
||||
"modules": [
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
除了上述我们已经多次观察的值的类型之外,JSON还允许一种特殊的数据类型,这种数据类型被称为**数组**(**Array**)。我们可以观察到,与对象非常类似的是,数组也使用一种形式的括号来作为两边的边界,只不过,数组使用的是方括号`[]`而非花括号。
|
||||
|
||||
我们之前已经知道,对象中的每一个字段都有其“名字”,即它的键,但是,数组中的值并没有与之对应的键,它们唯一的不同在于它们在数组中出现的顺序,即谁是第0位,谁是第1位,谁是第2位等。数组中只有值,数组中每一个值被称为一个**元素**(**Element**)。
|
||||
|
||||
和对象可以拥有任意多的字段一样,数组理论上也可以拥有任意多的元素,但是,有些位置的数组受到游戏接口的限制,只有一部分元素是有效的,且可以被游戏读取。比如,上述示例中的`"version"`和`"min_engine_version"`都只有前三个元素可以被游戏读取并正确解析为版本号,而`"modules"`字段则可以接受并正确读取任意多的元素。不过,这也仅仅是受限于游戏引擎提供的接口而已,这并不是本节想要讲述的内容。单纯从JSON格式上来看,不论你在数组中放置多少个元素,这个JSON文件都是符合格式标准的。
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": 2,
|
||||
"header": {
|
||||
"description": "resourcePack.vanilla.description",
|
||||
"name": "resourcePack.vanilla.name",
|
||||
"uuid": "0575c61f-a5da-4b7f-9961-ffda2908861e",
|
||||
"version": [0, 0, 1],
|
||||
"min_engine_version": [1, 13, 0]
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"description": "resourcePack.vanilla.description",
|
||||
"type": "resources",
|
||||
"uuid": "53644fac-a276-42e5-843f-a3c6f169a9ab",
|
||||
"version": [0, 0, 1]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
数组中和对象中字段的值所接受的类型并没有什么差别,比如上述例子中的`"modules"`数组的元素就是一个对象。数组中元素的顺序,或者说“位置”,被称为该元素的**索引**(**Index**)。注意,**索引都是从0开始计数的**,例如上述的`"modules"`数组只有一个元素,这个元素是一个对象,它的索引是0。
|
||||
|
||||
如果你还记得的话,我们一开始说过,JSON是从JavaScript语言中析取出来的一种格式。在JavaScript中,数组也是一种特殊的对象,或许是因为这个原因,在JSON中,人们有时也会使用一个JSON数组来作为JSON的根“对象”,这并非是一种错误的写法,只不过并不那么常见。以下是一个最外层(即根“对象”)是一个数组的示例:
|
||||
|
||||
```json
|
||||
[
|
||||
"en_US",
|
||||
"zh_CN",
|
||||
"zh_TW"
|
||||
]
|
||||
```
|
||||
|
||||
## 布尔值
|
||||
|
||||
为了纪念伟大的数学家与逻辑学家**乔治·布尔**(George Boole),人们将一种用于表示纯粹的“真”或“假”的概念的数据类型称为**布尔值**(**Boolean Value**,**boolean**,**bool**),这种值的类型被实现到了很多的计算机语言中,JSON中也不例外。在JSON中,我们使用`true`表示“**真**”或者“是”的概念,`false`表示“**假**”或者“否”的概念,二者皆为小写,不可以使用大写的形式。像`true`、`false`这样的预先给定了“只能这么写”的值在JSON中也被称为**字面量**(**Literal**),由于是直接的字面量,所以它们**不需要像字符串那样使用引号将自身括住**。以下是一个使用了布尔值的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "小明",
|
||||
"is_chinese": true,
|
||||
"is_american": false,
|
||||
"is_british": false,
|
||||
"is_japanese": false
|
||||
}
|
||||
```
|
||||
|
||||
## 空值
|
||||
|
||||
和布尔值一样,JSON中还有第三个字面量`null`,被称为**空值**(**Null**),用于代表“空”或“未知”的概念。空值`null`和数字中的`0`、字符串中的空字符串`""`、空对象`{}`、空数组`[]`都不同,它仅仅代表“这里什么都没有”或者“什么都不知道”。比如,我们可以问小明手里有几个苹果,如果回答“0”,那么我们就可以知道小明手里有0个苹果(即没有苹果),但是如果回答“Null”,结果就变成了我们无法知道小明手里有多少苹果,甚至小明有可能身患残疾,根本无法“手持”苹果了,这一点我们也无法从“Null”这个结果中肯定或否定。在一般的JSON编写中,我们并不经常会用到空值`null`,这个值一般是用于防止程序出现意外错误而引入的。注意,如同两个布尔值一样,`null`中的每一个字母也需要小写:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "小明",
|
||||
"handed_apple_count": null
|
||||
}
|
||||
```
|
||||
45
docs/103.4理解Json/3-JSON数据结构/4-注释与存储.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# 注释与存储
|
||||
|
||||
最后,我们来了解JSON的注释与文件存储。
|
||||
|
||||
## 注释
|
||||
|
||||
**注释**(**Comment**)是代码文件中为了阐明上下文信息而写入的一段文本,有效的注释可以使阅读代码变得更加高效。**标准的JSON规范是不支持注释的**,但是**《我的世界》中的JSON全部都支持注释**。注释可以通过两种方式实现,分别是**单行注释**(**Single-line Comment**)和**多行注释**(**Multi-line Comment**)。
|
||||
|
||||
### 单行注释
|
||||
|
||||
我们可以使用连续的两个英文正斜杠`//`来开启一个**单行注释**,从`//`之后的所有部分都将属于注释的内容,不会被当做JSON的正文被计算机解析。以下是一个运用了单行注释的JSON示例:
|
||||
|
||||
```json
|
||||
// 小明的个人信息
|
||||
{
|
||||
"name": "小明", // 姓名
|
||||
"height": 170, // 身高
|
||||
"weight": 60 // 体重
|
||||
}
|
||||
```
|
||||
|
||||
### 多行注释
|
||||
|
||||
单行注释虽然应用起来非常方便,但是还是有诸多限制,例如,单行注释开始之后就必须遇到换行符才能结束注释,并不能通过我们的自由意志来控制何时结束,亦或者,单行注释只能在同一行中进行注释,如果我们想书写一些跨行文本作为注释,就必须在每一行前面都写入两个英文正斜杠`//`,这显得十分冗余。所以,应对上述举例中的情形,我们更愿意使用**多行注释**来解决问题。
|
||||
|
||||
多行注释以连续的一个英文正斜杠和一个星号`/*`开始,以连续的一个星号和一个英文正斜`*/`结束,其中间所有内容皆属于注释内容,不会被计算机解析,示例如下:
|
||||
|
||||
```json
|
||||
/* 小明的个人信息
|
||||
包含了姓名、身高、体重等信息
|
||||
内部数据,不可外传 */
|
||||
{
|
||||
"name": "小明", // 姓名
|
||||
"height": 170, // 身高
|
||||
"weight": 60 // 体重
|
||||
}
|
||||
```
|
||||
|
||||
善用注释,既可以方便自己在后期对代码进行调试,也方便他人对代码进行快速阅读和理解。
|
||||
|
||||
## 文件
|
||||
|
||||
虽然之前介绍过JSON编辑工具,但我们还没有学习如何将JSON保存为一个文件。事实上,JSON保存为文件非常简单,虽然JSON文件的文件扩展名为`.json`,但其事实上就是一个纯文本文件(你可以理解为扩展名为`.json`的TXT文件)。整个文件以左花括号(或左方括号)开始,以右花括号(或右方括号)结束,包含了一整个JSON对象(或数组),这便是一个JSON文件。额外地,JSON文件的MIME类型是“application/json”。
|
||||
|
||||
正确且熟练地编辑JSON文件是《我的世界》附加包学习和开发的基础,请开发者们谨记本节学习到的内容,练习并熟练地应用到附加包开发的过程中。
|
||||
92
docs/103.4理解Json/4-JSON故障排除示例及方法.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# JSON故障排除示例及方法
|
||||
|
||||
在编写JSON的过程中,由于JSON的严谨格式,导致开发者经常会出现不小心就将JSON文件无效化的行为。在本节中,我们举几个常见的错误编写示例,并给出排除方法。
|
||||
|
||||
## 括号遗漏
|
||||
|
||||
JSON中的对象的花括号和数组的方括号都是成对出现的,如果只出现一边而没有出现另一边,便会导致JSON读取错误。虽说良好的缩进习惯可以帮助我们排除括号数量的问题,但还是可能会出现一些意想不到的括号错误。例如:
|
||||
|
||||
```json
|
||||
{
|
||||
"pools": [
|
||||
{
|
||||
"entries": [
|
||||
{
|
||||
"functions": [
|
||||
{
|
||||
"count": {
|
||||
"max": 1,
|
||||
"min": 1
|
||||
},
|
||||
"function": "set_count"
|
||||
},
|
||||
{
|
||||
"data": 0,
|
||||
"function": "set_data"
|
||||
}
|
||||
],
|
||||
"name": "test:custom_food",
|
||||
"type": "item",
|
||||
"weight": 1
|
||||
],
|
||||
"rolls": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
你能很快地定位到上述文件中遗漏的一个括号在哪里吗?相比这也是需要些许时间的。当文件内容更多时,一个括号的错误往往会更难排除。
|
||||
|
||||
排除括号的最简单的方法就是数括号的数量,因为有一个左括号就必定有一个右括号。首先,我们数左花括号的数量,共有6个。然后数右花括号的数量,却发现只有5个。那么我们就确定了一个括号不匹配的问题。
|
||||
|
||||
接下来,我们可以选择从最外层或最内层向另一个方向一对一对地匹配括号,很容易,我们会发现中间这个结构缺少右花括号:
|
||||
|
||||
```json
|
||||
{
|
||||
"functions": [
|
||||
{
|
||||
"count": {
|
||||
"max": 1,
|
||||
"min": 1
|
||||
},
|
||||
"function": "set_count"
|
||||
},
|
||||
{
|
||||
"data": 0,
|
||||
"function": "set_data"
|
||||
}
|
||||
],
|
||||
"name": "test:custom_food",
|
||||
"type": "item",
|
||||
"weight": 1
|
||||
```
|
||||
|
||||
在补上右花括号后,整个JSON重新回到有效状态。
|
||||
|
||||
## 最后的逗号
|
||||
|
||||
不管是对象还是数组,其内容物都是由一些逗号进行分隔。所以,逗号本质上是分隔符,而不是末尾的定界符。这意味着,不管是对象还是数组,其中最后一个元素的末尾都是不需要加逗号的。但是,由于我们的编写习惯,有些时候还是可能会不自觉在最后一个元素后面添加逗号,因此造成整个JSON解析失败。例如:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "小明",
|
||||
"height": 170,
|
||||
"weight": 60,
|
||||
}
|
||||
```
|
||||
|
||||
我们只需要格外注意最后一个元素,并将其逗号去掉即可,例如:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "小明",
|
||||
"height": 170,
|
||||
"weight": 60
|
||||
}
|
||||
```
|
||||
|
||||
## 缩进工具
|
||||
|
||||
大家可以搜索JSON格式化工具、JSON美化工具等关键词,找到一些在线的JSON格式化网页,这些网易能够将你的JSON一件格式化,同时添加合适的缩进,从而更方便大家的JSON数据故障排除。有些工具还能智能地指出一些JSON的错误,直接帮助我们定位到错误行进行故障排除。
|
||||
|
||||
如果你使用Visual Studio Code等IDE进行编辑,也可以享受这些IDE自带的错误提示功能,直接找到错误位置进行故障排除。
|
||||
84
docs/103.4理解Json/5-重温:自定义奖励物品/1-基本属性.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# 基本属性
|
||||
|
||||
在接下来的章节中,我们以先在《我的世界》开发工作台编辑器中添加属性,然后打开具体路径来观察JSON文件的方式回顾学习各种自定义对象的JSON文件写法。接下来,我们先回顾之前的自定义奖励物品。我们首先学习各类常见的基本属性。
|
||||
|
||||
## 在编辑器中添加
|
||||
|
||||

|
||||
|
||||
我们在编辑器中添加一个标识符为`test:test_item`的物品。
|
||||
|
||||

|
||||
|
||||
我们在“行为包属性”中添加如上图所示属性。
|
||||
|
||||

|
||||
|
||||
我们在“资源包”属性中添加如上图所示属性。这样,我们便通过编辑器添加了一些常用的基本属性。
|
||||
|
||||
## 实际文件
|
||||
|
||||
然后我们一起来查看自定义物品的实际文件。物品分为客户端和服务端两个文件,客户端文件在资源包的`netease_items_res`文件夹中,服务端文件在行为包的`netease_items_beh`文件夹中。
|
||||
|
||||
我们打开资源包中的客户端文件,查看如下:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.10",
|
||||
"minecraft:item": {
|
||||
"components": {
|
||||
"minecraft:icon": "test:test_item",
|
||||
"minecraft:use_animation": "eat"
|
||||
},
|
||||
"description": {
|
||||
"category": "Construction",
|
||||
"identifier": "test:test_item",
|
||||
"register_to_create_menu": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
行为包中的服务端文件,查看如下:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.10",
|
||||
"minecraft:item": {
|
||||
"components": {
|
||||
"minecraft:max_damage": 0,
|
||||
"minecraft:max_stack_size": 64,
|
||||
"minecraft:use_duration": 0.0,
|
||||
"netease:allow_offhand": {
|
||||
"value": true
|
||||
},
|
||||
"netease:cooldown": {
|
||||
"category": "",
|
||||
"duration": 0
|
||||
},
|
||||
"netease:enchant_material": {
|
||||
"value": true
|
||||
},
|
||||
"netease:fire_resistant": {
|
||||
"value": true
|
||||
},
|
||||
"netease:fuel": {
|
||||
"duration": 0
|
||||
},
|
||||
"netease:show_in_hand": {
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"category": "Construction",
|
||||
"identifier": "test:test_item"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`format_version`代表该文件的格式版本,控制接口字段的结构。在`minecraft:item`对象下,有两个对象,`description`对象定义了物品的标识符和分类,`components`对象定义了物品的组件,对应编辑器中的“属性”。
|
||||
|
||||
有些组件本身直接就是一个值,例如上面行为包中的`minecraft:max_damage`等。有些组件本身是一个对象,对象中定义了该属性的各个子属性,例如`netease:cooldown`等。
|
||||
|
||||
关于基本属性中各个组件的含义和用法,可以参见官方文档[自定义基础物品](https://mc.163.com/dev/mcmanual/mc-dev/mcguide/20-%E7%8E%A9%E6%B3%95%E5%BC%80%E5%8F%91/15-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%B8%B8%E6%88%8F%E5%86%85%E5%AE%B9/1-%E8%87%AA%E5%AE%9A%E4%B9%89%E7%89%A9%E5%93%81/1-%E8%87%AA%E5%AE%9A%E4%B9%89%E5%9F%BA%E7%A1%80%E7%89%A9%E5%93%81.html?catalog=1)。
|
||||
61
docs/103.4理解Json/5-重温:自定义奖励物品/2-工具.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# 工具
|
||||
|
||||
在本节中,我们学习工具的自定义物品JSON文件。
|
||||
|
||||
## 在编辑器中添加
|
||||
|
||||

|
||||
|
||||
我们创建一个标识符为`test:test_tool`的物品。
|
||||
|
||||

|
||||
|
||||
我们为其添加`minecraft:max_stack_size`、`minecraft:max_damage`和`netease:weapon`属性。在后面我们可以看到,这三个属性本质上是三种组件。
|
||||
|
||||

|
||||
|
||||
然后在武器属性这里我们把所有的子属性都添加上。
|
||||
|
||||

|
||||
|
||||
接着,我们在基础属性中添加`custom_item_type`。
|
||||
|
||||

|
||||
|
||||
并确认值为`weapon`。这样,我们便添加了一个自定义工具的基本配置。你可以先在编辑器中进行一些修改,也可以直接打开JSON修改。
|
||||
|
||||
## 实际文件
|
||||
|
||||
由于以上自定义的属性都位于行为包,这里我们只展示行为包文件的内容:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.10",
|
||||
"minecraft:item": {
|
||||
"components": {
|
||||
"minecraft:max_damage": 0,
|
||||
"minecraft:max_stack_size": 64,
|
||||
"netease:weapon": {
|
||||
"attack_damage": 0,
|
||||
"enchantment": 0,
|
||||
"level": 0,
|
||||
"speed": 0,
|
||||
"type": "hoe"
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"category": "Construction",
|
||||
"custom_item_type": "weapon",
|
||||
"identifier": "test:test_tool"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`minecraft:max_damage`组件是一个整数,代表该工具的最大耐久值。我们可以在JSON中手动将其更改到更高的值。
|
||||
|
||||
`minecraft:max_stack_size`是该工具的最大堆叠数,这里的默认值64是有问题的,我们必须将其更改到1,因为工具应默认不可堆叠。
|
||||
|
||||
`netease:weapon`是网易自己添加的组件,可以用于定义原版的五种工具:剑、镐、斧、锹、锄。具体属性可以至官方文档[自定义武器及工具](https://mc.163.com/dev/mcmanual/mc-dev/mcguide/20-%E7%8E%A9%E6%B3%95%E5%BC%80%E5%8F%91/15-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%B8%B8%E6%88%8F%E5%86%85%E5%AE%B9/1-%E8%87%AA%E5%AE%9A%E4%B9%89%E7%89%A9%E5%93%81/2-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%AD%A6%E5%99%A8%E5%8F%8A%E5%B7%A5%E5%85%B7.html?catalog=1)处查看。
|
||||
|
||||
`description`中的`custom_item_type`是用于自定义特殊物品用的,这里值为`weapon`,用于和`netease:weapon`组件相配合。你依旧可以在上面提及的自定义武器及工具页面找到它的相关信息。
|
||||
54
docs/103.4理解Json/5-重温:自定义奖励物品/3-食物.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# 食物
|
||||
|
||||
在本节中,我们学习食物的自定义物品JSON文件。
|
||||
|
||||
## 在编辑器中添加
|
||||
|
||||

|
||||
|
||||
在前面的系列教程中,我们添加过钻石苹果自定义物品。它的属性如上述所示。
|
||||
|
||||
## 实际文件
|
||||
|
||||
在我们的例子中,我们依旧只需要展示行为包文件:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.10",
|
||||
"minecraft:item": {
|
||||
"components": {
|
||||
"minecraft:foil": true,
|
||||
"minecraft:food": {
|
||||
"can_always_eat": true,
|
||||
"effects": [
|
||||
{
|
||||
"amplifier": 3,
|
||||
"chance": 1.0,
|
||||
"duration": 20,
|
||||
"name": "health_boost"
|
||||
},
|
||||
{
|
||||
"amplifier": 4,
|
||||
"chance": 1.0,
|
||||
"duration": 600,
|
||||
"name": "absorption"
|
||||
}
|
||||
],
|
||||
"nutrition": 16
|
||||
},
|
||||
"minecraft:max_stack_size": 64,
|
||||
"minecraft:use_duration": 20.0
|
||||
},
|
||||
"description": {
|
||||
"category": "Nature",
|
||||
"identifier": "test:custom_food",
|
||||
"register_to_create_menu": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`minecraft:foil`用于物品是否开启铂晕效果,即类似附魔效果的光效。
|
||||
|
||||
`minecraft:food`用于自定义食用效果。`can_always_eat`对应是否可以在满饥饿值状态下食用,类似于金苹果、附魔金苹果。`effects`是食用后出发的状态效果。`nutrition`是食用后恢复的饥饿值。更多的属性可以在基岩版开发维基的[`minecraft:food`](https://wiki.mcbe-dev.net/p/Manual:Minecraft:food#tabber-1.12.0)页面找到名称及其用法。
|
||||
|
||||
100
docs/103.4理解Json/5-重温:自定义奖励物品/4-盔甲.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# 盔甲
|
||||
|
||||
在本节中,我们学习盔甲的自定义物品JSON文件。
|
||||
|
||||
## 在编辑器中添加
|
||||
|
||||

|
||||
|
||||
我们创建一个标识符为`test:test_armor`的自定义物品,注意,为了快速创建一个盔甲,我们可以选择“自定义盔甲”数据模板。
|
||||
|
||||

|
||||
|
||||
此时,我们会额外的看到“盔甲穿戴属性”一栏被填充了内容,这也是自定义盔甲时与众不同的一处。我们会在下面的JSON文件讲解中实际看到这一点。
|
||||
|
||||
## 实际文件
|
||||
|
||||
首先我们查看盔甲物品的行为包文件:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.10",
|
||||
"minecraft:item": {
|
||||
"components": {
|
||||
"minecraft:max_damage": 10,
|
||||
"netease:armor": {
|
||||
"armor_slot": 1,
|
||||
"defense": 20,
|
||||
"enchantment": 10
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"category": "Equipment",
|
||||
"identifier": "test:test_armor",
|
||||
"register_to_create_menu": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
可以看到,`netease:armor`组件定义了盔甲相关参数,`armor_slot`为1代表着定义的是胸甲,`defense`是提供的护甲值的量,`enchantment`是附魔能力。此外,还有一些其它参数,可以参考官方文档[自定义盔甲](https://mc.163.com/dev/mcmanual/mc-dev/mcguide/20-%E7%8E%A9%E6%B3%95%E5%BC%80%E5%8F%91/15-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%B8%B8%E6%88%8F%E5%86%85%E5%AE%B9/1-%E8%87%AA%E5%AE%9A%E4%B9%89%E7%89%A9%E5%93%81/3-%E8%87%AA%E5%AE%9A%E4%B9%89%E7%9B%94%E7%94%B2.html?catalog=1)的解释。
|
||||
|
||||
盔甲和其他物品有一点不同之处在于,他需要使用附着物(Attachable)来盔甲穿戴在玩家身上的效果。附着物是一种类似于客户端实体的对象,这一点在我们之后章节回顾学习了实体JSON写法之后你可以清晰地看到。你可以理解为,附着物是一种挂接在玩家身上的额外部件,而盔甲便是使用这一种对象来渲染穿戴效果。
|
||||
|
||||

|
||||
|
||||
我们打开资源包的`attachables`文件夹,便可以看到对应的附着物JSON文件,我们观察此文件:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"minecraft:attachable": {
|
||||
"description": {
|
||||
"geometry": {
|
||||
"default": "geometry.humanoid.armor.chestplate"
|
||||
},
|
||||
"identifier": "test:test_armor",
|
||||
"materials": {
|
||||
"default": "armor",
|
||||
"enchanted": "armor_enchanted"
|
||||
},
|
||||
"render_controllers": [
|
||||
"controller.render.armor"
|
||||
],
|
||||
"scripts": {
|
||||
"parent_setup": "variable.chest_layer_visible = 0.0;"
|
||||
},
|
||||
"textures": {
|
||||
"default": "textures/models/armor/diamond_1",
|
||||
"enchanted": "textures/misc/enchanted_item_glint"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
首先,在`identifier`字段处我们可以看到该附着物的标识符,这里需要与物品的标识符保持一致,为`test:test_armor`。
|
||||
|
||||
`textures`是该附着物对应的纹理,这里就是盔甲穿戴的纹理。
|
||||
|
||||
`materials`是该附着物渲染用的材质,一般无需更改。
|
||||
|
||||
`geometry`是该附着物使用的模型,这里需要注意,应该与盔甲对应部位模型一致。对于原版而言,有以下四种模型:
|
||||
|
||||
| 模型标识符 | 说明 |
|
||||
| ------------------------------------ | ---- |
|
||||
| `geometry.humanoid.armor.helmet` | 头盔 |
|
||||
| `geometry.humanoid.armor.chestplate` | 胸甲 |
|
||||
| `geometry.humanoid.armor.leggings` | 护腿 |
|
||||
| `geometry.humanoid.armor.boots` | 靴子 |
|
||||
|
||||
你也可以自定义一些你自己的与原版盔甲不同的模型,相关内容都在上面提供过的自定义盔甲官方文档里有详细说明。
|
||||
|
||||
`scripts/parent_setup`是会在父对象(即玩家)初始化时执行的脚本,这里可以使用四种变量来调控玩家渲染效果,更具体的内容,请查看上面提供的自定义盔甲官方文档:
|
||||
|
||||
| 变量标识符 | 说明 |
|
||||
| ------------------------------------ | ---- |
|
||||
| `variable.helmet_layer_visible` | 是否显示玩家皮肤的头盔层 |
|
||||
| `variable.chest_layer_visible` | 是否显示玩家皮肤的胸甲层 |
|
||||
| `variable.leg_layer_visible` | 是否显示玩家皮肤的护腿层 |
|
||||
| `variable.boot_layer_visible` | 是否显示玩家皮肤的靴子层 |
|
||||
BIN
docs/103.4理解Json/5-重温:自定义奖励物品/assets/image-20240922153858628.png
Normal file
|
After Width: | Height: | Size: 67 KiB |
BIN
docs/103.4理解Json/5-重温:自定义奖励物品/assets/image-20240922154442254.png
Normal file
|
After Width: | Height: | Size: 117 KiB |
BIN
docs/103.4理解Json/5-重温:自定义奖励物品/assets/image-20240922154544067.png
Normal file
|
After Width: | Height: | Size: 55 KiB |
BIN
docs/103.4理解Json/5-重温:自定义奖励物品/assets/image-20240922162331823.png
Normal file
|
After Width: | Height: | Size: 67 KiB |
BIN
docs/103.4理解Json/5-重温:自定义奖励物品/assets/image-20240922162434988.png
Normal file
|
After Width: | Height: | Size: 115 KiB |
BIN
docs/103.4理解Json/5-重温:自定义奖励物品/assets/image-20240922163544729.png
Normal file
|
After Width: | Height: | Size: 370 KiB |
BIN
docs/103.4理解Json/5-重温:自定义奖励物品/assets/image-20240922164206394.png
Normal file
|
After Width: | Height: | Size: 860 KiB |
BIN
docs/103.4理解Json/5-重温:自定义奖励物品/assets/image-20240922164243832.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
docs/103.4理解Json/5-重温:自定义奖励物品/assets/image-20240922171303814.png
Normal file
|
After Width: | Height: | Size: 97 KiB |
BIN
docs/103.4理解Json/5-重温:自定义奖励物品/assets/image-20240923095628990.png
Normal file
|
After Width: | Height: | Size: 68 KiB |
BIN
docs/103.4理解Json/5-重温:自定义奖励物品/assets/image-20240923095923388.png
Normal file
|
After Width: | Height: | Size: 57 KiB |
BIN
docs/103.4理解Json/5-重温:自定义奖励物品/assets/image-20240923103524073.png
Normal file
|
After Width: | Height: | Size: 68 KiB |
67
docs/103.4理解Json/6-重温:自定义生物/1-基本结构.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# 基本结构
|
||||
|
||||
在下面这几节中我们一起来回顾学习实体相关的自定义JSON文件。和之前一样,我们首先来回顾编辑器中创建的实体。
|
||||
|
||||
## 在编辑器中添加
|
||||
|
||||

|
||||
|
||||
我们在新建文件向导中新建一个实体配置。标识符设置为`test:test_entity`,模板选择空。
|
||||
|
||||

|
||||
|
||||
可以看到,虽然我们创建了一个空白的实体,但编辑器依旧为我们添加了“持久化保存”的行为包组件,该组件代表着实体在生成之后不会通过自动毁除(despawn)机制毁除,而是会保存至存档中。
|
||||
|
||||
资源包组件中也添加了模型和纹理的相关内容。我们很快会看到在实际JSON文件中他们的表现。
|
||||
|
||||
## 实际文件
|
||||
|
||||
在行为包的`entities`文件夹中,我们可以找到实体的服务端定义文件:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.12.0",
|
||||
"minecraft:entity": {
|
||||
"component_groups": {
|
||||
|
||||
},
|
||||
"components": {
|
||||
"minecraft:persistent": {
|
||||
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"identifier": "test:test_entity",
|
||||
"is_experimental": false
|
||||
},
|
||||
"events": {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
在资源包的`entity`文件夹中,我们可以找到实体的资源包定义文件:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"minecraft:client_entity": {
|
||||
"description": {
|
||||
"geometry": {
|
||||
"default": ""
|
||||
},
|
||||
"identifier": "test:test_entity",
|
||||
"textures": {
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
可以看到,在双端`description`的`identifier`下,定义了相同的实体标识符`test:test_entity`,这可以告诉引擎他们是同一个实体的不同部分。
|
||||
|
||||
服务端定义中的`components`是服务端的组件,这里可以看到持久化组件`minecraft:persistent`已经被添加。`component_groups`是实体的组件组,这是用于控制实体在不同状态之间切换的对象,其中可以分组定义成组的组件,然后我们可以在这些分组之间切换,可以参见Minecraft Wiki的[定义](https://zh.minecraft.wiki/w/%E5%AE%9A%E4%B9%89)页面。`events`是实体的事件,我们可以通过事件来增删组件组。
|
||||
|
||||
在客户端定义中,我们默认只有`description`对象,和`identifier`并列的`textures`用于控制纹理,`geometry`用于控制模型。此外,还有更多的其他属性,大家可以在编辑器中可视化添加这些属性并返回JSON文件查看。我们也会在后续的章节中对其中一部分进行讲解。
|
||||
155
docs/103.4理解Json/6-重温:自定义生物/2-外观.md
Normal file
@@ -0,0 +1,155 @@
|
||||
# 外观
|
||||
|
||||
在本节中,我们回顾学习实体的外观。
|
||||
|
||||
## 在编辑器中添加
|
||||
|
||||

|
||||
|
||||
我们回到之前添加过的守卫实体。可以看到,资源包组件处具有丰富的属性。我们可以尝试浏览这些属性,和后面JSON实际文件中的表现做出对比。
|
||||
|
||||

|
||||
|
||||
点击添加属性,我们也可以实际看到编辑器支持添加的属性列表。
|
||||
|
||||
## 实际文件
|
||||
|
||||
下面,我们一起来看一下守卫实体的资源包中的客户端定义文件:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.8.0",
|
||||
"minecraft:client_entity": {
|
||||
"description": {
|
||||
"animation_controllers": [
|
||||
{
|
||||
"humanoid_baby_big_head": "controller.animation.humanoid.baby_big_head"
|
||||
},
|
||||
{
|
||||
"humanoid_base_pose": "controller.animation.humanoid.base_pose"
|
||||
},
|
||||
{
|
||||
"look_at_target": "controller.animation.humanoid.look_at_target"
|
||||
},
|
||||
{
|
||||
"move": "controller.animation.humanoid.move"
|
||||
},
|
||||
{
|
||||
"riding": "controller.animation.humanoid.riding"
|
||||
},
|
||||
{
|
||||
"holding": "controller.animation.humanoid.holding"
|
||||
},
|
||||
{
|
||||
"brandish_spear": "controller.animation.humanoid.brandish_spear"
|
||||
},
|
||||
{
|
||||
"charging": "controller.animation.humanoid.charging"
|
||||
},
|
||||
{
|
||||
"attack": "controller.animation.humanoid.attack"
|
||||
},
|
||||
{
|
||||
"sneaking": "controller.animation.humanoid.sneaking"
|
||||
},
|
||||
{
|
||||
"bob": "controller.animation.humanoid.bob"
|
||||
},
|
||||
{
|
||||
"damage_nearby_mobs": "controller.animation.humanoid.damage_nearby_mobs"
|
||||
},
|
||||
{
|
||||
"bow_and_arrow": "controller.animation.humanoid.bow_and_arrow"
|
||||
},
|
||||
{
|
||||
"swimming": "controller.animation.humanoid.swimming"
|
||||
},
|
||||
{
|
||||
"use_item_progress": "controller.animation.humanoid.use_item_progress"
|
||||
},
|
||||
{
|
||||
"zombie_attack_bare_hand": "controller.animation.zombie.attack_bare_hand"
|
||||
},
|
||||
{
|
||||
"zombie_swimming": "controller.animation.zombie.swimming"
|
||||
}
|
||||
],
|
||||
"animations": {
|
||||
"attack.rotations": "animation.humanoid.attack.rotations.v1.0",
|
||||
"bob": "animation.humanoid.bob.v1.0",
|
||||
"bow_and_arrow": "animation.humanoid.bow_and_arrow.v1.0",
|
||||
"brandish_spear": "animation.humanoid.brandish_spear.v1.0",
|
||||
"charging": "animation.humanoid.charging.v1.0",
|
||||
"damage_nearby_mobs": "animation.humanoid.damage_nearby_mobs.v1.0",
|
||||
"holding": "animation.humanoid.holding.v1.0",
|
||||
"humanoid_base_pose": "animation.humanoid.base_pose.v1.0",
|
||||
"humanoid_big_head": "animation.humanoid.big_head",
|
||||
"look_at_target_default": "animation.humanoid.look_at_target.default.v1.0",
|
||||
"look_at_target_gliding": "animation.humanoid.look_at_target.gliding.v1.0",
|
||||
"look_at_target_swimming": "animation.humanoid.look_at_target.swimming.v1.0",
|
||||
"move": "animation.humanoid.move.v1.0",
|
||||
"riding.arms": "animation.humanoid.riding.arms.v1.0",
|
||||
"riding.legs": "animation.humanoid.riding.legs.v1.0",
|
||||
"sneaking": "animation.humanoid.sneaking.v1.0",
|
||||
"swimming": "animation.humanoid.swimming.v1.0",
|
||||
"use_item_progress": "animation.humanoid.use_item_progress.v1.0",
|
||||
"zombie_attack_bare_hand": "animation.zombie.attack_bare_hand",
|
||||
"zombie_swimming": "animation.zombie.swimming"
|
||||
},
|
||||
"enable_attachables": true,
|
||||
"geometry": {
|
||||
"default": "geometry.zombie"
|
||||
},
|
||||
"identifier": "test:guard",
|
||||
"materials": {
|
||||
"default": "zombie"
|
||||
},
|
||||
"render_controllers": [
|
||||
"controller.render.zombie"
|
||||
],
|
||||
"scripts": {
|
||||
"pre_animation": [
|
||||
"variable.tcos0 = (Math.cos(query.modified_distance_moved * 38.17) * query.modified_move_speed / variable.gliding_speed_value) * 57.3;"
|
||||
]
|
||||
},
|
||||
"spawn_egg": {
|
||||
"texture": "spawn_egg",
|
||||
"texture_index": 12
|
||||
},
|
||||
"textures": {
|
||||
"default": "textures/entity/guard"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
可以看到,一个已经定义完成的实体的客户端定义文件比空实体要丰富很多。
|
||||
|
||||
曾经,我们通过修改`textures/default`字段修改过守卫实体的纹理,大家现在已经改知道了,这就是修改了JSON中纹理指向的文件路径。
|
||||
|
||||
除了材质`materials`、几何模型`geometry`之外,我们还有一个专门的文件用于控制渲染的结果,那便是渲染控制器。渲染控制器位于资源包的`render_controllers`文件夹中,然后继而被实体客户端的`render_controllers`字段引用。在当前的例子中,实体客户端定义文件下的
|
||||
`render_controllers`引用了原版的`controller.render.zombie`控制器。我们可以打开原版安装文件查看该控制器对应的JSON文件的内容:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version":"1.8.0",
|
||||
"render_controllers":{
|
||||
"controller.render.zombie":{
|
||||
"geometry":"Geometry.default",
|
||||
"materials":[
|
||||
{
|
||||
"*":"Material.default"
|
||||
}
|
||||
],
|
||||
"textures":[
|
||||
"Texture.default"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
渲染控制器具体各个字段的含义可以在官方文档[自定义生物](https://mc.163.com/dev/mcmanual/mc-dev/mcguide/20-%E7%8E%A9%E6%B3%95%E5%BC%80%E5%8F%91/15-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%B8%B8%E6%88%8F%E5%86%85%E5%AE%B9/3-%E8%87%AA%E5%AE%9A%E4%B9%89%E7%94%9F%E7%89%A9/01-%E8%87%AA%E5%AE%9A%E4%B9%89%E5%9F%BA%E7%A1%80%E7%94%9F%E7%89%A9.html?catalog=1)页面中找到。
|
||||
|
||||
此外,实体还有一些动画效果。`animations`字段定义了该实体中可以引用的所有动画,而`animation_controllers`中则定义了该实体使用的动画控制器。实体的动画制作较为繁琐,大家可以在上述自定义生物官方页面中找到具体JSON字段含义,并在官方课程[自定义松鼠实体资源](https://mc.163.com/dev/mcmanual/mc-dev/mconline/15-%E7%8E%A9%E6%B3%95%E7%BB%84%E4%BB%B6%E6%95%99%E7%A8%8B%E3%80%90%E6%96%B0%E7%89%88%E3%80%91/11-%E7%B2%BE%E9%80%9A%E8%87%AA%E5%AE%9A%E4%B9%89%E5%A4%8D%E6%9D%82%E7%9A%84%E5%AE%9E%E4%BD%93/4-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%9D%BE%E9%BC%A0%E5%AE%9E%E4%BD%93%E8%B5%84%E6%BA%90.html?catalog=1)中找到相关制作方法。
|
||||
712
docs/103.4理解Json/6-重温:自定义生物/3-AI.md
Normal file
@@ -0,0 +1,712 @@
|
||||
# AI
|
||||
|
||||
在本节中,我们回顾学习实体的AI控制。
|
||||
|
||||
## 在编辑器中添加
|
||||
|
||||

|
||||
|
||||
依旧以守卫实体为例,我们可以看到在行为包组件中添加了很多以“行为.”开头的组件。这些组件便是与AI行为有关的组件。
|
||||
|
||||

|
||||
|
||||
我们也可以自行添加更多的其他行为。这些行为组件英文都是以`behavior.`开头。
|
||||
|
||||
## 实际文件
|
||||
|
||||
我们来观察守卫实体的行为包定义文件:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.20.10",
|
||||
"minecraft:entity": {
|
||||
"component_groups": {
|
||||
"minecraft:can_break_doors": {
|
||||
"minecraft:annotation.break_door": {
|
||||
|
||||
}
|
||||
},
|
||||
"minecraft:can_have_equipment": {
|
||||
"minecraft:equipment": {
|
||||
"table": "loot_tables/entities/zombie_equipment.json"
|
||||
}
|
||||
},
|
||||
"minecraft:convert_to_baby_drowned": {
|
||||
"minecraft:is_shaking": {
|
||||
|
||||
},
|
||||
"minecraft:transformation": {
|
||||
"delay": {
|
||||
"value": 15
|
||||
},
|
||||
"drop_equipment": true,
|
||||
"into": "minecraft:drowned<minecraft:as_baby>",
|
||||
"transformation_sound": "convert_to_drowned"
|
||||
}
|
||||
},
|
||||
"minecraft:convert_to_drowned": {
|
||||
"minecraft:is_shaking": {
|
||||
|
||||
},
|
||||
"minecraft:transformation": {
|
||||
"delay": {
|
||||
"value": 15
|
||||
},
|
||||
"drop_equipment": true,
|
||||
"into": "minecraft:drowned<minecraft:as_adult>",
|
||||
"transformation_sound": "convert_to_drowned"
|
||||
}
|
||||
},
|
||||
"minecraft:look_to_start_drowned_transformation": {
|
||||
"minecraft:environment_sensor": {
|
||||
"triggers": {
|
||||
"event": "minecraft:start_transforming",
|
||||
"filters": {
|
||||
"operator": "==",
|
||||
"subject": "self",
|
||||
"test": "is_underwater",
|
||||
"value": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"minecraft:start_drowned_transformation": {
|
||||
"minecraft:environment_sensor": {
|
||||
"triggers": {
|
||||
"event": "minecraft:stop_transforming",
|
||||
"filters": {
|
||||
"operator": "==",
|
||||
"subject": "self",
|
||||
"test": "is_underwater",
|
||||
"value": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"minecraft:timer": {
|
||||
"looping": false,
|
||||
"time": 30,
|
||||
"time_down_event": {
|
||||
"event": "minecraft:convert_to_drowned"
|
||||
}
|
||||
}
|
||||
},
|
||||
"minecraft:zombie_adult": {
|
||||
"minecraft:behavior.mount_pathing": {
|
||||
"priority": 2,
|
||||
"speed_multiplier": 1.25,
|
||||
"target_dist": 0.0,
|
||||
"track_target": true
|
||||
},
|
||||
"minecraft:experience_reward": {
|
||||
"on_death": "query.last_hit_by_player ? 5 + (query.equipment_count * Math.Random(1,3)) : 0"
|
||||
},
|
||||
"minecraft:movement": {
|
||||
"value": 0.23
|
||||
},
|
||||
"minecraft:rideable": {
|
||||
"family_types": [
|
||||
"zombie"
|
||||
],
|
||||
"seat_count": 1,
|
||||
"seats": {
|
||||
"lock_rider_rotation": 0,
|
||||
"position": [
|
||||
0.0,
|
||||
1.1,
|
||||
-0.35
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"minecraft:zombie_baby": {
|
||||
"minecraft:experience_reward": {
|
||||
"on_death": "query.last_hit_by_player ? 12 + (query.equipment_count * Math.Random(1,3)) : 0"
|
||||
},
|
||||
"minecraft:is_baby": {
|
||||
|
||||
},
|
||||
"minecraft:movement": {
|
||||
"value": 0.35
|
||||
},
|
||||
"minecraft:scale": {
|
||||
"value": 0.5
|
||||
}
|
||||
},
|
||||
"minecraft:zombie_jockey": {
|
||||
"minecraft:behavior.find_mount": {
|
||||
"max_failed_attempts": 20,
|
||||
"priority": 1,
|
||||
"start_delay": 15,
|
||||
"within_radius": 16
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"minecraft:behavior.delayed_attack": {
|
||||
"attack_duration": 1.0
|
||||
},
|
||||
"minecraft:behavior.equip_item": {
|
||||
"priority": 2
|
||||
},
|
||||
"minecraft:behavior.hurt_by_target": {
|
||||
"priority": 1
|
||||
},
|
||||
"minecraft:behavior.look_at_player": {
|
||||
"look_distance": 6,
|
||||
"priority": 8,
|
||||
"probability": 0.02
|
||||
},
|
||||
"minecraft:behavior.melee_attack": {
|
||||
"priority": 3
|
||||
},
|
||||
"minecraft:behavior.nearest_attackable_target": {
|
||||
"entity_types": [
|
||||
{
|
||||
"filters": {
|
||||
"any_of": [
|
||||
{
|
||||
"subject": "other",
|
||||
"test": "is_family",
|
||||
"value": "player"
|
||||
},
|
||||
{
|
||||
"subject": "other",
|
||||
"test": "is_family",
|
||||
"value": "snowgolem"
|
||||
},
|
||||
{
|
||||
"subject": "other",
|
||||
"test": "is_family",
|
||||
"value": "irongolem"
|
||||
}
|
||||
]
|
||||
},
|
||||
"max_dist": 35
|
||||
},
|
||||
{
|
||||
"filters": {
|
||||
"any_of": [
|
||||
{
|
||||
"subject": "other",
|
||||
"test": "is_family",
|
||||
"value": "villager"
|
||||
},
|
||||
{
|
||||
"subject": "other",
|
||||
"test": "is_family",
|
||||
"value": "wandering_trader"
|
||||
}
|
||||
]
|
||||
},
|
||||
"max_dist": 35,
|
||||
"must_see": false
|
||||
},
|
||||
{
|
||||
"filters": {
|
||||
"all_of": [
|
||||
{
|
||||
"subject": "other",
|
||||
"test": "is_family",
|
||||
"value": "baby_turtle"
|
||||
},
|
||||
{
|
||||
"operator": "!=",
|
||||
"subject": "other",
|
||||
"test": "in_water",
|
||||
"value": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"max_dist": 35
|
||||
}
|
||||
],
|
||||
"must_see": true,
|
||||
"must_see_forget_duration": 17.0,
|
||||
"priority": 2,
|
||||
"reselect_targets": true,
|
||||
"within_radius": 25.0
|
||||
},
|
||||
"minecraft:behavior.pickup_items": {
|
||||
"can_pickup_any_item": true,
|
||||
"excluded_items": [
|
||||
"minecraft:glow_ink_sac"
|
||||
],
|
||||
"goal_radius": 2,
|
||||
"max_dist": 3,
|
||||
"pickup_based_on_chance": true,
|
||||
"priority": 6,
|
||||
"speed_multiplier": 1.0
|
||||
},
|
||||
"minecraft:behavior.random_look_around": {
|
||||
"priority": 9
|
||||
},
|
||||
"minecraft:behavior.random_stroll": {
|
||||
"priority": 7,
|
||||
"speed_multiplier": 1
|
||||
},
|
||||
"minecraft:behavior.stomp_turtle_egg": {
|
||||
"goal_radius": 1.14,
|
||||
"interval": 20,
|
||||
"priority": 4,
|
||||
"search_height": 2,
|
||||
"search_range": 10,
|
||||
"speed_multiplier": 1
|
||||
},
|
||||
"minecraft:breathable": {
|
||||
"breathes_air": true,
|
||||
"breathes_water": true,
|
||||
"suffocate_time": 0,
|
||||
"total_supply": 15
|
||||
},
|
||||
"minecraft:burns_in_daylight": {
|
||||
|
||||
},
|
||||
"minecraft:can_climb": {
|
||||
|
||||
},
|
||||
"minecraft:collision_box": {
|
||||
"height": 1.9,
|
||||
"width": 0.6
|
||||
},
|
||||
"minecraft:conditional_bandwidth_optimization": {
|
||||
|
||||
},
|
||||
"minecraft:despawn": {
|
||||
"despawn_from_distance": {
|
||||
|
||||
}
|
||||
},
|
||||
"minecraft:environment_sensor": {
|
||||
"triggers": {
|
||||
"event": "minecraft:start_transforming",
|
||||
"filters": {
|
||||
"operator": "==",
|
||||
"test": "is_underwater",
|
||||
"value": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"minecraft:equip_item": {
|
||||
|
||||
},
|
||||
"minecraft:health": {
|
||||
"max": 40,
|
||||
"value": 40
|
||||
},
|
||||
"minecraft:hurt_on_condition": {
|
||||
"damage_conditions": [
|
||||
{
|
||||
"cause": "lava",
|
||||
"damage_per_tick": 4,
|
||||
"filters": {
|
||||
"operator": "==",
|
||||
"subject": "self",
|
||||
"test": "in_lava",
|
||||
"value": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"minecraft:is_hidden_when_invisible": {
|
||||
|
||||
},
|
||||
"minecraft:jump.static": {
|
||||
|
||||
},
|
||||
"minecraft:loot": {
|
||||
"table": "loot_tables/entities/zombie.json"
|
||||
},
|
||||
"minecraft:movement.basic": {
|
||||
|
||||
},
|
||||
"minecraft:nameable": {
|
||||
|
||||
},
|
||||
"minecraft:navigation.walk": {
|
||||
"can_break_doors": true,
|
||||
"can_pass_doors": true,
|
||||
"can_walk": true,
|
||||
"is_amphibious": true
|
||||
},
|
||||
"minecraft:persistent": {
|
||||
|
||||
},
|
||||
"minecraft:physics": {
|
||||
|
||||
},
|
||||
"minecraft:pushable": {
|
||||
"is_pushable": true,
|
||||
"is_pushable_by_piston": true
|
||||
},
|
||||
"minecraft:shareables": {
|
||||
"items": [
|
||||
{
|
||||
"item": "minecraft:netherite_sword",
|
||||
"priority": 0,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:diamond_sword",
|
||||
"priority": 1,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:iron_sword",
|
||||
"priority": 2,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:stone_sword",
|
||||
"priority": 3,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:golden_sword",
|
||||
"priority": 4,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:wooden_sword",
|
||||
"priority": 5,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:netherite_helmet",
|
||||
"priority": 0,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:diamond_helmet",
|
||||
"priority": 1,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:iron_helmet",
|
||||
"priority": 2,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:chainmail_helmet",
|
||||
"priority": 3,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:golden_helmet",
|
||||
"priority": 4,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:leather_helmet",
|
||||
"priority": 5,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:turtle_helmet",
|
||||
"priority": 6,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:skull:0",
|
||||
"priority": 7,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:skull:1",
|
||||
"priority": 7,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:carved_pumpkin",
|
||||
"priority": 7,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:netherite_chestplate",
|
||||
"priority": 0,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:diamond_chestplate",
|
||||
"priority": 1,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:iron_chestplate",
|
||||
"priority": 2,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:chainmail_chestplate",
|
||||
"priority": 3,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:golden_chestplate",
|
||||
"priority": 4,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:leather_chestplate",
|
||||
"priority": 5,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:netherite_leggings",
|
||||
"priority": 0,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:diamond_leggings",
|
||||
"priority": 1,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:iron_leggings",
|
||||
"priority": 2,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:chainmail_leggings",
|
||||
"priority": 3,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:golden_leggings",
|
||||
"priority": 4,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:leather_leggings",
|
||||
"priority": 5,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:netherite_boots",
|
||||
"priority": 0,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:diamond_boots",
|
||||
"priority": 1,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:iron_boots",
|
||||
"priority": 2,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:chainmail_boots",
|
||||
"priority": 3,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:golden_boots",
|
||||
"priority": 4,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:leather_boots",
|
||||
"priority": 5,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
}
|
||||
],
|
||||
"singular_pickup": true
|
||||
},
|
||||
"minecraft:type_family": {
|
||||
"family": [
|
||||
"zombie",
|
||||
"undead",
|
||||
"monster",
|
||||
"mob"
|
||||
]
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"identifier": "test:guard",
|
||||
"is_experimental": false,
|
||||
"is_spawnable": true,
|
||||
"is_summonable": true
|
||||
},
|
||||
"events": {
|
||||
"minecraft:as_adult": {
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"minecraft:zombie_adult"
|
||||
]
|
||||
}
|
||||
},
|
||||
"minecraft:as_baby": {
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"minecraft:zombie_baby"
|
||||
]
|
||||
}
|
||||
},
|
||||
"minecraft:convert_to_drowned": {
|
||||
"sequence": [
|
||||
{
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"minecraft:convert_to_drowned"
|
||||
]
|
||||
},
|
||||
"filters": {
|
||||
"operator": "!=",
|
||||
"test": "has_component",
|
||||
"value": "minecraft:is_baby"
|
||||
},
|
||||
"remove": {
|
||||
"component_groups": [
|
||||
"minecraft:start_drowned_transformation"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"minecraft:convert_to_baby_drowned"
|
||||
]
|
||||
},
|
||||
"filters": {
|
||||
"test": "has_component",
|
||||
"value": "minecraft:is_baby"
|
||||
},
|
||||
"remove": {
|
||||
"component_groups": [
|
||||
"minecraft:start_drowned_transformation"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"minecraft:entity_spawned": {
|
||||
"sequence": [
|
||||
{
|
||||
"randomize": [
|
||||
{
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"minecraft:zombie_adult",
|
||||
"minecraft:can_have_equipment"
|
||||
]
|
||||
},
|
||||
"remove": {
|
||||
|
||||
},
|
||||
"weight": 380
|
||||
},
|
||||
{
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"minecraft:zombie_baby",
|
||||
"minecraft:can_have_equipment"
|
||||
]
|
||||
},
|
||||
"remove": {
|
||||
|
||||
},
|
||||
"weight": 17
|
||||
},
|
||||
{
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"minecraft:zombie_baby",
|
||||
"minecraft:zombie_jockey",
|
||||
"minecraft:can_have_equipment"
|
||||
]
|
||||
},
|
||||
"remove": {
|
||||
|
||||
},
|
||||
"weight": 3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"randomize": [
|
||||
{
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"minecraft:can_break_doors"
|
||||
]
|
||||
},
|
||||
"weight": 10
|
||||
},
|
||||
{
|
||||
"weight": 90
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"minecraft:start_transforming": {
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"minecraft:start_drowned_transformation"
|
||||
]
|
||||
},
|
||||
"remove": {
|
||||
"component_groups": [
|
||||
"minecraft:look_to_start_drowned_transformation"
|
||||
]
|
||||
}
|
||||
},
|
||||
"minecraft:stop_transforming": {
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"minecraft:look_to_start_drowned_transformation"
|
||||
]
|
||||
},
|
||||
"remove": {
|
||||
"component_groups": [
|
||||
"minecraft:start_drowned_transformation"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
这相当的复杂,但我们仔细观察,依旧可以在`components`下找到`minecraft:behavior.`开头的相关组件。这边是与编辑器中行为组件相对应的实际文件中的实体组件。特别地,这样的组件被称为AI意向(AI Goal)组件。
|
||||
|
||||
比如,最上方的`minecraft:behavior.delayed_attack`便代表实体具有延迟攻击意向。你可以在官方参考文档[国际版 - 实体AI意向列表](https://mc.163.com/dev/mcmanual/mc-dev/mcguide/20-%E7%8E%A9%E6%B3%95%E5%BC%80%E5%8F%91/100-%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99/13-AIGoalList.html?catalog=1)中找到所有AI意向的列表。
|
||||
|
||||
每一个AI意向都可选地接受一个`priority`字段,代表该意向的优先级,优先级以值更小的为更优先。每一个AI意向也可选地接受一个`control_flags`数组,其中可以添加字符串`look`、`move`、`jump`,用于调整该意向使用的控制旗标。大部分意向的控制旗标是默认选择好的,但对于某一些意向来说,精准调整控制旗标有助于精准控制意向触发的时机,例如`minecraft:behavior.timer_flag_1`、`minecraft:behavior.timer_flag_2`、`minecraft:behavior.timer_flag_3`等计时器意向。
|
||||
|
||||
关于生物AI意向的相关机制内容,可以参考Minecraft Wiki上的[生物AI](https://zh.minecraft.wiki/w/%E7%94%9F%E7%89%A9AI)页面,学习相关内容。
|
||||
77
docs/103.4理解Json/6-重温:自定义生物/4-掉落.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# 掉落
|
||||
|
||||
在本节中,我们学习实体的掉落物机制。
|
||||
|
||||
# 在编辑器中添加
|
||||
|
||||

|
||||
|
||||
我们可以在编辑器中添加行为包组件,并找到`minecraft:loot`。在我们的守卫实体中,该组件已经天然添加到行为包组件中了。
|
||||
|
||||

|
||||
|
||||
可以看到,实体的掉落物也是由一个战利品表控制的。这里使用了原版僵尸的战利品表。
|
||||
|
||||
## 实际文件
|
||||
|
||||

|
||||
|
||||
我们依旧查看行为包的服务端定义文件,这里我们只截取对应组件部分:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.20.10",
|
||||
"minecraft:entity": {
|
||||
"component_groups": {
|
||||
// ...
|
||||
},
|
||||
"components": {
|
||||
// ...
|
||||
"minecraft:loot": {
|
||||
"table": "loot_tables/entities/zombie.json"
|
||||
},
|
||||
// ...
|
||||
},
|
||||
"description": {
|
||||
"identifier": "test:guard",
|
||||
"is_experimental": false,
|
||||
"is_spawnable": true,
|
||||
"is_summonable": true
|
||||
},
|
||||
"events": {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`minecraft:loot`组件的`table`字段引用了一个战利品表。这和方块掉落物一样,我们可以用相同的格式自定义实体的掉落物,即实体的战利品。例如,我们可以把实体的战利品更改为我们的钻石苹果战利品表:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.20.10",
|
||||
"minecraft:entity": {
|
||||
"component_groups": {
|
||||
// ...
|
||||
},
|
||||
"components": {
|
||||
// ...
|
||||
"minecraft:loot": {
|
||||
"table": "loot_tables/diamond_apple_loot.json"
|
||||
},
|
||||
// ...
|
||||
},
|
||||
"description": {
|
||||
"identifier": "test:guard",
|
||||
"is_experimental": false,
|
||||
"is_spawnable": true,
|
||||
"is_summonable": true
|
||||
},
|
||||
"events": {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
当我们的守卫实体被打败时,将不再掉落腐肉,而是掉落一个钻石苹果。
|
||||
BIN
docs/103.4理解Json/6-重温:自定义生物/assets/image-20240923110420440.png
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
docs/103.4理解Json/6-重温:自定义生物/assets/image-20240923110506668.png
Normal file
|
After Width: | Height: | Size: 62 KiB |
BIN
docs/103.4理解Json/6-重温:自定义生物/assets/image-20240923113305258.png
Normal file
|
After Width: | Height: | Size: 68 KiB |
BIN
docs/103.4理解Json/6-重温:自定义生物/assets/image-20240923113418572.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
docs/103.4理解Json/6-重温:自定义生物/assets/image-20240923123129331.png
Normal file
|
After Width: | Height: | Size: 93 KiB |
BIN
docs/103.4理解Json/6-重温:自定义生物/assets/image-20240923123354653.png
Normal file
|
After Width: | Height: | Size: 166 KiB |
BIN
docs/103.4理解Json/6-重温:自定义生物/assets/image-20240923131425596.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
docs/103.4理解Json/6-重温:自定义生物/assets/image-20240923131533155.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
docs/103.4理解Json/6-重温:自定义生物/assets/image-20240923131628453.png
Normal file
|
After Width: | Height: | Size: 73 KiB |
113
docs/103.4理解Json/7-重温:自定义方块/1-基本属性.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# 基本属性
|
||||
|
||||
在下面这几节中我们一起来回顾学习方块相关的自定义JSON文件。首先,我们在编辑器中新建一个自定义方块作为示例并观察他的JSON结构。
|
||||
|
||||
## 在编辑器中创建
|
||||
|
||||

|
||||
|
||||
我们创建一个空的标识符为`test:test_block`的方块。
|
||||
|
||||

|
||||
|
||||
我们在行为包组件中添加一些最基本的常用组件作为示例。
|
||||
|
||||

|
||||
|
||||
以上是添加了行为包组件之后的编辑器中显示效果。
|
||||
|
||||

|
||||
|
||||
我们再在“方块属性列表”栏中添加一些属性。
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
我们如图所示添加一些内容。
|
||||
|
||||
## 实际文件
|
||||
|
||||
虽然只有行为包中有存储方块定义的`netease_blocks`文件夹,但实际上方块也需要在客户端中进行定义。在客户端中定义方块的是一个独立文件`blocks.json`文件,这个文件就位于客户端的根目录中。我们先查看`blocks.json`文件:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": [
|
||||
1,
|
||||
1,
|
||||
0
|
||||
],
|
||||
"test:loot": {
|
||||
"textures": "test:barrel_side"
|
||||
},
|
||||
"test:test_block": {
|
||||
"isotropic": {
|
||||
"down": false,
|
||||
"east": false,
|
||||
"north": false,
|
||||
"south": false,
|
||||
"up": false,
|
||||
"west": false
|
||||
},
|
||||
"sound": "stone",
|
||||
"textures": "test:custom_dirt"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
可以看到,我们定义过的所有方块其实都会出现在这同一文件中,该文件中可以定义方块的一系列客户端属性。`textures`用于定义方块使用的纹理,`sound`用于定义方块使用的音效,`isotropic`用于定义方块是否具有“各向异性”效果,即贴图随着坐标不同随机旋转或变化。
|
||||
|
||||
我们再来观察方块的行为包定义文件。方块的行为包定义文件位于行为包的`netease_blocks`文件夹下,打开之后如下所示:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"minecraft:block": {
|
||||
"components": {
|
||||
"minecraft:destroy_time": {
|
||||
"value": 0.0
|
||||
},
|
||||
"minecraft:explosion_resistance": {
|
||||
"value": 0.0
|
||||
},
|
||||
"minecraft:map_color": {
|
||||
"color": "#000000"
|
||||
},
|
||||
"minecraft:max_stack_size": {
|
||||
"value": 64
|
||||
},
|
||||
"netease:aabb": {
|
||||
"clip": [
|
||||
|
||||
],
|
||||
"collision": [
|
||||
|
||||
]
|
||||
},
|
||||
"netease:fuel": {
|
||||
"duration": 0
|
||||
},
|
||||
"netease:pathable": {
|
||||
"value": true
|
||||
},
|
||||
"netease:render_layer": {
|
||||
"value": "opaque"
|
||||
},
|
||||
"netease:solid": {
|
||||
"value": false
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"identifier": "test:test_block"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
整个结构与物品、实体非常类似,只是组件有所不同。
|
||||
|
||||
`minecraft:destroy_time`用于指定方块的硬度,原版方块的硬度可以在Minecraft Wiki的[方块挖掘时间](https://zh.minecraft.wiki/w/%E6%8C%96%E6%8E%98/%E6%96%B9%E5%9D%97%E6%8C%96%E6%8E%98%E6%97%B6%E9%97%B4)页面找到。`minecraft:explosion_resistance`用于指定方块的爆炸抗性。`minecraft:map_color`用于指定方块在地图上显示的颜色。
|
||||
|
||||
`netease:aabb`是中国版自定义的组件,可以指定方块的碰撞箱和击中箱。`netease:fuel`可以用来指定方块成为熔炉燃料。`netease:pathable`用于指定是否可被生物寻路。`netease:render_layer`用于指定该方块在渲染时的渲染图层,也即渲染时的透明性。`netease:solid`用于指定方块是否有固体属性。
|
||||
|
||||
关于更多的方块组件内容及使用方法,可以参考官方文档自定义方块的[JSON组件](https://mc.163.com/dev/mcmanual/mc-dev/mcguide/20-%E7%8E%A9%E6%B3%95%E5%BC%80%E5%8F%91/15-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%B8%B8%E6%88%8F%E5%86%85%E5%AE%B9/2-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%96%B9%E5%9D%97/1-JSON%E7%BB%84%E4%BB%B6.html?catalog=1)章节。
|
||||
98
docs/103.4理解Json/7-重温:自定义方块/2-物理属性.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# 物理属性
|
||||
|
||||
在本节中,我们回顾学习方块的一些物理属性。
|
||||
|
||||
## 在编辑器中添加
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
我们继续向我们的方块中添加一些属性。
|
||||
|
||||

|
||||
|
||||
同时,我们在方块基础属性中添加`base_block`。
|
||||
|
||||

|
||||
|
||||
并将其设置为重力方块。
|
||||
|
||||

|
||||
|
||||
我们的属性栏中便多出了这些属性。
|
||||
|
||||
## 实际文件
|
||||
|
||||
接下来我们观察方块服务端定义文件的变化:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"minecraft:block": {
|
||||
"components": {
|
||||
"minecraft:block_light_absorption": {
|
||||
"value": 0
|
||||
},
|
||||
"minecraft:block_light_emission": {
|
||||
"emission": 0
|
||||
},
|
||||
"minecraft:destroy_time": {
|
||||
"value": 0.0
|
||||
},
|
||||
"minecraft:explosion_resistance": {
|
||||
"value": 0.0
|
||||
},
|
||||
"minecraft:map_color": {
|
||||
"color": "#000000"
|
||||
},
|
||||
"minecraft:max_stack_size": {
|
||||
"value": 64
|
||||
},
|
||||
"netease:aabb": {
|
||||
"clip": [
|
||||
|
||||
],
|
||||
"collision": [
|
||||
|
||||
]
|
||||
},
|
||||
"netease:fall": {
|
||||
"adjust_percentage": 0.98,
|
||||
"cancel_drop": false,
|
||||
"fall_acceleration": 0.04,
|
||||
"fall_damage_amount": 2.0,
|
||||
"force_break_tick": 600,
|
||||
"hurt_entity": false,
|
||||
"max_fall_damage": 40,
|
||||
"min_height_remove_tick": 100,
|
||||
"send_python_event": false
|
||||
},
|
||||
"netease:fuel": {
|
||||
"duration": 0
|
||||
},
|
||||
"netease:pathable": {
|
||||
"value": true
|
||||
},
|
||||
"netease:render_layer": {
|
||||
"value": "opaque"
|
||||
},
|
||||
"netease:solid": {
|
||||
"value": false
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"base_block": "custom_heavy_block",
|
||||
"identifier": "test:test_block"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
现在我们的方块便具有了一些更多的物理属性,例如与光线的交互,或者是可以像沙子、铁砧那样下落。
|
||||
|
||||
`minecraft:block_light_absorption`用于指定方块的光线吸收度。世界中每个方块都有一个亮度,亮度默认会在向四周传播时如果相隔的是空气,每隔一个方块减少1,如果是一些“固体”方块,则直接减少15级,即不透光。这里我们可以更改这个值,使其阻挡自定义多的光线或者不吸收任何光线。
|
||||
|
||||
`minecraft:block_light_emission`则是定义了一个光源,其值代表光源发出多少级亮度的光。
|
||||
|
||||
`netease:fall`需要配合`description/base_block`为`custom_heavy_block`来使用,定义一个方块可以受重力下落。具体的下落方块字段属性的含义可以参考官方文档[自定义重力方块](https://mc.163.com/dev/mcmanual/mc-dev/mcguide/20-%E7%8E%A9%E6%B3%95%E5%BC%80%E5%8F%91/15-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%B8%B8%E6%88%8F%E5%86%85%E5%AE%B9/2-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%96%B9%E5%9D%97/3-%E7%89%B9%E6%AE%8A%E6%96%B9%E5%9D%97/6-%E8%87%AA%E5%AE%9A%E4%B9%89%E9%87%8D%E5%8A%9B%E6%96%B9%E5%9D%97.html?catalog=1)页面。
|
||||
38
docs/103.4理解Json/7-重温:自定义方块/3-掉落.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# 掉落
|
||||
|
||||
在本节中,我们回顾学习方块的掉落属性。
|
||||
|
||||
## 在编辑器中添加
|
||||
|
||||

|
||||
|
||||
和实体一样,也如之前教程中所教的那样,方块的掉落是由`minecraft:loot`属性控制的。我们可以在行为包属性中找到该属性并添加。
|
||||
|
||||

|
||||
|
||||
我们之前的木桶战利品方块已经添加过该组件了。
|
||||
|
||||
## 实际文件
|
||||
|
||||
我们打开并查看木桶战利品方块的服务端定义文件:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"minecraft:block": {
|
||||
"components": {
|
||||
"minecraft:loot": {
|
||||
"table": "loot_tables/diamond_apple_loot.json"
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"identifier": "test:loot"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`minecraft:loot`便是控制方块被挖掘之后掉落物如何生成的组件,其下的`table`接受一个战利品表。如果没有设置该组件,则默认掉落方块自身。
|
||||
|
||||
当然,如果你希望方块不掉落任何物品,你可以设置原版的空掉落战利品表:`loot_tables/empty.json`。
|
||||
|
||||
125
docs/103.4理解Json/7-重温:自定义方块/4-外观.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# 外观
|
||||
|
||||
最后,我们回顾学习如何修改方块的外观。
|
||||
|
||||
## 在编辑器中添加
|
||||
|
||||

|
||||
|
||||
我们回到`test:test_block`方块,在“方块列表属性”中像这样选中并添加一些属性。
|
||||
|
||||

|
||||
|
||||
在属性栏中,我们产生了如图所示的属性列表。要注意的是,我们此处是为了演示对应关系而将他们全部添加进来了,事实上,在实际操作中,我们未必需要这些全部同时存在。你马上就会知道这些属性之间的含义有哪些异同。
|
||||
|
||||
## 实际文件
|
||||
|
||||
我么打开资源包的`blocks.json`文件:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": [
|
||||
1,
|
||||
1,
|
||||
0
|
||||
],
|
||||
"test:loot": {
|
||||
"textures": "test:barrel_side"
|
||||
},
|
||||
"test:test_block": {
|
||||
"client_entity": {
|
||||
"hand_model_use_client_entity": false,
|
||||
"identifier": ""
|
||||
},
|
||||
"isotropic": {
|
||||
"down": false,
|
||||
"east": false,
|
||||
"north": false,
|
||||
"south": false,
|
||||
"up": false,
|
||||
"west": false
|
||||
},
|
||||
"model_item_texture": "",
|
||||
"model_textures": [
|
||||
|
||||
],
|
||||
"netease_model": "",
|
||||
"sound": "stone",
|
||||
"textures": "test:custom_dirt"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
首先,我们关注`netease_model`字段,这用于控制方块是否使用自定义模型。使用自定义模型的方块如同实体一样,可以拥有更细致的外观。使用这种方法定义的自定义模型必须是网易特有的JSON格式,关于如何制作这种JSON格式,你可以详细参考官方文档的[自定义方块模型](https://mc.163.com/dev/mcmanual/mc-dev/mcguide/20-%E7%8E%A9%E6%B3%95%E5%BC%80%E5%8F%91/15-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%B8%B8%E6%88%8F%E5%86%85%E5%AE%B9/2-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%96%B9%E5%9D%97/5-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%96%B9%E5%9D%97%E6%A8%A1%E5%9E%8B.html?catalog=1)页面。特别地,我们这里展示如何在编辑器中通过导入`.bbmodel`文件来产生网易自定义的方块模型格式:
|
||||
|
||||

|
||||
|
||||
在导入完成后,我们可以在资源包的`models`文件夹下的`netease_block`文件夹中找到对应模型的JSON文件。一个示例的JSON文件形如此:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.13.0",
|
||||
"netease:block_geometry": {
|
||||
"bones": [
|
||||
{
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [-16, 0, 8],
|
||||
"size": [16, 16, 0],
|
||||
"pivot": [-8, 0, 8],
|
||||
"rotation": [0, -45, 0],
|
||||
"uv": {
|
||||
"north": {
|
||||
"texture": 0,
|
||||
"uv": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"uv_size": [
|
||||
16,
|
||||
16
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"origin": [-16, 0, 8],
|
||||
"size": [16, 16, 0],
|
||||
"pivot": [-8, 0, 8],
|
||||
"rotation": [0, 45, 0],
|
||||
"uv": {
|
||||
"north": {
|
||||
"texture": 0,
|
||||
"uv": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"uv_size": [
|
||||
16,
|
||||
16
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "unknown_bone",
|
||||
"pivot": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
}
|
||||
],
|
||||
"description": {
|
||||
"identifier": "customblocks:web_preset",
|
||||
"use_ao": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
该模型文件是网易内置的一个特殊模型文件,标识符可以在文件内容中轻松找到,为`customblocks:web_preset`。由于是内置的,这也意味着我们不能再采用这个标识符作为模型名。
|
||||
|
||||
如果我们将`netease_model`字段设置为这个`customblocks:web_preset`模型,那么我们将允许直接在`blocks.json`文件中配置使用交叉贴图模型的方块。`model_textures`和`model_item_texture`字段将在此时有效。如果`netease_model`字段设置为其他值,这两个字段将无效。关于交叉贴图方块相关字段如何设置可以查看官方文档[自定义交叉贴图方块](https://mc.163.com/dev/mcmanual/mc-dev/mcguide/20-%E7%8E%A9%E6%B3%95%E5%BC%80%E5%8F%91/15-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%B8%B8%E6%88%8F%E5%86%85%E5%AE%B9/2-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%96%B9%E5%9D%97/3-%E7%89%B9%E6%AE%8A%E6%96%B9%E5%9D%97/8-%E8%87%AA%E5%AE%9A%E4%B9%89%E4%BA%A4%E5%8F%89%E8%B4%B4%E5%9B%BE%E6%96%B9%E5%9D%97.html?catalog=1)页面。
|
||||
|
||||
最后我们来看`client_entity`字段。该字段是用于配置客户端方块实体的。方块实体允许方块在客户端使用自定义模型的同时使用与实体一样的模型动画。在这里,我们接受的模型不再是方块模型,而是直接接受一个实体客户端定义文件的标识符,也就是直接引用一个实体客户端定义。可想而知,实体的所有渲染表现形式都可以轻松在这里的方块实体中实现。具体方块实体相关字段的配置可以参考官方文档[自定义方块实体外观](https://mc.163.com/dev/mcmanual/mc-dev/mcguide/20-%E7%8E%A9%E6%B3%95%E5%BC%80%E5%8F%91/15-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%B8%B8%E6%88%8F%E5%86%85%E5%AE%B9/2-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%96%B9%E5%9D%97/4.1-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%96%B9%E5%9D%97%E5%AE%9E%E4%BD%93%E5%A4%96%E8%A7%82.html?catalog=1)页面。
|
||||
BIN
docs/103.4理解Json/7-重温:自定义方块/assets/image-20240923133828819.png
Normal file
|
After Width: | Height: | Size: 56 KiB |
BIN
docs/103.4理解Json/7-重温:自定义方块/assets/image-20240923134435346.png
Normal file
|
After Width: | Height: | Size: 142 KiB |
BIN
docs/103.4理解Json/7-重温:自定义方块/assets/image-20240923134603320.png
Normal file
|
After Width: | Height: | Size: 143 KiB |
BIN
docs/103.4理解Json/7-重温:自定义方块/assets/image-20240923134614534.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
docs/103.4理解Json/7-重温:自定义方块/assets/image-20240923135011974.png
Normal file
|
After Width: | Height: | Size: 334 KiB |
BIN
docs/103.4理解Json/7-重温:自定义方块/assets/image-20240923135117305.png
Normal file
|
After Width: | Height: | Size: 367 KiB |
BIN
docs/103.4理解Json/7-重温:自定义方块/assets/image-20240923135148504.png
Normal file
|
After Width: | Height: | Size: 84 KiB |
BIN
docs/103.4理解Json/7-重温:自定义方块/assets/image-20240923135201136.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
docs/103.4理解Json/7-重温:自定义方块/assets/image-20240923135831634.png
Normal file
|
After Width: | Height: | Size: 144 KiB |
BIN
docs/103.4理解Json/7-重温:自定义方块/assets/image-20240923135844089.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
docs/103.4理解Json/7-重温:自定义方块/assets/image-20240923143330102.png
Normal file
|
After Width: | Height: | Size: 145 KiB |
BIN
docs/103.4理解Json/7-重温:自定义方块/assets/image-20240923143443076.png
Normal file
|
After Width: | Height: | Size: 169 KiB |
BIN
docs/103.4理解Json/7-重温:自定义方块/assets/image-20240923143627218.png
Normal file
|
After Width: | Height: | Size: 324 KiB |
BIN
docs/103.4理解Json/7-重温:自定义方块/assets/image-20240923143659460.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
docs/103.4理解Json/7-重温:自定义方块/assets/image-20240923143731423.png
Normal file
|
After Width: | Height: | Size: 76 KiB |
BIN
docs/103.4理解Json/7-重温:自定义方块/assets/image-20240923212139939.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
docs/103.4理解Json/7-重温:自定义方块/assets/image-20240923212236656.png
Normal file
|
After Width: | Height: | Size: 68 KiB |
BIN
docs/103.4理解Json/7-重温:自定义方块/assets/image-20240923220349153.png
Normal file
|
After Width: | Height: | Size: 363 KiB |
BIN
docs/103.4理解Json/7-重温:自定义方块/assets/image-20240923220437081.png
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
docs/103.4理解Json/7-重温:自定义方块/assets/image-20240923221900104.png
Normal file
|
After Width: | Height: | Size: 71 KiB |
29
docs/103.4理解Json/8-利用开发者官网资源.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# 利用开发者官网资源
|
||||
|
||||

|
||||
|
||||
打开我们的中国版《我的世界》开发者官网:https://mc.163.com/dev/index.html 。你会发现顶栏上有“开发指南”、“教学课程”和“API文档”这三个标签。这些内容便是我们开发者官网的各类开发资源。
|
||||
|
||||
作为优秀的开发者,我们应当善于利用这些资源来充实自己的开发能力。
|
||||
|
||||
## 开发指南
|
||||
|
||||

|
||||
|
||||
开发指南是关于《我的世界》开发过程中遇到的各类话题的功能文档。其中既有各类介绍性文章,也有一些步骤指南和接口列表,以功能使用说明为主。特别地,“玩法开发”板块下的“自定义游戏内容”的主要内容便是本教程讲述的JSON文件相关接口的开发说明。
|
||||
|
||||
## 教学课程
|
||||
|
||||

|
||||
|
||||
教学课程是各类官方系列教程的存放处。这里从附加包开发到网络服插件教程应有尽有。如果你对某种类型的开发感兴趣,可以直接跟随教程的脚步,逐步构建良好的知识体系。
|
||||
|
||||
## API文档
|
||||
|
||||

|
||||
|
||||
API文档则是中国版独有的Python的模组SDK文档,这里包括模组API(一般附加包接口)、Apollo(服务端插件接口)和预设API(预设与零件接口)的相关参考文档,你可以通过左侧导航栏树状视图浏览,也可以快速搜索找到想要的功能接口。
|
||||
|
||||
## 其他资源
|
||||
|
||||
除此之外,开发者官网还有开发者社区、开发者内容管理工具、帮助中心等内容,可以在各个方向为你的开发提供帮助、保驾护航!善用开发者官网的资源,将是你成为开发者大师的第一步。
|
||||
13
docs/103.4理解Json/9-练习时间.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# 练习时间
|
||||
|
||||
在这一节中,你将完成一次自定义JSON文件的任务。你将运用前面学习到的知识,一套新的游戏物品、生物和方块,具体内容你可以自行发挥。
|
||||
|
||||
在本节中,你将完成:
|
||||
|
||||
- 直接利用JSON文件创建一个物品。
|
||||
- 直接利用JSON文件创建一个生物实体。
|
||||
- 直接利用JSON文件创建一个方块。
|
||||
|
||||
## 如何完成练习?
|
||||
|
||||
你需要借助先前所学习到的知识,直接在JSON文件内编写,完成自定义对象的创建。在成功制作一套游戏物品、生物和方块之后,便是算作完成了此次练习!
|
||||
BIN
docs/103.4理解Json/assets/image-20240921223305212.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
docs/103.4理解Json/assets/image-20240921223417607.png
Normal file
|
After Width: | Height: | Size: 72 KiB |
BIN
docs/103.4理解Json/assets/image-20240921223423372.png
Normal file
|
After Width: | Height: | Size: 72 KiB |
BIN
docs/103.4理解Json/assets/image-20240922104248459.png
Normal file
|
After Width: | Height: | Size: 263 KiB |
BIN
docs/103.4理解Json/assets/image-20240922105036614.png
Normal file
|
After Width: | Height: | Size: 129 KiB |
BIN
docs/103.4理解Json/assets/image-20240923224602556.png
Normal file
|
After Width: | Height: | Size: 3.3 MiB |
BIN
docs/103.4理解Json/assets/image-20240923224814355.png
Normal file
|
After Width: | Height: | Size: 676 KiB |
BIN
docs/103.4理解Json/assets/image-20240923225544688.png
Normal file
|
After Width: | Height: | Size: 350 KiB |
BIN
docs/103.4理解Json/assets/image-20240923225817479.png
Normal file
|
After Width: | Height: | Size: 158 KiB |