zh_cn:tutorial:blocks
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
zh_cn:tutorial:blocks [2022/12/16 01:20] – [自定义VoxelShape] solidblock | zh_cn:tutorial:blocks [2024/12/08 14:23] (current) – [下一步] solidblock | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== 添加一个方块 ====== | + | ====== 添加方块 ====== |
- | 将方块添加到你的模组过程与[[zh_cn: | + | 将方块添加到你的模组过程与[[zh_cn: |
- | ===== 创建一个方块 ===== | + | ===== 创建方块 ===== |
+ | :!: 使用你使用的是 1.21.2 或者之后的版本,请直接看 [[#在 1.21.2+ 中注册方块]]。 | ||
首先创建 '' | 首先创建 '' | ||
- | <code java [enable_line_numbers=" | + | <code java [enable_line_numbers=" |
public class ExampleMod implements ModInitializer { | public class ExampleMod implements ModInitializer { | ||
Line 17: | Line 18: | ||
| | ||
- | | + | |
*/ | */ | ||
- | public static final Block EXAMPLE_BLOCK = new Block(FabricBlockSettings.of(Material.METAL).hardness(4.0f)); | + | |
+ | // 对于 1.20 以下版本: | ||
+ | // public static final Block EXAMPLE_BLOCK = new Block(FabricBlockSettings.of(Material.METAL).strength(4.0f)); | ||
+ | // 对于 1.20.5 以下版本: | ||
+ | // public static final Block EXAMPLE_BLOCK = new Block(FabricBlockSettings.create().strength(4.0f)); | ||
+ | // 对于自 1.20.5 之后、1.21.2 以前的版本: | ||
+ | public static final Block EXAMPLE_BLOCK = new Block(Block.Settings.create().strength(4.0f)); | ||
| | ||
@Override | @Override | ||
Line 27: | Line 34: | ||
} | } | ||
</ | </ | ||
- | ==== 注册方块 ==== | + | ===== 注册方块 |
- | 方块应该注册在 '' | + | 方块应该注册在 '' |
如果你使用的是 1.19.2 以下的版本,请将 '' | 如果你使用的是 1.19.2 以下的版本,请将 '' | ||
- | <code java [enable_line_numbers=" | + | <code java [enable_line_numbers=" |
public class ExampleMod implements ModInitializer { | public class ExampleMod implements ModInitializer { | ||
- | public static final Block EXAMPLE_BLOCK = new Block(FabricBlockSettings.of(Material.METAL).strength(4.0f)); | + | |
+ | // public static final Block EXAMPLE_BLOCK = new Block(FabricBlockSettings.of(Material.METAL).strength(4.0f)); | ||
+ | // 对于 1.20.5 以下版本: | ||
+ | // public static final Block EXAMPLE_BLOCK = new Block(FabricBlockSettings.create().strength(4.0f)); | ||
+ | // 对于自 1.20.5 之后、1.21.2 以前的版本: | ||
+ | public static final Block EXAMPLE_BLOCK = new Block(Block.Settings.create().strength(4.0f)); | ||
| | ||
@Override | @Override | ||
public void onInitialize() { | public void onInitialize() { | ||
- | Registry.register(Registries.BLOCK, | + | |
+ | // Registry.register(Registries.BLOCK, | ||
+ | // 对于 1.21 之后的版本: | ||
+ | Registry.register(Registries.BLOCK, | ||
} | } | ||
} | } | ||
</ | </ | ||
- | 您的方块不能作为物品存入背包,但可以通过使用 ''/ | + | 你的自定义方块不能作为物品存入背包,但可以通过使用 ''/ |
==== 为方块注册物品 ==== | ==== 为方块注册物品 ==== | ||
Line 51: | Line 66: | ||
在大多数情况下,您希望能够拿着物品放置方块。为此,您需要在物品注册表中注册一个相应的物品。您可以通过在 '' | 在大多数情况下,您希望能够拿着物品放置方块。为此,您需要在物品注册表中注册一个相应的物品。您可以通过在 '' | ||
- | <code java [enable_line_numbers=" | + | <code java [enable_line_numbers=" |
public class ExampleMod implements ModInitializer { | public class ExampleMod implements ModInitializer { | ||
- | public static final Block EXAMPLE_BLOCK = new Block(FabricBlockSettings.of(Material.METAL).strength(4.0f)); | + | |
+ | // public static final Block EXAMPLE_BLOCK = new Block(FabricBlockSettings.of(Material.METAL).strength(4.0f)); | ||
+ | // 对于 1.20.5 以下版本: | ||
+ | // public static final Block EXAMPLE_BLOCK = new Block(FabricBlockSettings.create().strength(4.0f)); | ||
+ | // 对于自 1.20.5 之后、1.21.2 之前的版本: | ||
+ | public static final Block EXAMPLE_BLOCK = new Block(Block.Settings.create().strength(4.0f)); | ||
| | ||
@Override | @Override | ||
public void onInitialize() { | public void onInitialize() { | ||
Registry.register(Registries.BLOCK, | Registry.register(Registries.BLOCK, | ||
- | Registry.register(Registries.ITEM, | + | |
+ | // Registry.register(Registries.ITEM, | ||
+ | // 对于 1.21 以下版本: | ||
+ | // Registry.register(Registries.ITEM, | ||
+ | // 对于 1.21 之后的版本: | ||
+ | Registry.register(Registries.ITEM, | ||
} | } | ||
} | } | ||
</ | </ | ||
- | ===== 给您的方块一个外观 ===== | + | ===== 注册方块的最佳实践 ===== |
+ | :!: 本段不适用于 1.21.2 之后的版本。 | ||
+ | |||
+ | 有时你的模组有许多方块。如果这样注册,你会为每个方块都写这样复杂的代码,代码就会显乱。所以,类似于注册物品,我们为方块创建单独的类,以及一个实用方法以注册方块和物品。 | ||
+ | |||
+ | <code java TutorialBlocks.java> | ||
+ | public final class TutorialBlocks { | ||
+ | public static final Block EXAMPLE_BLOCK = register(" | ||
+ | |||
+ | private static <T extends Block> T register(String path, T block) { | ||
+ | Registry.register(Registries.BLOCK, | ||
+ | Registry.register(Registries.ITEM, | ||
+ | return block; | ||
+ | } | ||
+ | |||
+ | public static void initialize() { | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | 记得要在 '' | ||
+ | <code java ExampleMod.java> | ||
+ | public class ExampleMod implements ModInitializer { | ||
+ | @Override | ||
+ | public void onInitialize() { | ||
+ | TutorialBlocks.initialize(); | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== 在 1.21.2+ 中注册方块 ===== | ||
+ | 在 1.21.2+ 中,要把 '' | ||
+ | |||
+ | <code java> | ||
+ | public class ExampleMod implements ModInitializer { | ||
+ | public static final Block EXAMPLE_BLOCK = register(" | ||
+ | |||
+ | private static Block register(String path, Function< | ||
+ | final Identifier identifier = Identifier.of(" | ||
+ | final RegistryKey< | ||
+ | |||
+ | final Block block = Blocks.register(registryKey, | ||
+ | Items.register(block); | ||
+ | return block; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | 上面的代码中,'' | ||
+ | |||
+ | ===== 给予方块外观 ===== | ||
- | 您可能已经注意到,新的方块只是游戏中紫色和黑色棋盘格图案。这表明Minecraft加载方块资源或外观时出错。运行客户端时,完整的问题列表会输出在你的日志中。你需要以下文件来给予方块外观: | + | 你可能已经注意到,新的方块只是游戏中紫色和黑色棋盘格图案。这表明 Minecraft 加载方块资源或外观时出错。运行客户端时,完整的问题列表会输出在你的日志中。你需要以下文件来给予方块外观: |
* 方块状态文件 | * 方块状态文件 | ||
Line 75: | Line 150: | ||
这些文件位于: | 这些文件位于: | ||
- | 方块状态:src/ | + | |
- | 方块模型:src/ | + | |
- | 物品模型:src/ | + | |
- | 方块纹理:src/ | + | |
方块状态文件根据其方块装填确定该方块应使用的模型。由于我们的方块没有所谓状态,所以我们用空字符串表示所有: | 方块状态文件根据其方块装填确定该方块应使用的模型。由于我们的方块没有所谓状态,所以我们用空字符串表示所有: | ||
Line 113: | Line 188: | ||
===== 配置方块掉落物 ===== | ===== 配置方块掉落物 ===== | ||
- | 该方块必须有一个// | + | 该方块必须有// |
- | <code JavaScript src/ | + | 对于 1.21 之后的版本,路径为 '' |
+ | |||
+ | <code JavaScript src/ | ||
{ | { | ||
" | " | ||
Line 137: | Line 214: | ||
</ | </ | ||
- | 在1.17,破坏方块有所改变,定义采集工具和采集等级需要使用标签,请参考[[zh_cn: | + | 条件 '' |
- | | + | 在 1.17,破坏方块有所改变,定义采集工具和采集等级需要使用标签,请参考[[zh_cn: |
- | 采集等级:src/ | + | |
+ | * 采集工具:'' | ||
+ | | ||
<code JavaScript src/ | <code JavaScript src/ | ||
Line 146: | Line 225: | ||
" | " | ||
" | " | ||
- | "example: | + | "tutorial: |
] | ] | ||
} | } | ||
Line 155: | Line 234: | ||
" | " | ||
" | " | ||
- | "example: | + | "tutorial: |
] | ] | ||
} | } | ||
</ | </ | ||
- | 对于采集等级标签(needs_stone_tool、needs_iron_tool和needs_diamond_tool)生效,在方块定义中将requiresTool()到FabricToolSettings: | + | 要采集等级标签('' |
<code java [enable_line_numbers=" | <code java [enable_line_numbers=" | ||
- | public static final Block EXAMPLE_BLOCK = new ExampleBlock(FabricBlockSettings.of(Material.METAL).strength(4.0f).requiresTool()); | + | public static final Block EXAMPLE_BLOCK = new ExampleBlock(Block.Settings.create().strength(4.0f).requiresTool()); |
</ | </ | ||
===== 创建自定义方块类 ===== | ===== 创建自定义方块类 ===== | ||
- | 当创建一个简单的方块时,上述方法效果很好,但是有时您想要一个具有// | + | 当创建一个简单的方块时,上述方法效果很好,但是有时您想要一个具有// |
- | <code java [enable_line_numbers=" | + | <code java [enable_line_numbers=" |
public class ExampleBlock extends Block { | public class ExampleBlock extends Block { | ||
- | |||
public ExampleBlock(Settings settings) { | public ExampleBlock(Settings settings) { | ||
super(settings); | super(settings); | ||
Line 181: | Line 259: | ||
你可以在方块类中覆盖方法以实现特殊功能。这里是 '' | 你可以在方块类中覆盖方法以实现特殊功能。这里是 '' | ||
- | <code java [enable_line_numbers=" | + | <code java [enable_line_numbers=" |
public class ExampleBlock extends Block { | public class ExampleBlock extends Block { | ||
Line 188: | Line 266: | ||
} | } | ||
+ | // 对于 1.20.5 以下版本,方法参数应该是“BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit” | ||
@Override | @Override | ||
- | public ActionResult onUse(BlockState state, | + | public ActionResult onUse(World world, PlayerEntity player, BlockHitResult hit) { |
if (!world.isClient) { | if (!world.isClient) { | ||
- | player.sendMessage(Text.of(" | + | player.sendMessage(Text.literal(" |
} | } | ||
Line 201: | Line 280: | ||
要使用自定义方块类,请在注册时将 '' | 要使用自定义方块类,请在注册时将 '' | ||
- | <code java [enable_line_numbers=" | + | <code java [enable_line_numbers=" |
- | public class ExampleMod implements ModInitializer | + | public |
- | public static final ExampleBlock | + | public static final Block EXAMPLE_BLOCK = register(" |
| | ||
- | | + | |
- | public void onInitialize() { | + | |
- | Registry.register(Registries.BLOCK, new Identifier(" | + | |
- | Registry.register(Registries.ITEM, | + | |
- | } | + | |
} | } | ||
</ | </ | ||
- | ==== 自定义形状e ==== | + | ==== 自定义形状 ==== |
当使用不能完整填充一个方块的方块模型(例如铁砧、台阶、楼梯)而其形状却仍是完整的时,邻近的方块的隐藏面就会暴露: | 当使用不能完整填充一个方块的方块模型(例如铁砧、台阶、楼梯)而其形状却仍是完整的时,邻近的方块的隐藏面就会暴露: | ||
Line 222: | Line 297: | ||
要解决这个问题,我们需要定义方块的 '' | 要解决这个问题,我们需要定义方块的 '' | ||
- | <code java> | + | < |
public class ExambleBlock extends Block { | public class ExambleBlock extends Block { | ||
[...] | [...] | ||
Line 236: | Line 311: | ||
{{: | {{: | ||
- | ==== 下一步 ==== | + | 你也可以定义其他几类方块形状,方块形状的类型包括: |
+ | * **外观形状(outline shape)**:方块大多数类型的形状都使用这个值作为默认。在世界中,当你指向这个形状时,会根据此形状绘制道明的黑色边框。大多数时候,这个形状不应该是空的。 | ||
+ | * **碰撞形状(collision shape)**:用于计算碰撞的形状。实体(包括玩家)移动时,其碰撞箱通常不能与方块的碰撞形状重合。一些方块,例如栅栏和墙,碰撞形状高于一格。一些方块,例如花,碰撞形状是空的。除了修改 '' | ||
+ | * **raycasting shape**:用于计算视线投射(判断你正在指向哪个方块的过程)的形状。通过不需要指定。 | ||
+ | * **相机碰撞形状(camera collision shape)**:用于计算第三人称视角的相机的位置的形状。玻璃和细雪的相机碰撞形状为空。 | ||
+ | * | ||
+ | ===== 下一步 | ||
[[zh_cn: | [[zh_cn: | ||
- | [[zh_cn: | + | [[zh_cn: |
+ | |||
+ | 要让方块可燃(也就是说,可以被火燃烧),可使用 '' |
zh_cn/tutorial/blocks.1671153627.txt.gz · Last modified: 2022/12/16 01:20 by solidblock