Cat_Anchor 发表于 2023-12-10 12:27:32

附加包教程:42.方块(八)

本帖最后由 Cat_Anchor 于 2024-1-13 12:57 编辑


巧克力活板门https://pic.imgdb.cn/item/65753dd9c458853aef98c8b8.gif
稀有度常见
创造分类建筑
材料固体
合适挖掘工具镐
硬度0.5
爆炸抗性1.2
亮度0
窒息生物否
红石导体否
光照透明1
可被火破坏否
可被熔岩生成火否
可再生是
最大堆叠64
命名空间IDchocolate_trapdoor





前言



最近我的糖果大陆附加包涉及到活板门和门的实现,所以这期和下期我们来放出它们的教程。



https://klpbbs.com/static/image/hrline/line5.png


目标



制作一个尽可能与原版一样的活板门,包括可以打开/关闭,可以放置在方块的上面/下面等。



https://klpbbs.com/static/image/hrline/line7.png


分析与解决



今天的任务比之前的液体方块简单得多。首先,既然是活板门,那么它肯定有4个方向;还需要指定放置在方块的上方还是下方;最后,还需要指定它是否打开了。这就是三个方块状态。
活板门的上下取决于它放置在方块的上半部分还是下半部分,所以可以用方块特征里的minecraft:placement_position实现。4个方向是根据我们放置时的朝向决定的,所以使用minecraft:placement_direction实现。至于开关与否,就单独定义一个方块状态。
{
"format_version": "1.20.30", //使用较新的格式版本才可以使用方块特征
"minecraft:block": { //定义一个方块
    "description": {
      "identifier": "supplementary:chocolate_trapdoor", //方块ID
      "menu_category": { //指定方块要放在创造模式物品栏的哪里
      "category": "construction", //指定放在建材分类下
      "group": "itemGroup.name.trapdoor" //指定放在活板门一组里
      },
      "traits": { //定义方块特征
      "minecraft:placement_position": {
          "enabled_states": [
            "minecraft:vertical_half" //启用minecraft:placement_position中的minecraft:vertical_half状态,检测放置在方块的上半部分还是下半部分
          ]
      },
      "minecraft:placement_direction": {
          "enabled_states": [
            "minecraft:cardinal_direction" //启用minecraft:placement_direction中的minecraft:cardinal_direction状态,检测放置的4个方向,忽略向上和向下
          ]
      }
      },
      "states": { //定义方块状态
      "supplementary:open_bit": [ //定义一个叫supplementary:open_bit的状态,接受布尔值,默认值为false
          false,
          true
      ]
      }
    }, ...
}
}
然后定义一些基本的方块组件,例如爆炸抗性、光照等。
... "components": {
      "tag:stone": {}, //让自定义镐子识别用的标签,所以这个方块用镐子挖掘更快
      "minecraft:destructible_by_mining": { //定义可挖掘性
      "seconds_to_destroy": 0.5 //需要0.5秒钟破坏
      },
      "minecraft:destructible_by_explosion": { //定义可被爆炸摧毁性
      "explosion_resistance": 1.2 //爆炸抗性为1.2
      },
      "minecraft:collision_box": { //定义实体碰撞箱,这里是活板门的碰撞箱
      "origin": [
          -8,
          0,
          -8
      ],
      "size": [
          16,
          3,
          16
      ]
      },
      "minecraft:selection_box": { //定义挖掘判定箱,这里是活板门的判定箱
      "origin": [
          -8,
          0,
          -8
      ],
      "size": [
          16,
          3,
          16
      ]
      },
      "minecraft:geometry": "geometry.trapdoor", //这个方块要使用活板门的模型
      "minecraft:material_instances": {
      "*": {
          "texture": "chocolate_trapdoor", //由于使用了模型,我们可以直接定义纹理。这里还定义了渲染方法。
          "render_method": "blend" //允许透明/半透明,它上面不能放置红石线且不能刷怪,它也不能被红石充能。
      }
      },
      "minecraft:on_interact": {
      "event": "toggle"
      }, //当我们点击它的时候,活板门会打开或关闭。
      "minecraft:light_dampening": 0 //不阻挡光线
    }, ...
刚才我们定义了一个事件,用来打开/关闭活板门。事件代码如下。
"toggle": {
"sequence": [ //按顺序执行事件
    {
      "set_block_state": {
      "supplementary:open_bit": "!q.block_state('supplementary:open_bit')" //把“是否打开”的方块状态变为原来的相反值(打开变为关上,关上变为打开)
      }
    },
    {
      "condition": "q.block_state('supplementary:open_bit')", //当活板门打开时...
      "run_command": {
      "command": "playsound close.wooden_trapdoor @a ~~~ 0.9 0.9" //播放关闭木活板门的声音
      }
    },
    {
      "condition": "!q.block_state('supplementary:open_bit')", //当活板门关闭时...
      "run_command": {
      "command": "playsound open.wooden_trapdoor @a ~~~ 0.9 0.9" //播放打开木活板门的声音
      }
    }
]
}
接下来定义方块排列。
活板门的开关、上下、方向都可以通过旋转实现。可以按三个轴旋转。比如,把活板门打开就是沿Z轴旋转-90度,上下通过沿X或Z轴旋转180度实现,方向通过沿Y轴旋转90/180/-90度实现,等等。
总共有16(4*2*2)个排列,代码太长,请看下面的完整示例。

