This is an old revision of the document!
添加一个方块
介绍
要将一个方块添加到您的mod,您将需要注册一个新的Block类实例。为了更好地控制您的方块,可以创建一个自定义方块类。我们还将研究添加方块模型。
创建一个方块
首先,在您的主要mod类中创建Block的实例。 块的构造函数使用FabricBlockSettings构造器来设置方块的基本属性,例如硬度和抗炸性:
public class ExampleMod implements ModInitializer { // an instance of our new block public static final Block EXAMPLE_BLOCK = new Block(FabricBlockSettings.of(Material.METAL).build()); [...] }
注册方块
方块应该注册在Block.REGISTRY
的注册表下。调用Registry.register并传递适当的参数。
public class ExampleMod implements ModInitializer { public static final Block EXAMPLE_BLOCK = new Block(FabricBlockSettings.of(Material.METAL).hardness(4.0f)); @Override public void onInitialize() { } }
您的方块不能作为物品存入背包,但可以通过使用/setblock tutorial:example_block
在游戏中看到。
为方块注册物品
在大多数情况下,您希望能够拿着物品放置方块。为此,您需要在物品注册表中注册一个相应的BlockItem。您可以通过在Registry.ITEM下注册BlockItem的实例来执行此操作。该物品的注册表名称通常应与该方块的注册表名称相同。
public class ExampleMod implements ModInitializer { /* Declare and initialize our custom block instance. We set out block material to METAL, which requires a pickaxe to efficiently break. Hardness represents how long the break takes to break. Stone has a hardness of 1.5f, while Obsidian has a hardness of 50.0f. */ public static final Block EXAMPLE_BLOCK = new Block(FabricBlockSettings.of(Material.METAL)); @Override public void onInitialize() { } }
给您的方块一个外观
您可能已经注意到,新的方块只是游戏中紫色和黑色棋盘格图案。这表明Minecraft加载方块资源或外观时出错。运行客户端时,完整的问题列表会输出在你的日志中。你需要以下文件来给予方块外观:
- 方块状态文件
- 方块模型文件
- 材质
- 物品模型文件(如果方块有与之关联的物品)
这些文件位于:
方块状态:src/main/resources/assets/tutorial/blockstates/example_block.json 方块模型:src/main/resources/assets/tutorial/models/block/example_block.json 物品模型:src/main/resources/assets/tutorial/models/item/example_block.json 方块材质:src/main/resources/assets/tutorial/textures/block/example_block.png
方块状态文件根据其方块装填确定该方块应使用的模型。由于我们的方块没有所谓状态,所以我们用空字符串表示所有:
- src/main/resources/assets/tutorial/blockstates/example_block.json
{ "variants": { "": { "model": "tutorial:block/example_block" } } }
方块模型文件定义了方块的形状和材质。我们将使用block/cube_all作为父模型,这将使我们能够轻松地在方块的所有面上设置相同的材质。
- src/main/resources/assets/tutorial/models/block/example_block.json
{ "parent": "block/cube_all", "textures": { "all": "tutorial:block/example_block" } }
在大多数情况下,您想让方块作为物品时外观还是这个方块。为此,您可以制作一个从方块模型文件继承的项目文件,这会使得该物品外观和方块相同:
- src/main/resources/assets/tutorial/models/item/example_block.json
{ "parent": "tutorial:block/example_block" }
加载Minecraft,您的方块最终应该具有外观!
配置掉落物
该方块必须有一个战利品表,以便在该块损坏时掉落物品。以下文件会使方块被破坏时掉落其本身。
- src/main/resources/data/tutorial/loot_tables/blocks/example_block.json
{ "type": "minecraft:block", "pools": [ { "rolls": 1, "entries": [ { "type": "minecraft:item", "name": "tutorial:example_block" } ], "conditions": [ { "condition": "minecraft:survives_explosion" } ] } ] }
在生存模式下被破坏时,该方块现在会掉落物品。
创建自定义方块类
当创建一个简单的方块时,上述方法效果很好,但是有时您想要一个具有独一无二机制的方块。我们将创建一个单独的类来扩展Block来执行此操作。该类需要一个带有AbstractBlock.Settings
参数的构造器:
public class ExampleBlock extends Block { public ExampleBlock(Settings settings) { super(settings); } }
就像我们在项目教程中所做的一样,您可以覆盖方块类中的方法以实现自定义功能。Here's an implementation of the onUse
method, which is called when you right-click the block. We check if the interaction is occurring on the server, and then send the player a message saying, “Hello, world!”
public class ExampleBlock extends Block { public ExampleBlock(Settings settings) { super(settings); } @Override public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { if (!world.isClient) { player.sendMessage(new LiteralText("Hello, world!"), false); } return ActionResult.SUCCESS; } }
要使用自定义方块类,请在注册时将new Block替换为new ExampleBlock:
public class ExampleMod implements ModInitializer { public static final ExampleBlock EXAMPLE_BLOCK = new ExampleBlock(Block.Settings.of(Material.STONE).hardness(4.0f)); @Override public void onInitialize() { } }
自定义VoxelShape
当使用不能完整
填充一个方块的方块模型(例如铁砧、台阶、楼梯)时,邻近的方块会隐藏面:
要解决这个问题,我们需要定义方块的VoxelShape
:
@Override public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, ShapeContext context) { return VoxelShapes.cuboid(0f, 0f, 0f, 1f, 1.0f, 0.5f); }
注意方块的collision shape默认为其描边形状,如果未被指定。
下一步
给块一个方块实体,使它们可以具有物品栏之类的的高级状态。此外,还需要像GUI和自定义块渲染很多东西。