first commit
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/1.png
Normal file
|
After Width: | Height: | Size: 148 KiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/14.gif
Normal file
|
After Width: | Height: | Size: 1.8 MiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/15.gif
Normal file
|
After Width: | Height: | Size: 1.7 MiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/17.gif
Normal file
|
After Width: | Height: | Size: 3.5 MiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/18.gif
Normal file
|
After Width: | Height: | Size: 522 KiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/19.png
Normal file
|
After Width: | Height: | Size: 647 KiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/2.png
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/20.gif
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/21.gif
Normal file
|
After Width: | Height: | Size: 1.8 MiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/22.gif
Normal file
|
After Width: | Height: | Size: 1.8 MiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/23.gif
Normal file
|
After Width: | Height: | Size: 4.1 MiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/24.gif
Normal file
|
After Width: | Height: | Size: 8.4 MiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/25.png
Normal file
|
After Width: | Height: | Size: 525 KiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/26.png
Normal file
|
After Width: | Height: | Size: 685 KiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/27.png
Normal file
|
After Width: | Height: | Size: 922 KiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/28.gif
Normal file
|
After Width: | Height: | Size: 9.4 MiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/29.gif
Normal file
|
After Width: | Height: | Size: 3.4 MiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/3.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/30.gif
Normal file
|
After Width: | Height: | Size: 2.1 MiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/31.gif
Normal file
|
After Width: | Height: | Size: 5.4 MiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/32.gif
Normal file
|
After Width: | Height: | Size: 8.6 MiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/33.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/40.png
Normal file
|
After Width: | Height: | Size: 909 KiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/41.png
Normal file
|
After Width: | Height: | Size: 116 KiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/42.png
Normal file
|
After Width: | Height: | Size: 119 KiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/43.gif
Normal file
|
After Width: | Height: | Size: 5.9 MiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/7.png
Normal file
|
After Width: | Height: | Size: 891 KiB |
BIN
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/images/9.gif
Normal file
|
After Width: | Height: | Size: 7.8 MiB |
464
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/课程01.接触新自定义方块.md
Normal file
@@ -0,0 +1,464 @@
|
||||
---
|
||||
front: https://nie.res.netease.com/r/pic/20210730/ee109f39-8987-46e0-9fe7-40ebb23060fa.png
|
||||
hard: 进阶
|
||||
time: 30分钟
|
||||
---
|
||||
|
||||
# 开始接触新自定义方块
|
||||
|
||||
打开MCStudio,使用关卡编辑器就可以直接新建一个自定义方块,非常的方便;但是,我们打开文件可以看到,方块的行为放在**netease_blocks**文件夹内,这里主要存放中国版特色的自定义方块,随着版本的更新,原版Add-on的自定义方块也可以实现很多有趣的功能,所以本章将全面展开介绍新自定义方块的概念的用法并制作地图的农作物、家具。
|
||||
|
||||
[认识自定义方块](../../10-addon教程/第09章:自定义方块/课程01.认识自定义方块.md)
|
||||
|
||||

