附加包教程:33.方块(五)
本帖最后由 Cat_Anchor 于 2023-3-31 22:11 编辑坩埚https://pic.imgdb.cn/item/64032302f144a01007ae1112.png
稀有度常见
创造分类建筑
材料金属
合适挖掘工具镐
硬度5
爆炸抗性0
亮度0
窒息生物否
红石导体否
光照透明0.7
可被火破坏否
可被熔岩生成火否
可再生是
最大堆叠64
命名空间IDcrucible
前言
所有我知道的关于附加包理论的知识几乎已经讲完了,但还有一些遗漏。不管怎样,我们从这一期开始进入教程后期。这一期的题目叫“方块(五)”,因为我要在这一期放出一些制作方块的例子。
https://klpbbs.com/static/image/hrline/line5.png
目标
今天我闲来无事,想要给我的附加包加一点新东西。思来想去,我觉得添加一口锅还有点意思。我要添加一口能盛水、熔岩、牛奶的锅,每个液体都应该可以有不同高度,而且肯定得反复使用,不能只用一次就歇菜。
除此之外,我添加这个锅和原版的炼药锅的区别是,这个锅可以做饭和混合黑曜石。相当于不用钻石镐就获得黑曜石的一种途径。
最后,我打算叫它“坩埚”。
https://klpbbs.com/static/image/hrline/line7.png
分析与解决
好的,那么既然是坩埚,第一件事就是给它确定一个命名空间ID。我把坩埚丢进了翻译器里,结果是“crucible”。校对了一下意思,发现没有很大的歧义,于是在本例子中,我就把它的ID定为“supplementary:crucible”吧!
于是我在行为包根目录/blocks/下创建crucible.json。打开它,首先把基本的方块格式写出来。
然后我注意到需要定义两个方块属性,一个用来管液体的类型,一个用来管液体的高度。然后要给两个属性确定类型。液体高度我设置了7层,0层代表没有,6层代表满,而第7层是预留给以后使用的。至于另一个液体类型,当然是设置成字符串,这让代码易懂了很多。虽然也可以设置成数字,然后记住0代表什么1代表什么;但这样写出的代码,时间一久,自己都忘了这些代码到底怎么运作的,更不要提优化或者是修复漏洞了。
至于题目说的“做饭功能”,我暂且用做甜菜根汤代替,因为这个最简单。当然也可以做蘑菇煲和兔肉汤,但那些涉及到添加原料时的一个hasitem选择器问题,这就容易闹出版本问题和一堆历史遗留问题。总之,液体类型就设置成none、water、lava、milk和beetroot吧。
然后需要一个坩埚模型,随便做一个就好了。记得在做液体层数时给对应的立方体命名“layerX”,X代表到底是哪一层。以上用于part_visibility组件,实际上就是用于显示液体高度。我放一个我做的模型示例吧。
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.crucible",
"texture_width": 112,
"texture_height": 112,
"visible_bounds_width": 2,
"visible_bounds_height": 2.5,
"visible_bounds_offset":
},
"bones": [
{
"name": "root",
"pivot": ,
"cubes": [
{"origin": [-8, 1, -8], "size": , "uv": },
{"origin": [-8, 0, -8], "size": , "uv": },
{"origin": [-8, 2, 6], "size": , "uv": },
{"origin": , "size": , "uv": },
{"origin": [-8, 0, 3], "size": , "uv": },
{"origin": , "size": , "uv": },
{"origin": [-8, 2, -8], "size": , "uv": },
{"origin": [-8, 2, -6], "size": , "uv": },
{"origin": , "size": , "uv": }
]
},
{
"name": "layer1",
"pivot": ,
"cubes": [
{"origin": [-6, 2, -6], "size": , "uv": }
]
}, //第1层,叫layer1,以下同理
{
"name": "layer6",
"pivot": ,
"cubes": [
{"origin": [-6, 14.85, -6], "size": , "uv": }
]
}, //不要在意这个顺序
{
"name": "layer3",
"pivot": ,
"cubes": [
{"origin": [-6, 7.14, -6], "size": , "uv": }
]
},
{
"name": "layer5",
"pivot": ,
"cubes": [
{"origin": [-6, 12.28, -6], "size": , "uv": }
]
},
{
"name": "layer4",
"pivot": ,
"cubes": [
{"origin": [-6, 9.71, -6], "size": , "uv": }
]
},
{
"name": "layer2",
"pivot": ,
"cubes": [
{"origin": [-6, 4.57, -6], "size": , "uv": }
]
},
{
"name": "layer7",
"pivot": ,
"cubes": [
{"origin": [-6, 17.42, -6], "size": , "uv": }
]
}
]
}
]
}
方块代码如下。
{
"format_version": "1.18.0",
"minecraft:block": {
"description": {
"identifier": "supplementary:crucible", //方块的命名空间ID,简称方块ID。
"properties": {
"supplementary:material_type": [ //液体类型
"none", //没有液体
"water", //水
"lava", //熔岩
"milk", //牛奶
"beetroot" //甜菜根汤
],
"supplementary:height": [ //液体高度
0,
1,
2,
3,
4,
5,
6,
7
]
}
},
"components": {
"tag:metal": {}, //暂时认为锅是金属的,添加一个金属标签
"minecraft:on_interact": {
"event": "fill_material" //交互时触发事件,事件名是fill_material,下文会讲
},
"minecraft:geometry": "geometry.crucible", //一口锅总得有个模型吧
"minecraft:material_instances": {
"*": {
"texture": "crucible_empty", //有了模型,就可以用minecraft:material_instances组件直接定义纹理短名了。
"render_method": "blend" //允许半透明,同时有防止它上面刷怪等效果
}
},
"minecraft:destroy_time": 5, //设定破坏时间
"minecraft:block_light_filter": 0.7,
"minecraft:part_visibility": { //这个组件用于在对应的层数显示对应的高度。在1.19.80及以后,它被合并到了minecraft:geometry的bone_visibility中。
"rules": {
"layer0": "q.block_property('supplementary:height')==0",
"layer1": "q.block_property('supplementary:height')==1",
"layer2": "q.block_property('supplementary:height')==2",
"layer3": "q.block_property('supplementary:height')==3",
"layer4": "q.block_property('supplementary:height')==4",
"layer5": "q.block_property('supplementary:height')==5",
"layer6": "q.block_property('supplementary:height')==6",
"layer7": "q.block_property('supplementary:height')==7"
}
}
}, ...
}
}
然后,要让我们拿着水桶时点击坩埚,坩埚里得出现液体才行。所以在组件那里有minecraft:on_interact触发器组件,触发fill_material事件。这个事件会运用sequence来确定顺序,还有condition判定到底玩家手持的是什么。这个事件的代码如下。
... "fill_material": {
"sequence": [
{
"condition": "q.get_equipped_item_name=='water_bucket'", //如果玩家手里拿着水桶,那么...
"set_block_property": { //设置方块属性。没错,可以像下面这样一次设置两个。
"supplementary:material_type": "'water'", //液体类型设置为水。
"supplementary:height": 6 //高度设置为满(6层高)
},
"run_command": { //运行命令
"command": [
"clear @p water_bucket 0 1",
"give @p bucket"
] //清除水桶,给予空桶。记得限定只清除一个水桶。
}
},
{ //这部分用于熔岩
"condition": "q.get_equipped_item_name=='lava_bucket'",
"set_block_property": {
"supplementary:material_type": "'lava'",
"supplementary:height": 6
},
"run_command": {
"command": [
"clear @p lava_bucket 0 1",
"give @p bucket"
]
}
},
{ //这部分用于牛奶
"condition": "q.get_equipped_item_name=='milk_bucket'",
"set_block_property": {
"supplementary:material_type": "'milk'",
"supplementary:height": 6
},
"run_command": {
"command": [
"clear @p milk_bucket 0 1",
"give @p bucket"
]
}
}
]
} ...
注:如果要用set_block_property设置一个字符串类型的方块属性,必须把要设置的值用''括起来才可以设置。例如"supplementary:material_type":"'water'"。
再注:我也不知道为啥要括起来,当时我不知道,没有括,结果报错了,于是就搁置了这个项目。后来看到一个附加包里用''括起来了,我也试了一下,居然成功了。
再再注:set_block_property可以一次设置两个属性,也是我突发奇想写的,没想到居然成功了。
到现在为止,一切都还好办。然后要定义方块排列(Permutations)。我也不知道为啥Permutations叫排列,可能是用翻译器翻译的吧。感觉好怪啊。
...
"permutations": [
{
"condition": "q.block_property('supplementary:material_type')=='water'", //如果液体材料是水,那么用以下组件替换原来的组件。
"components": {
"minecraft:material_instances": {
"*": {
"texture": "crucible_water",
"render_method": "blend"
}
}, //定义一个水的纹理。
"minecraft:on_interact": {
"event": "empty_water"
} //玩家点击时触发事件empty_water。详情见下文。
}
},
{ //这个管熔岩
"condition": "q.block_property('supplementary:material_type')=='lava'",
"components": {
"minecraft:material_instances": {
"*": {
"texture": "crucible_lava",
"render_method": "blend"
}
},
"minecraft:on_interact": {
"event": "empty_lava"
}
}
},
{ //牛奶
"condition": "q.block_property('supplementary:material_type')=='milk'",
"components": {
"minecraft:material_instances": {
"*": {
"texture": "crucible_milk",
"render_method": "blend"
}
},
"minecraft:on_interact": {
"event": "empty_milk"
}
}
},
{ //甜菜根汤
"condition": "q.block_property('supplementary:material_type')=='beetroot'",
"components": {
"minecraft:material_instances": {
"*": {
"texture": "crucible_beetroot",
"render_method": "blend"
}
},
"minecraft:on_interact": {
"event": "empty_beetroot"
}
}
}
]
...
我们已经完成了一大半,接下来就是定义如何清除坩埚里的液体了。刚才有empty_water等事件,以下是empty_water的代码。注:千万不要在清除液体时仅仅把液体高度设置为0,那样,这个坩埚还保持着水的液体类型,那这锅看起来是空了,实际上真就歇菜了,不能倒熔岩等其他液体了。这是因为锅还保持着水的液体类型,这个排列下,点击方块会触发empty_water事件而不是fill_material事件。
清除熔岩和牛奶比较简单,只需要把高度设为0,类型设为none,然后用命令把桶换成熔岩桶或牛奶桶就好了。但清除水时,有很多操作:加甜菜根可以变成甜菜汤,加熔岩可以变成黑曜石,用水瓶可以舀3瓶,用桶可以直接舀一锅。下面我放了我写的empty_water事件的示例。太长了,我折叠一下。
"empty_water": {
"sequence": [
{
"condition": "q.get_equipped_item_name=='beetroot'&&q.block_property('supplementary:height')==6", //如果锅里的水满了,而且玩家手持甜菜,那么...
"set_block_property": { //把类型换成甜菜汤
"supplementary:material_type": "'beetroot'",
"supplementary:height": 6
},
"run_command": {
"command": "clear @p beetroot 0 3" //清除3个甜菜根
}
}, //以上用于“加入甜菜根变成甜菜汤”功能
{
"condition": "q.get_equipped_item_name=='bucket'&&q.block_property('supplementary:height')==6",
"set_block_property": {
"supplementary:material_type": "'none'",
"supplementary:height": 0
},
"run_command": {
"command": [
"clear @p bucket 0 1",
"give @p water_bucket"
]
}
}, //这个对象用于用桶舀水
{
"condition": "q.get_equipped_item_name=='glass_bottle'&&q.block_property('supplementary:height')>=3",
"set_block_property": {
"supplementary:height": "q.block_property('supplementary:height')-2"
},
"run_command": {
"command": [
"clear @p glass_bottle 0 1",
"give @p potion"
]
}
},
{
"condition": "q.get_equipped_item_name=='glass_bottle'&&q.block_property('supplementary:height')<=2",
"set_block_property": {
"supplementary:material_type": "'none'",
"supplementary:height": 0
},
"run_command": {
"command": [
"clear @p glass_bottle 0 1",
"give @p potion"
]
}
}, //以上两个对象用于用水瓶舀水。因为可以舀3次,所以前两次减少液体层数,最后一次直接把液体类型设置为none,清空液体层数。如果不这么做会导致锅用一次就歇菜。
{
"condition": "q.get_equipped_item_name=='lava_bucket'&&q.block_property('supplementary:height')==6",
"set_block_property": {
"supplementary:material_type": "'none'",
"supplementary:height": 0
},
"run_command": {
"command": [
"clear @p lava_bucket 0 1",
"give @p bucket",
"give @p obsidian"
]
}
} //用于混合黑曜石
]
}
一番操作猛如虎,经过好几次T&E之后,我终于做好了坩埚。以下代码就是我的crucible.json里写的内容,供大家参考。
{
"format_version": "1.18.0",
"minecraft:block": {
"description": {
"identifier": "supplementary:crucible",
"properties": {
"supplementary:material_type": [
"none",
"water",
"lava",
"milk",
"beetroot"
],
"supplementary:height": [
0,
1,
2,
3,
4,
5,
6,
7
]
}
},
"components": {
"tag:metal": {},
"minecraft:on_interact": {
"event": "fill_material"
},
"minecraft:geometry": "geometry.crucible",
"minecraft:material_instances": {
"*": {
"texture": "crucible_empty",
"render_method": "blend"
}
},
"minecraft:destroy_time": 5,
"minecraft:block_light_filter": 0.7,
"minecraft:part_visibility": {
"rules": {
"layer0": "q.block_property('supplementary:height')==0",
"layer1": "q.block_property('supplementary:height')==1",
"layer2": "q.block_property('supplementary:height')==2",
"layer3": "q.block_property('supplementary:height')==3",
"layer4": "q.block_property('supplementary:height')==4",
"layer5": "q.block_property('supplementary:height')==5",
"layer6": "q.block_property('supplementary:height')==6",
"layer7": "q.block_property('supplementary:height')==7"
}
}
},
"events": {
"empty_water": {
"sequence": [
{
"condition": "q.get_equipped_item_name=='beetroot'&&q.block_property('supplementary:height')==6",
"set_block_property": {
"supplementary:material_type": "'beetroot'",
"supplementary:height": 6
},
"run_command": {
"command": "clear @p beetroot 0 3"
}
},
{
"condition": "q.get_equipped_item_name=='bucket'&&q.block_property('supplementary:height')==6",
"set_block_property": {
"supplementary:material_type": "'none'",
"supplementary:height": 0
},
"run_command": {
"command": [
"clear @p bucket 0 1",
"give @p water_bucket"
]
}
},
{
"condition": "q.get_equipped_item_name=='glass_bottle'&&q.block_property('supplementary:height')>=3",
"set_block_property": {
"supplementary:height": "q.block_property('supplementary:height')-2"
},
"run_command": {
"command": [
"clear @p glass_bottle 0 1",
"give @p potion"
]
}
},
{
"condition": "q.get_equipped_item_name=='glass_bottle'&&q.block_property('supplementary:height')<=2",
"set_block_property": {
"supplementary:material_type": "'none'",
"supplementary:height": 0
},
"run_command": {
"command": [
"clear @p glass_bottle 0 1",
"give @p potion"
]
}
},
{
"condition": "q.get_equipped_item_name=='lava_bucket'&&q.block_property('supplementary:height')==6",
"set_block_property": {
"supplementary:material_type": "'none'",
"supplementary:height": 0
},
"run_command": {
"command": [
"clear @p lava_bucket 0 1",
"give @p bucket",
"give @p obsidian"
]
}
}
]
},
"empty_lava": {
"sequence": [
{
"condition": "q.get_equipped_item_name=='bucket'&&q.block_property('supplementary:height')==6",
"set_block_property": {
"supplementary:material_type": "'none'",
"supplementary:height": 0
},
"run_command": {
"command": [
"clear @p bucket 0 1",
"give @p lava_bucket"
]
}
},
{
"condition": "q.get_equipped_item_name=='water_bucket'&&q.block_property('supplementary:height')==6",
"set_block_property": {
"supplementary:material_type": "'none'",
"supplementary:height": 0
},
"run_command": {
"command": [
"clear @p water_bucket 0 1",
"give @p bucket",
"give @p obsidian"
]
}
}
]
},
"empty_milk": {
"sequence": [
{
"condition": "q.get_equipped_item_name=='bucket'&&q.block_property('supplementary:height')>5",
"set_block_property": {
"supplementary:material_type": "'none'",
"supplementary:height": 0
},
"run_command": {
"command": [
"clear @p bucket 0 1",
"give @p milk_bucket"
]
}
}
]
},
"empty_beetroot": {
"sequence": [
{
"condition": "q.get_equipped_item_name=='bowl'&&q.block_property('supplementary:height')>=3",
"set_block_property": {
"supplementary:height": "q.block_property('supplementary:height')-2"
},
"run_command": {
"command": [
"clear @p bowl 0 1",
"give @p beetroot_soup"
]
}
},
{
"condition": "q.get_equipped_item_name=='bowl'&&q.block_property('supplementary:height')<=2",
"set_block_property": {
"supplementary:material_type": "'none'",
"supplementary:height": 0
},
"run_command": {
"command": [
"clear @p bowl 0 1",
"give @p beetroot_soup"
]
}
}
]
},
"fill_material": {
"sequence": [
{
"condition": "q.get_equipped_item_name=='water_bucket'",
"set_block_property": {
"supplementary:material_type": "'water'",
"supplementary:height": 6
},
"run_command": {
"command": [
"clear @p water_bucket 0 1",
"give @p bucket"
]
}
},
{
"condition": "q.get_equipped_item_name=='lava_bucket'",
"set_block_property": {
"supplementary:material_type": "'lava'",
"supplementary:height": 6
},
"run_command": {
"command": [
"clear @p lava_bucket 0 1",
"give @p bucket"
]
}
},
{
"condition": "q.get_equipped_item_name=='milk_bucket'",
"set_block_property": {
"supplementary:material_type": "'milk'",
"supplementary:height": 6
},
"run_command": {
"command": [
"clear @p milk_bucket 0 1",
"give @p bucket"
]
}
}
]
}
},
"permutations": [
{
"condition": "q.block_property('supplementary:material_type')=='water'",
"components": {
"minecraft:material_instances": {
"*": {
"texture": "crucible_water",
"render_method": "blend"
}
},
"minecraft:on_interact": {
"event": "empty_water"
}
}
},
{
"condition": "q.block_property('supplementary:material_type')=='lava'",
"components": {
"minecraft:material_instances": {
"*": {
"texture": "crucible_lava",
"render_method": "blend"
}
},
"minecraft:on_interact": {
"event": "empty_lava"
}
}
},
{
"condition": "q.block_property('supplementary:material_type')=='milk'",
"components": {
"minecraft:material_instances": {
"*": {
"texture": "crucible_milk",
"render_method": "blend"
}
},
"minecraft:on_interact": {
"event": "empty_milk"
}
}
},
{
"condition": "q.block_property('supplementary:material_type')=='beetroot'",
"components": {
"minecraft:material_instances": {
"*": {
"texture": "crucible_beetroot",
"render_method": "blend"
}
},
"minecraft:on_interact": {
"event": "empty_beetroot"
}
}
}
]
}
}
模型文件在教程开头已经给出了,我会把我制作的方块纹理打包放在下方,有需要的可以参考。
https://klpbbs.com/static/image/hrline/line3.png
总结
这一期,我们制作了一个坩埚方块,可以盛装液体,也可以制作黑曜石和甜菜根汤。下期我们继续示范方块制作。
同时,这也是到目前为止我写的最长的一篇教程,大小达到了25KB,这个大小可能还会被超越。
第三十二期 第三十三期 第三十四期 Cat_Anchor 发表于 2023-3-26 10:38
就是坩埚在游戏内的样子(去除了背景)
现在1.21.5版本好像用不了了,请问可以更新一下教程吗? Cat_Anchor 发表于 2023-3-26 10:38
就是坩埚在游戏内的样子(去除了背景)
可以发一下完整的addon包吗?自己做的addon中方块和实体无法显示和调出 嗷呜不生电 发表于 2023-3-26 07:34
一开始那个图片是啥
就是坩埚在游戏内的样子(去除了背景) 苦力怕论坛感谢有你! 一开始那个图片是啥
页: [1]