那么活板门方块就做好了,下面是我的chocolate_trapdoor.json中的代码。{
"format_version": "1.20.30",
"minecraft:block": {
    "description": {
      "identifier": "supplementary:chocolate_trapdoor",
      "menu_category": {
      "category": "construction",
      "group": "itemGroup.name.trapdoor"
      },
      "traits": {
      "minecraft:placement_position": {
          "enabled_states": [
            "minecraft:vertical_half"
          ]
      },
      "minecraft:placement_direction": {
          "enabled_states": [
            "minecraft:cardinal_direction"
          ]
      }
      },
      "states": {
      "supplementary:open_bit": [
          false,
          true
      ]
      }
    },
    "components": {
      "tag:stone": {},
      "minecraft:destructible_by_mining": {
      "seconds_to_destroy": 0.5
      },
      "minecraft:destructible_by_explosion": {
      "explosion_resistance": 1.2
      },
      "minecraft:collision_box": {
      "origin": [
          -8,
          0,
          -8
      ],
      "size": [
          16,
          3,
          16
      ]
      },
      "minecraft:selection_box": {
      "origin": [
          -8,
          0,
          -8
      ],
      "size": [
          16,
          3,
          16
      ]
      },
      "minecraft:geometry": "geometry.trapdoor",
      "minecraft:material_instances": {
      "*": {
          "texture": "chocolate_trapdoor",
          "render_method": "blend"
      }
      },
      "minecraft:on_interact": {
      "event": "toggle"
      },
      "minecraft:light_dampening": 0
    },
    "events": {
      "toggle": {
      "sequence": [
          {
            "set_block_state": {
            "supplementary:open_bit": "!q.block_state('supplementary:open_bit')"
            }
          },
          {
            "condition": "q.block_state('supplementary:open_bit')",
            "run_command": {
            "command": "playsound close.wooden_trapdoor @a ~~~ 0.9 0.9"
            }
          },
          {
            "condition": "!q.block_state('supplementary:open_bit')",
            "run_command": {
            "command": "playsound open.wooden_trapdoor @a ~~~ 0.9 0.9"
            }
          }
      ]
      }
    },
    "permutations": [
      {
      "condition": "q.block_state('minecraft:vertical_half') == 'top' && q.block_state('minecraft:cardinal_direction') == 'north' && !q.block_state('supplementary:open_bit')",
      "components": {
          "minecraft:transformation": {
            "rotation": [
            0,
            0,
            180
            ]
          }
      }
      },
      {
      "condition": "q.block_state('minecraft:vertical_half') == 'top' && q.block_state('minecraft:cardinal_direction') == 'south' && !q.block_state('supplementary:open_bit')",
      "components": {
          "minecraft:transformation": {
            "rotation": [
            180,
            0,
            0
            ]
          }
      }
      },
      {
      "condition": "q.block_state('minecraft:vertical_half') == 'top' && q.block_state('minecraft:cardinal_direction') == 'east' && !q.block_state('supplementary:open_bit')",
      "components": {
          "minecraft:transformation": {
            "rotation": [
            180,
            -270,
            0
            ]
          }
      }
      },
      {
      "condition": "q.block_state('minecraft:vertical_half') == 'top' && q.block_state('minecraft:cardinal_direction') == 'west' && !q.block_state('supplementary:open_bit')",
      "components": {
          "minecraft:transformation": {
            "rotation": [
            180,
            270,
            0
            ]
          }
      }
      },
      {
      "condition": "q.block_state('minecraft:vertical_half') == 'top' && q.block_state('minecraft:cardinal_direction') == 'north' && q.block_state('supplementary:open_bit')",
      "components": {
          "minecraft:transformation": {
            "rotation": [
            -270,
            0,
            0
            ]
          }
      }
      },
      {
      "condition": "q.block_state('minecraft:vertical_half') == 'top' && q.block_state('minecraft:cardinal_direction') == 'south' && q.block_state('supplementary:open_bit')",
      "components": {
          "minecraft:transformation": {
            "rotation": [
            270,
            0,
            -180
            ]
          }
      }
      },
      {
      "condition": "q.block_state('minecraft:vertical_half') == 'top' && q.block_state('minecraft:cardinal_direction') == 'east' && q.block_state('supplementary:open_bit')",
      "components": {
          "minecraft:transformation": {
            "rotation": [
            0,
            270,
            90
            ]
          }
      }
      },
      {
      "condition": "q.block_state('minecraft:vertical_half') == 'top' && q.block_state('minecraft:cardinal_direction') == 'west' && q.block_state('supplementary:open_bit')",
      "components": {
          "minecraft:transformation": {
            "rotation": [
            180,
            -270,
            -270
            ]
          }
      }
      },
      {
      "condition": "q.block_state('minecraft:vertical_half') == 'bottom' && q.block_state('minecraft:cardinal_direction') == 'north' && !q.block_state('supplementary:open_bit')",
      "components": {
          "minecraft:transformation": {
            "rotation": [
            0,
            0,
            0
            ]
          }
      }
      },
      {
      "condition": "q.block_state('minecraft:vertical_half') == 'bottom' && q.block_state('minecraft:cardinal_direction') == 'south' && !q.block_state('supplementary:open_bit')",
      "components": {
          "minecraft:transformation": {
            "rotation": [
            0,
            180,
            0
            ]
          }
      }
      },
      {
      "condition": "q.block_state('minecraft:vertical_half') == 'bottom' && q.block_state('minecraft:cardinal_direction') == 'east' && !q.block_state('supplementary:open_bit')",
      "components": {
          "minecraft:transformation": {
            "rotation": [
            0,
            270,
            0
            ]
          }
      }
      },
      {
      "condition": "q.block_state('minecraft:vertical_half') == 'bottom' && q.block_state('minecraft:cardinal_direction') == 'west' && !q.block_state('supplementary:open_bit')",
      "components": {
          "minecraft:transformation": {
            "rotation": [
            0,
            -270,
            0
            ]
          }
      }
      },
      {
      "condition": "q.block_state('minecraft:vertical_half') == 'bottom' && q.block_state('minecraft:cardinal_direction') == 'north' && q.block_state('supplementary:open_bit')",
      "components": {
          "minecraft:transformation": {
            "rotation": [
            90,
            0,
            180
            ]
          }
      }
      },
      {
      "condition": "q.block_state('minecraft:vertical_half') == 'bottom' && q.block_state('minecraft:cardinal_direction') == 'south' && q.block_state('supplementary:open_bit')",
      "components": {
          "minecraft:transformation": {
            "rotation": [
            270,
            0,
            0
            ]
          }
      }
      },
      {
      "condition": "q.block_state('minecraft:vertical_half') == 'bottom' && q.block_state('minecraft:cardinal_direction') == 'east' && q.block_state('supplementary:open_bit')",
      "components": {
          "minecraft:transformation": {
            "rotation": [
            0,
            -270,
            90
            ]
          }
      }
      },
      {
      "condition": "q.block_state('minecraft:vertical_half') == 'bottom' && q.block_state('minecraft:cardinal_direction') == 'west' && q.block_state('supplementary:open_bit')",
      "components": {
          "minecraft:transformation": {
            "rotation": [
            180,
            270,
            -270
            ]
          }
      }
      }
    ]
}
}
以下是模型文件。
{"format_version":"1.12.0","minecraft:geometry":[{"description":{"identifier":"geometry.trapdoor","texture_width":16,"texture_height":16,"visible_bounds_width":3,"visible_bounds_height":1.5,"visible_bounds_offset":},"bones":[{"name":"trapdoor","pivot":,"cubes":[{"origin":[-8.01,-0.01,-8.01],"size":,"uv":{"north":{"uv":,"uv_size":[-16,-3]},"east":{"uv":,"uv_size":[-16,-3]},"south":{"uv":,"uv_size":[-16,-3]},"west":{"uv":,"uv_size":[-16,-3]},"up":{"uv":,"uv_size":[-16,-16]},"down":{"uv":,"uv_size":}}}]}]}]}
这里我本来是想通过texture_mesh实现镂空模型效果的,但是由于texture_mesh的texture字段指定的是附着物文档中的键名而不是方块文档中minecraft:material_instances的键名,不能实现这个功能。如果非得实现,模型代码会长很多,所以我还是选择了与原版保持一致。下期讲门的时候,拿在手里的门就是一个附着物,所以可以实现镂空效果。


https://klpbbs.com/static/image/hrline/line3.png


总结



这一期,我们制作了一个与原版极其相似的活板门。
最后,我放出我为这个活板门做的纹理,以及所有的示例文档,可以参考一下。






第四十一期 第四十二期 第四十三期

Cat_Anchor 发表于 2023-12-26 06:51:56

HuaV 发表于 2023-12-26 00:00
嘿,你知道附加包中可以添加世界包(世界模板)吗?是否有了解过其相关内容.. ...

世界模板好像是和附加包不同的.mctemplate文件,可以导入一个模板,创建世界时使用,似乎也可以在世界模板中包含附加包(和.mcworld差不多)

HuaV 发表于 2023-12-26 00:00:05

嘿,你知道附加包中可以添加世界包(世界模板)吗?是否有了解过其相关内容..

laohei 发表于 2023-12-10 12:28:10

感谢分享
页: [1]
查看完整版本: 附加包教程:42.方块(八)