|
||||
|
||||
中国版特色的自定义方块存放在netease_blocks文件夹内,而1.16+的新自定义方块写法需要放在微软的blocks文件夹内。
|
||||
|
||||
<img src="./images/2.png" alt="2" style="zoom:120%;" />
|
||||
|
||||
## 什么是方块属性
|
||||
|
||||
方块属性是1.16版本后新写法的“特色”之一:**properties**,里面可以存放很多属性,其实属性就是数组,用于引擎判断,利用方块属性可以做的很多有趣的功能,比如将方块做成农作物并判断其生长年龄;图中的**farm:age**和**farm:growth**就是判断农作物的。
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.16.100",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "farm:whiteradish",
|
||||
"register_to_creative_menu": true,
|
||||
"properties": { //方块属性
|
||||
"farm:age": [0, 1, 2],
|
||||
"farm:growth": [0, 1, 2, 3, 4, 5]
|
||||
}
|
||||
},
|
||||
"permutations": [···],
|
||||
"events": {···},
|
||||
"components": {···}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
使用**query.block_property**可以获取方块的属性值
|
||||
|
||||
```json
|
||||
"query.block_property('farm:age') == 0"
|
||||
```
|
||||
|
||||
## 什么是方块事件
|
||||
|
||||
想要灵活的修改方块的行为,需要事件的配合:**events**。比如当玩家站在方块上的时候,修改方块的掉落物;我们就需要在方块的组件里添加**触发器**,并且在events内添加响应的事件。
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.16.100",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "farm:my_block"
|
||||
},
|
||||
"components": { //方块组件
|
||||
"minecraft:on_step_on": { //触发器,当站在方块上的时候
|
||||
"event": "farm:drop_loot", //触发此事件
|
||||
"target": "self"
|
||||
}
|
||||
},
|
||||
"events": { //方块事件
|
||||
"farm:drop_loot": { //上方触发器触发的事件
|
||||
"spawn_loot": { //添加方块的掉落物
|
||||
"table": "loot_tables/blocks/my_loot_table.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 什么是方块组合
|
||||
|
||||
方块组合可以根据不同的条件应用于具有MoLang表达式的方法,可以非常自由的调配方块的各种组件,实现很多功能;图中的组合分别添加了不同的MoLang表达式条件,就是当方块属性的**farm:age**为特定值的时候,将下方**components**里的组件加到这个方块中。
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.16.100",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "farm:whiteradish",
|
||||
"register_to_creative_menu": true,
|
||||
"properties": {···}
|
||||
},
|
||||
"permutations": [ //方块组合
|
||||
{
|
||||
"condition": "query.block_property('farm:age') == 0",
|
||||
"components": {···}
|
||||
},
|
||||
{
|
||||
"condition": "query.block_property('farm:age') == 1",
|
||||
"components": {···}
|
||||
},
|
||||
{
|
||||
"condition": "query.block_property('farm:age') == 2",
|
||||
"components": {···}
|
||||
}
|
||||
],
|
||||
"events":{···},
|
||||
"components":{···}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 什么是方块标签
|
||||
|
||||
方块标签可以将不同的方块分组归类,并通过标签获取使用;我将**"tag:farm_plant"**这个标签添加到不同的方块上,当我想要在其它文件中使用或查询的时候,就可以应用这个标签。
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.16.100",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "farm:whiteradish",
|
||||
"register_to_creative_menu": true,
|
||||
"properties": {
|
||||
"farm:age": [0, 1, 2],
|
||||
"farm:growth": [0, 1, 2, 3, 4, 5]
|
||||
}
|
||||
},
|
||||
"permutations": [···],
|
||||
"components": {
|
||||
"tag:farm_plant":{} //方块标签
|
||||
},
|
||||
"events": {···}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
可以获取方块标签的表达式:
|
||||
|
||||
- query.all_tags
|
||||
- query.any_tag
|
||||
- query.block_has_all_tags
|
||||
- query.block_has_any_tag
|
||||
- query.relative_block_has_all_tags
|
||||
- query.relative_block_has_any_tag
|
||||
|
||||
## 新增了哪些方块组件
|
||||
|
||||
### minecraft:unit_cube
|
||||
|
||||
设定方块为普通的立方体
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:unit_cube": {}
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:crafting_table
|
||||
|
||||
设定方块为工作台
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:crafting_table": {
|
||||
"custom_description": "Example Crafting Table", // Name shown in GUI
|
||||
"grid_size": 3, // Currently only supports 3
|
||||
"crafting_tags": ["crafting_table", "custom_crafting_tag"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:material_instances
|
||||
|
||||
方块的材质贴图和渲染方式
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "texture_name",
|
||||
"render_method": "blend",
|
||||
"face_dimming": true,
|
||||
"ambient_occlusion": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:geometry
|
||||
|
||||
方块模型
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:geometry": "geometry.wiki"
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:on_step_on
|
||||
|
||||
触发器,配合事件使用:站在方块上时
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:on_step_on": {
|
||||
"event": "block_event",
|
||||
"target": "self",
|
||||
"condition": "query.block_property('wiki:block_property') == true"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:on_step_off
|
||||
|
||||
触发器,配合事件使用:离开方块上时
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:on_step_off": {
|
||||
"event": "block_event",
|
||||
"target": "self",
|
||||
"condition": "query.block_property('wiki:block_property') == true"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:on_fall_on
|
||||
|
||||
触发器,配合事件使用:方块坠落时
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:on_fall_on": {
|
||||
"event": "block_event",
|
||||
"target": "self",
|
||||
"condition": "query.block_property('wiki:block_property') == true",
|
||||
"min_fall_distance": 5
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:on_placed
|
||||
|
||||
触发器,配合事件使用:方块被放置时
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:on_placed": {
|
||||
"event": "block_event",
|
||||
"target": "self",
|
||||
"condition": "query.block_property('wiki:block_property') == true"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:on_player_placing
|
||||
|
||||
触发器,配合事件使用:玩家放置方块时
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:on_player_placing": {
|
||||
"event": "block_event",
|
||||
"target": "self",
|
||||
"condition": "query.block_property('wiki:block_property') == true"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:on_player_destroyed
|
||||
|
||||
触发器,配合事件使用:玩家破坏方块时
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:on_player_destroyed": {
|
||||
"event": "block_event",
|
||||
"target": "self",
|
||||
"condition": "query.block_property('wiki:block_property') == true"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:on_interact
|
||||
|
||||
触发器,配合事件使用:玩家与方块交互时
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:on_interact": {
|
||||
"event": "block_event",
|
||||
"target": "self",
|
||||
"condition": "query.block_property('wiki:block_property') == true"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:ticking
|
||||
|
||||
触发器,配合事件使用:设置特定值的刻
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:ticking": {
|
||||
"looping": true,
|
||||
"range": [4, 4],
|
||||
"on_tick": {
|
||||
"event": "block_event",
|
||||
"target": "self",
|
||||
"condition": "query.block_property('wiki:block_property') == true"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:random_ticking
|
||||
|
||||
触发器,配合事件使用:设置随机刻
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:random_ticking": {
|
||||
"on_tick": {
|
||||
"event": "block_event",
|
||||
"target": "self",
|
||||
"condition": "query.block_property('wiki:block_property') == true"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:entity_collision
|
||||
|
||||
方块实体的碰撞箱
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:entity_collision": {
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 16, 16]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:entity_collision": false
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:pick_collision
|
||||
|
||||
选择方块时的碰撞箱
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:pick_collision": {
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 16, 16]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:pick_collision": false
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:breakonpush
|
||||
|
||||
设定被活塞推动时会破碎
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:breakonpush": true
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:display_name
|
||||
|
||||
设定方块名称
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:display_name": "Name"
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:breathability
|
||||
|
||||
设定方块的透气性,作为固体或是空气
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:breathability": "solid" // Also accepts 'air'
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:immovable
|
||||
|
||||
设定能否被活塞推动
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:immovable": true
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:onlypistonpush
|
||||
|
||||
设定方块是否会跟随粘性活塞移动
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:onlypistonpush": true
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:placement_filter
|
||||
|
||||
设定方块在什么条件下可以放置
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:placement_filter": {
|
||||
"conditions": [
|
||||
{
|
||||
"block_filter": ["minecraft:dirt"],
|
||||
"allowed_faces": ["up"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:preventsjumping
|
||||
|
||||
设定踩在方块上时是否可以跳跃
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:preventsjumping": true
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:rotation
|
||||
|
||||
设定方块的旋转角度
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:rotation": [90, 180, 0]
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:unwalkable
|
||||
|
||||
设定踩在方块上时是否可以行走
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:unwalkable": true
|
||||
}
|
||||
```
|
||||
455
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/课程02.添加作物方块.md
Normal file
@@ -0,0 +1,455 @@
|
||||
---
|
||||
front: https://nie.res.netease.com/r/pic/20210730/ee109f39-8987-46e0-9fe7-40ebb23060fa.png
|
||||
hard: 进阶
|
||||
time: 40分钟
|
||||
---
|
||||
|
||||
# 开始添加作物方块
|
||||
|
||||
基本了解新的自定义方块写法后,我们开始制作地图中需要的农作物:
|
||||
|
||||
- 农作物有多个生长状态,并且模型和贴图会随着成长而变化
|
||||
- 部分农作物可收获多次
|
||||
- 特殊农作物需要种植在篱笆上
|
||||
|
||||

|
||||
|
||||
<iframe src="https://cc.163.com/act/m/daily/iframeplayer/?id=6152ba9148e27490891f035c" height="600" width="800" allow="fullscreen" />
|
||||
|
||||
|
||||
## 设定农作物不同阶段的生长状态
|
||||
|
||||
首先,我们给自定义方块添加基本的行为组件,使其可以在游戏中正常显示出来;
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.16.100",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "farm:whiteradish",
|
||||
"register_to_creative_menu": true
|
||||
},
|
||||
"permutations": [
|
||||
],
|
||||
"events": {
|
||||
},
|
||||
"components": {
|
||||
"minecraft:placement_filter": { //可以放在耕地上
|
||||
"conditions": [
|
||||
{
|
||||
"allowed_faces": ["up"],
|
||||
"block_filter": ["farmland"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"minecraft:entity_collision": false, //关闭生物碰撞箱
|
||||
"minecraft:pick_collision": { //设定选择时的碰撞箱
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 5, 16]
|
||||
},
|
||||
"minecraft:geometry": "geometry.whiteradish_stage_0", //方块模型
|
||||
"minecraft:material_instances": { //方块的贴图和渲染方法
|
||||
"*": {
|
||||
"texture": "farm:whiteradish_stage_0",
|
||||
"render_method": "alpha_test",
|
||||
"ambient_occlusion": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
||||
接下来,我们为其添加方块属性,并且利用触发器、事件和组合设定在不同属性的情况下,方块也会有明显的变化;
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.16.100",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "farm:whiteradish",
|
||||
"register_to_creative_menu": true,
|
||||
"properties": {
|
||||
"farm:age": [0, 1, 2] //设定农作物共有三个生长阶段
|
||||
}
|
||||
},
|
||||
"permutations": [
|
||||
{
|
||||
"condition": "query.block_property('farm:age') == 0", //组合的条件表达式,当方块属性farm:age等于0时
|
||||
"components": { //满足上方的条件,将下方组件添加到方块中
|
||||
"minecraft:loot": "loot_tables/empty.json",
|
||||
"minecraft:pick_collision": {
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 5, 16]
|
||||
},
|
||||
"minecraft:geometry": "geometry.whiteradish_stage_0",
|
||||
"minecraft:block_light_absorption": 0,
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "farm:whiteradish_stage_0",
|
||||
"render_method": "alpha_test",
|
||||
"ambient_occlusion": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"components": {
|
||||
"minecraft:placement_filter": {
|
||||
"conditions": [
|
||||
{
|
||||
"allowed_faces": ["up"],
|
||||
"block_filter": ["farmland"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"minecraft:entity_collision": false,
|
||||
"minecraft:on_player_placing": { //触发器,玩家放置方块时触发事件
|
||||
"event": "farm:on_player_placing",
|
||||
"target": "self"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"farm:on_player_placing": { //当玩家放置方块时触发此事件,设定方块的生长阶段为0
|
||||
"set_block_property": {
|
||||
"farm:age": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
根据上方图片可以看出,主要分为四个部分,属性、组合、基础组件、事件;这四个部分相互调配,非常灵活;
|
||||
|
||||
再添加一个属性,控制农作物的生长刻数,组合中添加随机刻的触发器,使方块可以根据随机刻触发事件,达到农作物生长的目的;
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.16.100",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "farm:whiteradish",
|
||||
"register_to_creative_menu": true,
|
||||
"properties": {
|
||||
"farm:age": [0, 1, 2],
|
||||
"farm:growth": [0, 1, 2, 3, 4, 5] //生长刻数,每次随机刻触发时都会+1
|
||||
}
|
||||
},
|
||||
"permutations": [
|
||||
{
|
||||
"condition": "query.block_property('farm:age') == 0",
|
||||
"components": {
|
||||
"minecraft:loot": "loot_tables/empty.json",
|
||||
"minecraft:pick_collision": {
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 5, 16]
|
||||
},
|
||||
"minecraft:random_ticking": { //添加随机刻的触发器,触发下方事件
|
||||
"on_tick": {
|
||||
"target": "self",
|
||||
"event": "farm:on_age_count_0" //触发的事件
|
||||
}
|
||||
},
|
||||
"minecraft:geometry": "geometry.whiteradish_stage_0",
|
||||
"minecraft:block_light_absorption": 0,
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "farm:whiteradish_stage_0",
|
||||
"render_method": "alpha_test",
|
||||
"ambient_occlusion": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"components": {···},
|
||||
"events": {
|
||||
"farm:on_age_count_0": { //上方添加的随机刻触发器触发时,响应此事件
|
||||
"sequence": [
|
||||
{
|
||||
"condition": "query.block_property('farm:growth') < 2", //条件,当farm:growth属性小于2时
|
||||
"set_block_property": {
|
||||
"farm:growth": "query.block_property('farm:growth') + 1" //设定方块的属性farm:growth加1
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "query.block_property('farm:growth') == 2", //条件,当farm:growth属性等于2时
|
||||
"trigger": {
|
||||
"event": "farm:on_whiteradish_grow_to_1", //触发新的事件
|
||||
"target": "self"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"farm:on_whiteradish_grow_to_1": { //当farm:growth属性等于2时触发的事件(说明此时随机刻已经触发了3次)
|
||||
"set_block_property": {
|
||||
"farm:age": 1, //设定方块的属性farm:age为1(成长到新的阶段)
|
||||
"farm:growth": 0 //设定方块的属性farm:growth为0(重置随机刻)
|
||||
}
|
||||
},
|
||||
"farm:on_player_placing": {
|
||||
"set_block_property": {
|
||||
"farm:age": 0
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
农作物的生长阶段到1后,条件是farm:age等于0的组合就失效了,所以我们需要添加新的组合表示农作物的新阶段,并且需要在组合中修改模型和贴图使农作物在到达新阶段时有所变化;
|
||||
|
||||
```json
|
||||
{
|
||||
"condition": "query.block_property('farm:age') == 1", //新添加的组合,条件是农作物的生长阶段等于1时
|
||||
"components": {
|
||||
"minecraft:loot": "loot_tables/empty.json",
|
||||
"minecraft:geometry": "geometry.whiteradish_stage_0", //若有不同的模型需要修改
|
||||
"minecraft:block_light_absorption": 0,
|
||||
"minecraft:pick_collision": {
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 8, 16]
|
||||
},
|
||||
"minecraft:random_ticking": { //因为农作物还没有完全成熟,所以仍需要随机刻的触发器
|
||||
"on_tick": {
|
||||
"target": "self",
|
||||
"event": "farm:on_age_count_1"
|
||||
}
|
||||
},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "farm:whiteradish_stage_1", //若有不同的贴图需要修改
|
||||
"render_method": "alpha_test",
|
||||
"ambient_occlusion": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
现在,农作物方块已经可以生长了,我们在编辑器中点击**开发测试**进入到游戏中测试一下。
|
||||
|
||||

|
||||
|
||||
成长阶段像0到1一样,继续添加从1-2的组合和事件,这样,一个较完整的农作物方块就完成了:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.16.100",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "farm:whiteradish",
|
||||
"register_to_creative_menu": true,
|
||||
"properties": {
|
||||
"farm:age": [0, 1, 2],
|
||||
"farm:growth": [0, 1, 2, 3, 4, 5]
|
||||
}
|
||||
},
|
||||
"permutations": [
|
||||
{
|
||||
"condition": "query.block_property('farm:age') == 0",
|
||||
"components": {
|
||||
"minecraft:pick_collision": {
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 5, 16]
|
||||
},
|
||||
"minecraft:random_ticking": {
|
||||
"on_tick": {
|
||||
"target": "self",
|
||||
"event": "farm:on_age_count_0"
|
||||
}
|
||||
},
|
||||
"minecraft:geometry": "geometry.whiteradish_stage_0",
|
||||
"minecraft:block_light_absorption": 0,
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "farm:whiteradish_stage_0",
|
||||
"render_method": "alpha_test",
|
||||
"ambient_occlusion": false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "query.block_property('farm:age') == 1",
|
||||
"components": {
|
||||
"minecraft:geometry": "geometry.whiteradish_stage_0",
|
||||
"minecraft:block_light_absorption": 0,
|
||||
"minecraft:pick_collision": {
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 8, 16]
|
||||
},
|
||||
"minecraft:random_ticking": {
|
||||
"on_tick": {
|
||||
"target": "self",
|
||||
"event": "farm:on_age_count_1"
|
||||
}
|
||||
},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "farm:whiteradish_stage_1",
|
||||
"render_method": "alpha_test",
|
||||
"ambient_occlusion": false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "query.block_property('farm:age') == 2",
|
||||
"components": {
|
||||
"minecraft:geometry": "geometry.whiteradish_stage_2",
|
||||
"minecraft:block_light_absorption": 0,
|
||||
"minecraft:pick_collision": {
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 12, 16]
|
||||
},
|
||||
"minecraft:on_player_destroyed": {
|
||||
"event": "farm:on_destroy_stage_2"
|
||||
},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "farm:whiteradish_stage_2",
|
||||
"render_method": "alpha_test",
|
||||
"ambient_occlusion": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"events": {
|
||||
"farm:on_age_count_0": {
|
||||
"sequence": [
|
||||
{
|
||||
"condition": "query.block_property('farm:growth') < 2",
|
||||
"set_block_property": {
|
||||
"farm:growth": "query.block_property('farm:growth') + 1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "query.block_property('farm:growth') == 2",
|
||||
"trigger": {
|
||||
"event": "farm:on_whiteradish_grow_to_1",
|
||||
"target": "self"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"farm:on_age_count_1": {
|
||||
"sequence": [
|
||||
{
|
||||
"condition": "query.block_property('farm:growth') < 5",
|
||||
"set_block_property": {
|
||||
"farm:growth": "query.block_property('farm:growth') + 1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "query.block_property('farm:growth') == 5",
|
||||
"trigger": {
|
||||
"event": "farm:on_whiteradish_grow_to_2",
|
||||
"target": "self"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"farm:on_player_placing": {
|
||||
"set_block_property": {
|
||||
"farm:age": 0,
|
||||
"farm:growth": 0
|
||||
}
|
||||
},
|
||||
"farm:on_whiteradish_grow_to_1": {
|
||||
"set_block_property": {
|
||||
"farm:age": 1,
|
||||
"farm:growth": 0
|
||||
}
|
||||
},
|
||||
"farm:on_whiteradish_grow_to_2": {
|
||||
"set_block_property": {
|
||||
"farm:age": 2,
|
||||
"farm:growth": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
|
||||
"minecraft:placement_filter": {
|
||||
"conditions": [
|
||||
{
|
||||
"allowed_faces": ["up"],
|
||||
"block_filter": ["farmland"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"minecraft:entity_collision": false,
|
||||
"minecraft:on_player_placing": {
|
||||
"event": "farm:on_player_placing",
|
||||
"target": "self"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 继续完善农作物方块
|
||||
|
||||
现在,我们已经有了农作物方块,不过还不够完整,没有农作物对应的果实和种下农作物需要的种子,我们来添加这些;
|
||||
|
||||
首先是种子,创建一个自定义物品,添加一个放置方块的组件即可。
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.16.100",
|
||||
"minecraft:item": {
|
||||
"description": {
|
||||
"identifier": "farm:whiteradish_seed",
|
||||
"category": "items"
|
||||
},
|
||||
"components": {
|
||||
"minecraft:icon": {
|
||||
"texture": "farm:whiteradish_seed"
|
||||
},
|
||||
"minecraft:ignores_permission": true,
|
||||
"minecraft:block_placer": { //设定此物品可以放置方块
|
||||
"block": "farm:whiteradish",
|
||||
"use_block_description": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
农作物的掉落物也很简单,只需要在农作物成熟的组合中添加一个掉落物表即可!
|
||||
|
||||
```json
|
||||
{
|
||||
"condition": "query.block_property('farm:age') == 2",
|
||||
"components": {
|
||||
"minecraft:loot": "loot_tables/whiteradish.json", //掉落物表路径
|
||||
"minecraft:geometry": "geometry.whiteradish_stage_2",
|
||||
"minecraft:block_light_absorption": 0,
|
||||
"minecraft:pick_collision": {
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 12, 16]
|
||||
},
|
||||
"minecraft:on_player_destroyed": {
|
||||
"event": "farm:on_destroy_stage_2"
|
||||
},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "farm:whiteradish_stage_2",
|
||||
"render_method": "alpha_test",
|
||||
"ambient_occlusion": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<img src="./images/17.gif" alt="17" style="zoom:115%;" />
|
||||
|
||||
713
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/课程03.添加其它的农作物方块.md
Normal file
@@ -0,0 +1,713 @@
|
||||
---
|
||||
front: https://nie.res.netease.com/r/pic/20210730/ee109f39-8987-46e0-9fe7-40ebb23060fa.png
|
||||
hard: 进阶
|
||||
time: 60分钟
|
||||
---
|
||||
|
||||
# 继续添加其它的农作物方块
|
||||
|
||||
上一节中,我们已经完整的制作了白萝卜这一种农作物,接下来我们将把剩余的其它农作物也都添加进来;当然,不同的农作物有不同的生长时间和环境,需要在制作的过程中做出不同程度的修改,首先是与白萝卜相似的以下几种农作物,我们只需要在方块属性中修改生长所需的刻数,就能做到农作物生长时间的把不同。
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.16.100",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "farm:eggplant", //茄子
|
||||
"register_to_creative_menu": true,
|
||||
"properties": {
|
||||
"farm:age": [0, 1, 2],
|
||||
"farm:growth": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] //为growth属性添加更多的刻数
|
||||
}
|
||||
},
|
||||
"permutations": [···],
|
||||
"components": {···},
|
||||
"events": {
|
||||
"farm:on_age_count_0": {
|
||||
"sequence": [
|
||||
{
|
||||
"condition": "query.block_property('farm:growth') < 7", //事件的条件也要修改,当farm:growth小于7时
|
||||
"set_block_property": {
|
||||
"farm:growth": "query.block_property('farm:growth') + 1" //为farm:growth加1
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "query.block_property('farm:growth') == 7", //当farm:growth等于7时
|
||||
"trigger": {
|
||||
"event": "farm:on_whiteradish_grow_to_1", //触发新的事件使其生长
|
||||
"target": "self"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"farm:on_age_count_1": {
|
||||
"sequence": [
|
||||
{
|
||||
"condition": "query.block_property('farm:growth') < 9",
|
||||
"set_block_property": {
|
||||
"farm:growth": "query.block_property('farm:growth') + 1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "query.block_property('farm:growth') == 9",
|
||||
"trigger": {
|
||||
"event": "farm:on_whiteradish_grow_to_2",
|
||||
"target": "self"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"farm:on_player_placing": {
|
||||
"set_block_property": {
|
||||
"farm:age": 0,
|
||||
"farm:growth": 0
|
||||
}
|
||||
},
|
||||
"farm:on_whiteradish_grow_to_1": {
|
||||
"set_block_property": {
|
||||
"farm:age": 1,
|
||||
"farm:growth": 0
|
||||
}
|
||||
},
|
||||
"farm:on_whiteradish_grow_to_2": {
|
||||
"set_block_property": {
|
||||
"farm:age": 2,
|
||||
"farm:growth": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
利用这种方法,我们依次将其它农作物也进行修改:
|
||||
|
||||
| 农作物名称 | 生长时间 |
|
||||
| ---------- | -------------------------------------------------- |
|
||||
| 白萝卜 | 随机刻3次,进入发芽阶段; 随机刻6次,进入成熟阶段 |
|
||||
| 茼蒿 | 随机刻3次,进入发芽阶段; 随机刻6次,进入成熟阶段 |
|
||||
| 菠菜 | 随机刻4次,进入发芽阶段; 随机刻6次,进入成熟阶段 |
|
||||
| 茄子 | 随机刻8次,进入发芽阶段; 随机刻10次,进入成熟阶段 |
|
||||
| 柠檬 | 随机刻8次,进入发芽阶段; 随机刻10次,进入成熟阶段 |
|
||||
|
||||
修改好后,点击编辑器的开发测试进入到游戏中同时种下这些农作物来观察判断一下是否成功;茄子和柠檬设定的随机刻数最多,理应生长的最慢;
|
||||
|
||||

|
||||
|
||||
## 较为特殊的农作物方块
|
||||
|
||||
现在我们已经制作出了五种完整的农作物,它们都有三个成长阶段,并且会随着随机刻的触发而成长,直到最终的成熟;不过这些农作物不能千篇一律,还有其它条件需要遵循,比如下面的两种农作物:
|
||||
|
||||
- 竹笋:在生长为成熟竹笋后,如果没有及时采集,最后会长成竹子(不仅可以种植在耕地上,泥土和灰化土也可以)
|
||||
- 豌豆:需要种植在篱笆方块上(篱笆放在耕地上)
|
||||
|
||||

|
||||
|
||||
竹笋的种植条件只需要在组件中添加灰化土和泥土就可以了:
|
||||
|
||||
```json
|
||||
"minecraft:placement_filter": {
|
||||
"conditions": [
|
||||
{
|
||||
"allowed_faces": ["up"],
|
||||
"block_filter": ["farmland","dirt","podzol"] //耕地、泥土、灰化土
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
而最终会长成竹子也只需要添加一个事件,将竹笋转换为竹子即可:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.16.100",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "farm:bambooshoot",
|
||||
"register_to_creative_menu": true,
|
||||
"properties": {
|
||||
"farm:age": [0, 1, 2],
|
||||
"farm:growth": [0, 1, 2, 3, 4, 5, 6, 7]
|
||||
}
|
||||
},
|
||||
"permutations": [
|
||||
{
|
||||
"condition": "query.block_property('farm:age') == 2", //当farm:age等于2时(说明竹笋已经成熟)
|
||||
"components": {
|
||||
"minecraft:loot": "loot_tables/bambooshoot.json",
|
||||
"minecraft:geometry": "geometry.bambooshoot_stage_2",
|
||||
"minecraft:block_light_absorption": 0,
|
||||
"minecraft:pick_collision": {
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 12, 16]
|
||||
},
|
||||
"minecraft:random_ticking": { //仍然添加随机刻触发器
|
||||
"on_tick": {
|
||||
"target": "self",
|
||||
"event": "farm:on_age_count_2" //触发的事件名
|
||||
}
|
||||
},
|
||||
"minecraft:on_player_destroyed": {
|
||||
"event": "farm:on_destroy_stage_2"
|
||||
},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "farm:bambooshoot_stage_2",
|
||||
"render_method": "alpha_test",
|
||||
"ambient_occlusion": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"components": {
|
||||
},
|
||||
"events": {
|
||||
"farm:setblock_bamboo": { //将竹笋改为竹子的事件
|
||||
"set_block": { //在当前方块位置 放置新的方块
|
||||
"block_type": "minecraft:bamboo" //放置竹子(将竹笋替换为竹子)
|
||||
},
|
||||
"set_block_at_pos": { //位置偏移放置方块
|
||||
"block_type": "minecraft:dirt", //放置泥土
|
||||
"block_offset": [0,-1,0] //Y轴偏移-1(也就是在竹笋下方放置泥土)
|
||||
}
|
||||
},
|
||||
"farm:on_age_count_2": { //上方随机刻触发的事件名
|
||||
"sequence": [
|
||||
{
|
||||
"condition": "query.block_property('farm:growth') < 4", 。
|
||||
"set_block_property": {
|
||||
"farm:growth": "query.block_property('farm:growth') + 1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "query.block_property('farm:growth') == 4",
|
||||
"trigger": {
|
||||
"event": "farm:setblock_bamboo", //当条件符合时触发事件
|
||||
"target": "self"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
||||
豌豆的篱笆实现方式也较简单,给豌豆添加一个组合,条件是farm:age的属性为0,这个组合设置模型和贴图为篱笆,不需要添加随机刻触发器,当玩家使用种子的时候变更farm:age为1,也就对应豌豆第一个成长阶段的组合:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.16.100",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "farm:peas",
|
||||
"register_to_creative_menu": true,
|
||||
"properties": {
|
||||
"farm:age": [0, 1, 2, 3], //添加一个数,0为篱笆,所以1、2、3就对应农作物的三个生长阶段
|
||||
"farm:growth": [0, 1, 2, 3, 4, 5]
|
||||
}
|
||||
},
|
||||
"permutations": [
|
||||
{
|
||||
"condition": "query.block_property('farm:age') == 1",
|
||||
"components": {···}
|
||||
},
|
||||
{
|
||||
"condition": "query.block_property('farm:age') == 2",
|
||||
"components": {···}
|
||||
},
|
||||
{
|
||||
"condition": "query.block_property('farm:age') == 3",
|
||||
"components": {···}
|
||||
},
|
||||
{
|
||||
"condition": "query.block_property('farm:age') == 0", //当farm:age为0时
|
||||
"components": {
|
||||
"minecraft:loot": "loot_tables/empty.json",
|
||||
"minecraft:pick_collision": {
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 16, 16]
|
||||
},
|
||||
"minecraft:geometry": "geometry.bamboo_fence",//模型使用篱笆
|
||||
"minecraft:block_light_absorption": 0,
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "farm:peas_stage_0", //贴图使用篱笆
|
||||
"render_method": "alpha_test",
|
||||
"ambient_occlusion": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"components": {
|
||||
"minecraft:placement_filter": {
|
||||
"conditions": [
|
||||
{
|
||||
"allowed_faces": ["up"],
|
||||
"block_filter": ["farmland"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"minecraft:entity_collision": false,
|
||||
"minecraft:on_player_placing": {
|
||||
"event": "farm:on_player_placing",
|
||||
"target": "self"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"farm:on_age_count_1": {
|
||||
"sequence": [
|
||||
{
|
||||
"condition": "query.block_property('farm:growth') < 3",
|
||||
"set_block_property": {
|
||||
"farm:growth": "query.block_property('farm:growth') + 1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "query.block_property('farm:growth') == 3",
|
||||
"trigger": {
|
||||
"event": "farm:on_whiteradish_grow_to_2",
|
||||
"target": "self"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"farm:on_age_count_2": {
|
||||
"sequence": [
|
||||
{
|
||||
"condition": "query.block_property('farm:growth') < 5",
|
||||
"set_block_property": {
|
||||
"farm:growth": "query.block_property('farm:growth') + 1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "query.block_property('farm:growth') == 5",
|
||||
"trigger": {
|
||||
"event": "farm:on_whiteradish_grow_to_3",
|
||||
"target": "self"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"farm:on_player_placing": {
|
||||
"set_block_property": {
|
||||
"farm:age": 0,
|
||||
"farm:growth": 0
|
||||
}
|
||||
},
|
||||
"farm:on_whiteradish_grow_to_2": {
|
||||
"set_block_property": {
|
||||
"farm:age": 2,
|
||||
"farm:growth": 0
|
||||
}
|
||||
},
|
||||
"farm:on_whiteradish_grow_to_3": {
|
||||
"set_block_property": {
|
||||
"farm:age": 3,
|
||||
"farm:growth": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
现在,豌豆方块刚放下时是篱笆,我们需要继续设定拿种子点击篱笆可以修改豌豆方块的farm:age为1,这里需要使用MODSDK,打开**blocklistener.py**,监听**ItemUseOnAfterServerEvent**事件,当玩家手持物品点击方块时触发:
|
||||
|
||||
```python
|
||||
class Main(ServerSystem):
|
||||
def __init__(self, namespace, system_name):
|
||||
ServerSystem.__init__(self, namespace, system_name)
|
||||
self.ListenForEvent(namespace, system_name,
|
||||
'ItemUseOnAfterServerEvent', self, self.using_block) #监听事件
|
||||
|
||||
def using_block(self, event):
|
||||
#从事件中取需要的参数:玩家id、方块名称、方块附加值、手持物品的信息字典、方块的坐标
|
||||
playerid = event['entityId']
|
||||
blockname = event['blockName']
|
||||
blockaux = event['blockAuxValue']
|
||||
itemname = event['itemDict']
|
||||
x = event['x']
|
||||
y = event['y']
|
||||
z = event['z']
|
||||
#逻辑中需要用到的接口
|
||||
item_comp = serverApi.GetEngineCompFactory().CreateItem(playerid)
|
||||
blockstatecomp = serverApi.GetEngineCompFactory().CreateBlockState(serverApi.GetLevelId())
|
||||
#判断 手持的物品是否是豌豆种子、点击的方块是否是豌豆方块、并且方块的附加值为0(farm:age对应的值就代表blockaux)
|
||||
if blockname == 'farm:peas' and itemname['newItemName'] == 'farm:peas_seed' and blockaux == 0:
|
||||
#获取手持物品的信息
|
||||
carried_item = item_comp.GetPlayerItem(ItemPosType.CARRIED, 0, True)
|
||||
#设定手持物品的数量-1
|
||||
carried_item['count'] -= 1
|
||||
#将更改数量后的物品信息设置到玩家上
|
||||
item_comp.SetPlayerAllItems({(ItemPosType.CARRIED,0):carried_item})
|
||||
#获取对应坐标的方块
|
||||
state = blockstatecomp.GetBlockStates((x,y,z), 0)
|
||||
#将方块的farm:age改为1
|
||||
state['farm:age'] = 1
|
||||
#将更改后的方块替换到获取的坐标上
|
||||
blockstatecomp.SetBlockStates((x,y,z), state, 0)
|
||||
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 增加农作物可收获的次数
|
||||
|
||||
| 农作物名称 | 生长时间 | 收获期数 |
|
||||
| ---------- | --------------------------------------------------- | -------- |
|
||||
| 玉米 | 随机刻8次,进入发芽阶段; 随机刻12次,进入成熟阶段 | 2次 |
|
||||
| 香蕉 | 随机刻10次,进入发芽阶段; 随机刻12次,进入成熟阶段 | 2次 |
|
||||
|
||||
对于香蕉、玉米这种可以收获多次的农作物,我们需要继续添加新功能使其可以在收获完后回到发芽阶段继续生长:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.16.100",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "farm:corn",
|
||||
"register_to_creative_menu": true,
|
||||
"properties": {
|
||||
"farm:age": [0, 1, 2, 3, 4], //添加两个阶段
|
||||
"farm:growth": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
|
||||
}
|
||||
},
|
||||
"permutations": [
|
||||
{
|
||||
"condition": "query.block_property('farm:age') == 0",
|
||||
"components": {···}
|
||||
},
|
||||
{
|
||||
"condition": "query.block_property('farm:age') == 1",
|
||||
"components": {···}
|
||||
},
|
||||
{
|
||||
"condition": "query.block_property('farm:age') == 2", //此阶段农作物成熟
|
||||
"components": {···}
|
||||
},
|
||||
{
|
||||
"condition": "query.block_property('farm:age') == 3", //收获一次后,进入到新的阶段,而这个阶段的模型和贴图都采用发芽阶段并且继续添加随机刻触发器使其可继续生长
|
||||
"components": {
|
||||
"minecraft:geometry": "geometry.corn_stage_0",
|
||||
"minecraft:block_light_absorption": 0,
|
||||
"minecraft:pick_collision": {
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 12, 16]
|
||||
},
|
||||
"minecraft:random_ticking": {
|
||||
"on_tick": {
|
||||
"target": "self",
|
||||
"event": "farm:on_age_count_3"
|
||||
}
|
||||
},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "farm:corn_stage_1",
|
||||
"render_method": "alpha_test",
|
||||
"ambient_occlusion": false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "query.block_property('farm:age') == 4", //第二次成熟阶段,添加掉落表,玩家可以打掉农作物以第二次收获
|
||||
"components": {
|
||||
"minecraft:loot": "loot_tables/corn.json", //添加掉落物表
|
||||
"minecraft:geometry": "geometry.corn_stage_2",
|
||||
"minecraft:block_light_absorption": 0,
|
||||
"minecraft:pick_collision": {
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 12, 16]
|
||||
},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "farm:corn_stage_2",
|
||||
"render_method": "alpha_test",
|
||||
"ambient_occlusion": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"components": {
|
||||
"minecraft:placement_filter": {
|
||||
"conditions": [
|
||||
{
|
||||
"allowed_faces": ["up"],
|
||||
"block_filter": ["farmland"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"minecraft:entity_collision": false,
|
||||
"minecraft:on_player_placing": {
|
||||
"event": "farm:on_player_placing",
|
||||
"target": "self"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"farm:on_whiteradish_grow_to_3":{
|
||||
"set_block_property": {
|
||||
"farm:age": 3,
|
||||
"farm:growth": 0
|
||||
}
|
||||
},
|
||||
"farm:on_age_count_0": {
|
||||
"sequence": [
|
||||
{
|
||||
"condition": "query.block_property('farm:growth') < 7",
|
||||
"set_block_property": {
|
||||
"farm:growth": "query.block_property('farm:growth') + 1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "query.block_property('farm:growth') == 7",
|
||||
"trigger": {
|
||||
"event": "farm:on_whiteradish_grow_to_1",
|
||||
"target": "self"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"farm:on_age_count_1": {
|
||||
"sequence": [
|
||||
{
|
||||
"condition": "query.block_property('farm:growth') < 11",
|
||||
"set_block_property": {
|
||||
"farm:growth": "query.block_property('farm:growth') + 1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "query.block_property('farm:growth') == 11",
|
||||
"trigger": {
|
||||
"event": "farm:on_whiteradish_grow_to_2",
|
||||
"target": "self"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"farm:on_age_count_3": { //第二个发芽阶段的随机刻事件
|
||||
"sequence": [
|
||||
{
|
||||
"condition": "query.block_property('farm:growth') < 11",
|
||||
"set_block_property": {
|
||||
"farm:growth": "query.block_property('farm:growth') + 1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "query.block_property('farm:growth') == 11",
|
||||
"trigger": {
|
||||
"event": "farm:on_whiteradish_grow_to_4", //符合条件触发的事件
|
||||
"target": "self"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"farm:on_player_placing": {
|
||||
"set_block_property": {
|
||||
"farm:age": 0,
|
||||
"farm:growth": 0
|
||||
}
|
||||
},
|
||||
"farm:on_whiteradish_grow_to_1": {
|
||||
"set_block_property": {
|
||||
"farm:age": 1,
|
||||
"farm:growth": 0
|
||||
}
|
||||
},
|
||||
"farm:on_whiteradish_grow_to_2": {
|
||||
"set_block_property": {
|
||||
"farm:age": 2,
|
||||
"farm:growth": 0
|
||||
}
|
||||
},
|
||||
"farm:on_whiteradish_grow_to_4": {
|
||||
"set_block_property": {
|
||||
"farm:age": 4,
|
||||
"farm:growth": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
现在的已经有了两次成熟的阶段,在第一次成熟的时候不能选择直接打掉农作物,所以需要玩家点击农作物进行第一次收获,仍然需要使用MODSDK监听**ServerBlockUseEvent**事件,当玩家点击第一次成熟的农作物时生成掉落物并将农作物替换到下一生长阶段:
|
||||
|
||||
```python
|
||||
class Main(ServerSystem):
|
||||
def __init__(self, namespace, system_name):
|
||||
ServerSystem.__init__(self, namespace, system_name)
|
||||
self.ListenForEvent(namespace, system_name,
|
||||
'ServerBlockUseEvent', self, self.using_item)
|
||||
def using_item(self, event):
|
||||
# 获取玩家ID
|
||||
player_id = event['playerId']
|
||||
# 创建玩家的物品接口
|
||||
item_comp = serverApi.GetEngineCompFactory().CreateItem(player_id)
|
||||
# 获取玩家手持物品信息
|
||||
carried_item = item_comp.GetPlayerItem(ItemPosType.CARRIED, 0, True)
|
||||
# 获取事件里交互的方块类型
|
||||
block_name = event['blockName']
|
||||
#获取交互方块的坐标
|
||||
x = event['x']
|
||||
y = event['y']
|
||||
z = event['z']
|
||||
#获取交互方块的附加值
|
||||
block_aux = event['aux']
|
||||
#玉米物品掉落物的信息字典
|
||||
corn_item = {
|
||||
'newItemName': 'farm:corn_item',
|
||||
'count': 1,
|
||||
'newAuxValue': 0,
|
||||
}
|
||||
#香蕉物品掉落物的信息字典
|
||||
banana_item = {
|
||||
'newItemName': 'farm:banana_item',
|
||||
'count': 1,
|
||||
'newAuxValue': 0,
|
||||
}
|
||||
#如果农作物方块的名称为farm:corn(玉米)并且方块的附加值为2(对应farm:age为2的第一次成熟阶段)
|
||||
if block_name == "farm:corn" and block_aux == 2:
|
||||
#获取并修改对应坐标方块的farm:age
|
||||
blockstatecomp = serverApi.GetEngineCompFactory().CreateBlockState(serverApi.GetLevelId())
|
||||
state = blockstatecomp.GetBlockStates((x,y,z), 0)
|
||||
state['farm:age'] = 3
|
||||
blockstatecomp.SetBlockStates((x,y,z), state, 0)
|
||||
#在交互方块的坐标位置生成掉落物
|
||||
drop_comp = serverApi.GetEngineCompFactory().CreateItem(serverApi.GetLevelId())
|
||||
drop_comp.SpawnItemToLevel(corn_item, 0, (x, y, z))
|
||||
|
||||
#如果农作物方块的名称为farm:banana(香蕉)并且方块的附加值为2(对应farm:age为2的第一次成熟阶段)
|
||||
elif block_name == "farm:banana" and block_aux == 2:
|
||||
#下方逻辑与上方玉米一致
|
||||
blockstatecomp = serverApi.GetEngineCompFactory().CreateBlockState(serverApi.GetLevelId())
|
||||
state = blockstatecomp.GetBlockStates((x,y,z), 0)
|
||||
state['farm:age'] = 3
|
||||
blockstatecomp.SetBlockStates((x,y,z), state, 0)
|
||||
|
||||
drop_comp = serverApi.GetEngineCompFactory().CreateItem(serverApi.GetLevelId())
|
||||
drop_comp.SpawnItemToLevel(banana_item, 0, (x, y, z))
|
||||
|
||||
```
|
||||
|
||||
<img src="./images/22.gif" alt="22" style="zoom:115%;" />
|
||||
|
||||
## 农作物可以被骨粉催熟
|
||||
|
||||
使用骨粉催熟农作物的功能与上面种植豌豆在篱笆上是差不多的,代码如下:
|
||||
|
||||
```python
|
||||
class Main(ServerSystem):
|
||||
|
||||
def __init__(self, namespace, system_name):
|
||||
ServerSystem.__init__(self, namespace, system_name)
|
||||
#时间戳参数
|
||||
self.interact_cooldown = {}
|
||||
#监听玩家使用物品与方块交互
|
||||
self.ListenForEvent(namespace, system_name,'ItemUseOnAfterServerEvent', self, self.using_block)
|
||||
|
||||
def using_block(self, event):
|
||||
#普通农作物列表
|
||||
normal_plant_list = ['farm:bambooshoot', 'farm:crown_dasiy', 'farm:eggplant', 'farm:lemon', 'farm:spinach',
|
||||
'farm:whiteradish']
|
||||
#需收获两次的农作物列表
|
||||
double_plant_list = ['farm:banana','farm:corn']
|
||||
#事件获取的方块名称
|
||||
blockname = event['blockName']
|
||||
#事件获取的方块附加值
|
||||
blockaux = event['blockAuxValue']
|
||||
#事件获取的手持物品信息字典
|
||||
itemname = event['itemDict']
|
||||
|
||||
#如果交互的方块名称在普通农作物列表中并且玩家手持的物品是骨粉,且方块的附加值小于2(小于2是为了避开已经成熟的农作物)
|
||||
if blockname in normal_plant_list and itemname['newItemName'] == 'minecraft:bone_meal' and blockaux < 2:
|
||||
#执行函数
|
||||
self.use_bone_meal(event)
|
||||
|
||||
#如果交互的方块名称在需收获两次的农作物列表中并且玩家手持的物品是骨粉,且方块的附加值小于4(收获两次的农作物的farm:age比普通农作物多)
|
||||
elif blockname in double_plant_list and itemname['newItemName'] == 'minecraft:bone_meal' and blockaux < 4:
|
||||
#执行函数
|
||||
self.use_bone_meal(event)
|
||||
|
||||
#如果交互的方块是豌豆并且玩家手持的物品是骨粉,且方块的附加值等于1或2
|
||||
elif blockname == "farm:peas" and itemname['newItemName'] == 'minecraft:bone_meal' and (blockaux == 1 or blockaux == 2):
|
||||
#执行函数
|
||||
self.use_bone_meal(event)
|
||||
else:
|
||||
pass
|
||||
|
||||
def use_bone_meal(self, event):
|
||||
playerid = event['entityId']
|
||||
x = event['x']
|
||||
y = event['y']
|
||||
z = event['z']
|
||||
item_comp = serverApi.GetEngineCompFactory().CreateItem(playerid)
|
||||
blockstatecomp = serverApi.GetEngineCompFactory().CreateBlockState(serverApi.GetLevelId())
|
||||
|
||||
#利用时间戳避免瞬间使用多次骨粉的情况
|
||||
#如果玩家id不在这个变量中(说明第一次使用骨粉)
|
||||
if playerid not in self.interact_cooldown:
|
||||
#给这个变量添加一个参数,键是玩家id,值是当前的时间戳
|
||||
self.interact_cooldown[playerid] = time.time()
|
||||
#获取手持物品的字典信息
|
||||
carried_item = item_comp.GetPlayerItem(ItemPosType.CARRIED, 0, True)
|
||||
#给获取到的物品数量减1
|
||||
carried_item['count'] -= 1
|
||||
#将修改数量后的物品信息设置到玩家手中
|
||||
item_comp.SetPlayerAllItems({(ItemPosType.CARRIED, 0): carried_item})
|
||||
#获取交互的方块信息
|
||||
state = blockstatecomp.GetBlockStates((x, y, z), 0)
|
||||
#给获取到的方块的farm:age加1(增加成长阶段)
|
||||
state['farm:age'] += 1
|
||||
#在坐标设置增加成长阶段后的方块
|
||||
blockstatecomp.SetBlockStates((x, y, z), state, 0)
|
||||
else:
|
||||
#如果这个变量有内容,并且当前时间戳减去变量中的时间戳大于0.5则执行下方逻辑(说明并不是第一次使用骨粉)
|
||||
if time.time() - self.interact_cooldown[playerid] > 0.5:
|
||||
#执行下方逻辑,与上方第一次使用骨粉的逻辑一样
|
||||
carried_item = item_comp.GetPlayerItem(ItemPosType.CARRIED, 0, True)
|
||||
carried_item['count'] -= 1
|
||||
item_comp.SetPlayerAllItems({(ItemPosType.CARRIED, 0): carried_item})
|
||||
state = blockstatecomp.GetBlockStates((x, y, z), 0)
|
||||
state['farm:age'] += 1
|
||||
blockstatecomp.SetBlockStates((x, y, z), state, 0)
|
||||
self.interact_cooldown[playerid] = time.time()
|
||||
pass
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1200
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/课程04.添加家具方块.md
Normal file
143
docs/mconline/20-玩法地图教程/第07章:使用实验玩法增加自定义内容/课程05.添加装扮装备.md
Normal file
@@ -0,0 +1,143 @@
|
||||
---
|
||||
front: https://nie.res.netease.com/r/pic/20210730/ee109f39-8987-46e0-9fe7-40ebb23060fa.png
|
||||
hard: 进阶
|
||||
time: 25分钟
|
||||
---
|
||||
|
||||
# 通过attchables和自定义物品添加新的装扮
|
||||
|
||||
接下来为地图添加多种多样的装饰装备,让玩家可以购买并自由搭配;装备共分为四个部位:头、身、腿、脚;中国版的自定义物品和微软1.16+的自定义物品都可以制作,本节会把两种方法都进行演示。
|
||||
|
||||

|
||||
|
||||
## 使用中国版自定义物品制作
|
||||
|
||||
在行为包下的**netease_items_beh**中新建一个json文件,为自定义物品添加行为组件:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.10",
|
||||
"minecraft:item": {
|
||||
"description": {
|
||||
"identifier": "farm:denim",
|
||||
"register_to_create_menu":true,
|
||||
"custom_item_type": "armor" //自定义物品类型:盔甲
|
||||
},
|
||||
"components": {
|
||||
"netease:armor":{ //定义物品为盔甲
|
||||
"defense": 1, //防御值
|
||||
"enchantment":1, //附魔能力
|
||||
"armor_slot":2 //盔甲槽位(0-头盔,1-胸甲,2-护腿,3-鞋子)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
在资源包下的**netease_items_res**中同样新建一个json文件,定义这个自定义物品的图标:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.10",
|
||||
"minecraft:item": {
|
||||
"description": {
|
||||
"identifier": "farm:denim",
|
||||
"category": "Equipment" //在创造栏中的类别:装备
|
||||
},
|
||||
"components": {
|
||||
"minecraft:icon": "farm:denim" //自定义物品的图标,对应item_texture文件
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
创建一个自定义物品后,继续在资源包的**attachables**文件中创建json文件,定义自定义装备的模型、贴图等:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.8.0",
|
||||
"minecraft:attachable": {
|
||||
"description": {
|
||||
"identifier": "farm:denim",
|
||||
"materials": {
|
||||
"default": "armor",
|
||||
"enchanted": "armor_enchanted"
|
||||
},
|
||||
"textures": { //贴图
|
||||
"default": "textures/models/denim", //正常状态时
|
||||
"enchanted": "textures/misc/enchanted_item_glint" //含有附魔时
|
||||
},
|
||||
"geometry": {
|
||||
"default": "geometry.denim" //模型
|
||||
},
|
||||
"scripts": {
|
||||
"parent_setup": "variable.leg_layer_visible = 0.0;" //定义装备的部位
|
||||
//variable.helmet_layer_visible 头盔
|
||||
//variable.chest_layer_visible 胸甲
|
||||
//variable.leg_layer_visible 护腿
|
||||
//variable.boot_layer_visible 靴子
|
||||
},
|
||||
"render_controllers": [ "controller.render.armor" ] //渲染控制器
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 使用微软自定义物品制作
|
||||
|
||||
**attachables**内的json文件无需做任何修改,和中国版是一样的;微软自定义物品的json文件放在**items**里:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.16.100",
|
||||
"minecraft:item": {
|
||||
"description": {
|
||||
"identifier": "farm:denim_new",
|
||||
"category": "equipment"
|
||||
},
|
||||
"components": {
|
||||
"minecraft:creative_category": { //在创造栏中的类别:装备
|
||||
"parent": "itemGroup.name.equipment"
|
||||
},
|
||||
"minecraft:icon": { //自定义物品的图标,同样对应item_texture文件
|
||||
"texture": "farm:denim"
|
||||
},
|
||||
"minecraft:enchantable": { //附魔等级
|
||||
"value": 1, //值
|
||||
"slot": "armor_legs" //附魔装备类型(护腿)
|
||||
},
|
||||
"minecraft:armor": {
|
||||
"protection": 1 //防御值
|
||||
},
|
||||
"minecraft:wearable": { //定义物品可穿戴
|
||||
"slot": "slot.armor.legs" //装备在腿部的格子上
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
微软自定义物品的创造栏类别和自定义物品图标都放在行为包的文件内,无需在资源包另外添加;
|
||||
|
||||
## 装扮装备的模型
|
||||
|
||||
装备的模型有一些部分需要特别注意,因为玩家在走动、转视角的时候,各个部位都有不同的动作,身上的装备也需要跟着部位动,所以装备模型的骨骼要设定好,以**blockbench**为例:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
装备模型和原版史蒂夫模型的很多组名(Group)都一样,这个牛仔裤模型的块都在leftLeg和rightLeg下,分别对应左腿和右腿,这里的组名就是和史蒂夫绑定的骨骼;
|
||||
|
||||
如果我们把rightleg的组名随意修改会发生什么?
|
||||
|
||||

|
||||
|
||||
左腿的装备是跟随玩家的腿移动的,不过右腿的装备就固定在原地,所以骨骼的绑定是非常重要的,建议装备的模型都严格的命名,更直观、高效。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||