User Tools

Site Tools


zh_cn:tutorial:blocks

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Last revisionBoth sides next revision
zh_cn:tutorial:blocks [2022/12/16 01:12] – [注册方块] solidblockzh_cn:tutorial:blocks [2024/04/15 01:45] – [为方块注册物品] solidblock
Line 1: Line 1:
-====== 添加一个方块 ======+====== 添加方块 ======
  
-将方块添加到你的模组过程与[[zh_cn:tutorial:items|添加物品]]类似。你可以创建 ''Block'' 或自定义类的实例,然后将其注册到 ''Registries.BLOCK''(1.19.3 以上版本)或 ''Registry.BLOCK'' (1.19.2 以下)注册表。你还需要提供纹理和方块状态或模型文件以提供方块外观。如需了解方块模型格式的更多信息,请参考[[https://minecraft-zh.gamepedia.com/模型|Minecraft Wiki模型页面]]。+将方块添加到你的模组过程与[[zh_cn:tutorial:items|添加物品]]类似。你可以创建 ''Block'' 或自定义类的实例,然后将其注册到 ''Registries.BLOCK''(1.19.3 以上版本)或 ''Registry.BLOCK'' (1.19.2 以下)注册表。你还需要提供纹理和方块状态或模型文件以提供方块外观。如需了解方块模型格式的更多信息,请参考[[https://zh.minecraft.wiki/模型|Minecraft Wiki模型页面]]。
  
-===== 创建一个方块 =====+===== 创建方块 =====
  
-首先创建''Block''的实例。该实例可以存储在任何地方,但是我们会在''ModInitializer''的顶部开始。''Block''构造器函数需要一个''AbstractBlock.Settings''实例,也就是用于配置方块属性的构造器。Fabric提供一个''FabricBlockSettings''构造器类以及更多可用的选项。+首先创建 ''Block'' 的实例。该实例可以存储在任何地方,但是我们会在 ''ModInitializer'' 的顶部开始。''Block'' 构造器函数需要一个 ''AbstractBlock.Settings'' 实例,也就是用于配置方块属性的构造器。Fabric 提供一个 ''FabricBlockSettings'' 构造器类以及更多可用的选项。
  
 <code java [enable_line_numbers="true"]> <code java [enable_line_numbers="true"]>
Line 17: Line 17:
        石头的硬度为 1.5f,抗性为 6.0f,黑曜石的硬度为 50.0f,抗性为 1200.0f。        石头的硬度为 1.5f,抗性为 6.0f,黑曜石的硬度为 50.0f,抗性为 1200.0f。
                
-       可以在`Blocks`类中查找所有原版方块的统计+       可以在`Blocks`类中查找所有原版方块,你可以以此作为参考
     */     */
-    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 之后的版本: 
 +    public static final Block EXAMPLE_BLOCK = new Block(Block.Settings.create().strength(4.0f));
          
     @Override     @Override
Line 36: Line 42:
 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));+    // 对于 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 之后的版本: 
 +    public static final Block EXAMPLE_BLOCK = new Block(Block.Settings.create().strength(4.0f));
          
     @Override     @Override
Line 45: Line 56:
 </code> </code>
  
-您的方块不能作为物品存入背包,但可以通过使用 ''/setblock tutorial:example_block'' 在游戏中看到。+您的方块不能作为物品存入背包,但可以通过使用 ''/setblock <位置> tutorial:example_block'' 在游戏中看到。
  
 ==== 为方块注册物品 ==== ==== 为方块注册物品 ====
  
-在大多数情况下,您希望能够拿着物品放置方块。为此,您需要在物品注册表中注册一个相应的BlockItem。您可以通过在Registry.ITEM下注册BlockItem的实例来执行此操作。该物品的注册表名称通常应与该方块的注册表名称相同。+在大多数情况下,您希望能够拿着物品放置方块。为此,您需要在物品注册表中注册一个相应的物品。您可以通过在 ''Registries.ITEM'' 下注册 ''BlockItem'' 的实例来执行此操作。该物品的注册表名称通常应与该方块的注册表名称相同。
  
 <code java [enable_line_numbers="true",highlight_lines_extra="12"]> <code java [enable_line_numbers="true",highlight_lines_extra="12"]>
 public class ExampleMod implements ModInitializer { public class ExampleMod implements ModInitializer {
  
-    /* Declare and initialize our custom block instance+    // 对于 1.20 以下版本: 
-       We set out block material to METAL, which requires a pickaxe to efficiently break. +    // public static final Block EXAMPLE_BLOCK = new Block(FabricBlockSettings.of(Material.METAL).strength(4.0f)); 
-       Hardness represents how long the break takes to breakStone has a hardness of 1.5f, while Obsidian has a hardness of 50.0f+    // 对于 1.20.5 以下版本: 
-    *+    // public static final Block EXAMPLE_BLOCK = new Block(FabricBlockSettings.create().strength(4.0f)); 
-    public static final Block EXAMPLE_BLOCK = new Block(FabricBlockSettings.of(Material.METAL));+    // 对于自 1.20.5 之后的版本: 
 +    public static final Block EXAMPLE_BLOCK = new Block(Block.Settings.create().strength(4.0f));
          
     @Override     @Override
     public void onInitialize() {     public void onInitialize() {
-        Registry.register(Registry.BLOCK, new Identifier("tutorial", "example_block"), EXAMPLE_BLOCK); +        Registry.register(Registries.BLOCK, new Identifier("tutorial", "example_block"), EXAMPLE_BLOCK); 
-        Registry.register(Registry.ITEM, new Identifier("tutorial", "example_block"), new BlockItem(EXAMPLE_BLOCK, new Item.Settings().group(ItemGroup.MISC)));+        // 对于 1.20.5 以下版本: 
 +        // Registry.register(Registries.ITEM, new Identifier("tutorial", "example_block"), new BlockItem(EXAMPLE_BLOCK, new FabricItemSettings())); 
 +        // 对于自 1.20.5 之后的版本: 
 +        Registry.register(Registries.ITEM, new Identifier("tutorial", "example_block"), new BlockItem(EXAMPLE_BLOCK, new Item.Settings()));
     }     }
 } }
 </code> </code>
  
-===== 给您的方块一个外观 =====+===== 给方块外观 =====
  
-可能已经注意到,新的方块只是游戏中紫色和黑色棋盘格图案。这表明Minecraft加载方块资源或外观时出错。运行客户端时,完整的问题列表会输出在你的日志中。你需要以下文件来给予方块外观:+可能已经注意到,新的方块只是游戏中紫色和黑色棋盘格图案。这表明Minecraft加载方块资源或外观时出错。运行客户端时,完整的问题列表会输出在你的日志中。你需要以下文件来给予方块外观:
  
   * 方块状态文件   * 方块状态文件
Line 79: Line 94:
 这些文件位于: 这些文件位于:
  
-  方块状态:src/main/resources/assets/tutorial/blockstates/example_block.json +  方块状态:''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/block/example_block.json'' 
-  物品模型:src/main/resources/assets/tutorial/models/item/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/textures/block/example_block.png''
  
 方块状态文件根据其方块装填确定该方块应使用的模型。由于我们的方块没有所谓状态,所以我们用空字符串表示所有: 方块状态文件根据其方块装填确定该方块应使用的模型。由于我们的方块没有所谓状态,所以我们用空字符串表示所有:
Line 117: Line 132:
 ===== 配置方块掉落物 ===== ===== 配置方块掉落物 =====
  
-该方块必须有一个//战利品表//,以便在该方块被破坏时掉落物品。以下文件会使方块被破坏时掉落其本身。+该方块必须有//战利品表//,以便在该方块被破坏时掉落物品。以下文件会使方块被破坏时掉落其本身。
  
 <code JavaScript src/main/resources/data/tutorial/loot_tables/blocks/example_block.json> <code JavaScript src/main/resources/data/tutorial/loot_tables/blocks/example_block.json>
Line 140: Line 155:
 } }
 </code> </code>
 +
 +条件 ''minecraft:survives_explosion'' 的意思是,如果方块是在带有损耗的爆炸(例如苦力怕的爆炸,而非 TNT 的爆炸)中破坏的,//有可能//不会掉落。如果没有这个条件,那么方块在带有损耗的爆炸中总是会掉落。
  
 在1.17,破坏方块有所改变,定义采集工具和采集等级需要使用标签,请参考[[zh_cn:tutorial:tags|标签教程]]。我们需要将方块添加到以下标签: 在1.17,破坏方块有所改变,定义采集工具和采集等级需要使用标签,请参考[[zh_cn:tutorial:tags|标签教程]]。我们需要将方块添加到以下标签:
  
-  采集工具:src/main/resources/data/minecraft/tags/blocks/mineable/<tooltype>.json,其中'tooltype'可以是'axe'、'pickaxe'、'shovel'、'hoe' + 采集工具:''src/main/resources/data/minecraft/tags/blocks/mineable/<tooltype>.json'',其中 ''<tooltype>'' 可以是 ''axe''、''pickaxe''、''shovel''、''hoe'
-  采集等级:src/main/resources/data/minecraft/tags/blocks/needs_<tier>_tool.json,其中'tier'可以是:'stone'、'iron'、'diamond'+ 采集等级:''src/main/resources/data/minecraft/tags/blocks/needs_<tier>_tool.json'',其中 ''<tier>'' 可以是:''stone''、''iron''、''diamond''(//不包括// ''netherite''
  
 <code JavaScript src/main/resources/data/minecraft/tags/blocks/mineable/pickaxe.json> <code JavaScript src/main/resources/data/minecraft/tags/blocks/mineable/pickaxe.json>
Line 164: Line 181:
 </code> </code>
  
-对于采集等级标签(needs_stone_tool、needs_iron_tool和needs_diamond_tool)生效,在方块定义中将requiresTool()到FabricToolSettings+对于采集等级标签(''needs_stone_tool''''needs_iron_tool'' 和 ''needs_diamond_tool'')生效,在方块定义中将 ''requiresTool()'' 到 ''Block.Settings''(以 1.20.5 以上版本为例)
  
 <code java [enable_line_numbers="true"]> <code java [enable_line_numbers="true"]>
-    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> </code>
  
 ===== 创建自定义方块类 ===== ===== 创建自定义方块类 =====
  
-当创建一个简单的方块时,上述方法效果很好,但是有时您想要一个具有//一无二//机制的方块。我们将创建一个//单独//扩展''Block''的类来执行此操作。该类需要一个带有''AbstractBlock.Settings''参数的构造器:+当创建一个简单的方块时,上述方法效果很好,但是有时您想要一个具有////机制的方块。我们将创建一个//单独//继承 ''Block'' 的类来执行此操作。该类需要一个带有 ''AbstractBlock.Settings'' 参数的构造器:
  
 <code java [enable_line_numbers="true"]> <code java [enable_line_numbers="true"]>
Line 183: Line 200:
 </code> </code>
  
-你可以在方块类中覆盖方法以实现特殊功能。这里是''onUse''方法的实现,右键单击方块时会调用此方法。我们检查交互是否在服务器进行,并向玩家发送消息,//"Hello, world!"//+你可以在方块类中覆盖方法以实现特殊功能。这里是 ''onUse'' 方法的实现,右键单击方块时会调用此方法。我们检查交互是否在服务器进行,并向玩家发送消息,//"Hello, world!"//
  
 <code java [enable_line_numbers="true",highlight_lines_extra="8,9,10,11,12,13,14,15"]> <code java [enable_line_numbers="true",highlight_lines_extra="8,9,10,11,12,13,14,15"]>
Line 192: Line 209:
     }     }
  
 +    // 对于 1.20.5 以下版本,方法参数应该是“BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit”
     @Override     @Override
-    public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {+    public ActionResult onUse(World world, PlayerEntity player, BlockHitResult hit) {
         if (!world.isClient) {         if (!world.isClient) {
-            player.sendMessage(Text.of("Hello, world!"), false);+            player.sendMessage(Text.literal("Hello, world!"), false);
         }         }
  
Line 203: Line 221:
 </code> </code>
  
-要使用自定义方块类,请在注册时将//new Block//替换为//new ExampleBlock//+要使用自定义方块类,请在注册时将 ''new Block'' 替换为 ''new ExampleBlock''
  
 <code java [enable_line_numbers="true",highlight_lines_extra="3"]> <code java [enable_line_numbers="true",highlight_lines_extra="3"]>
 public class ExampleMod implements ModInitializer { public class ExampleMod implements ModInitializer {
  
-    public static final ExampleBlock EXAMPLE_BLOCK = new ExampleBlock(Block.Settings.of(Material.STONE).hardness(4.0f));+    public static final ExampleBlock EXAMPLE_BLOCK = new ExampleBlock(Block.Settings.create().strength(4.0f));
          
     @Override     @Override
     public void onInitialize() {     public void onInitialize() {
-        Registry.register(Registry.BLOCK, new Identifier("tutorial", "example_block"), EXAMPLE_BLOCK); +        Registry.register(Registries.BLOCK, new Identifier("tutorial", "example_block"), EXAMPLE_BLOCK); 
-        Registry.register(Registry.ITEM, new Identifier("tutorial", "example_block"), new BlockItem(EXAMPLE_BLOCK, new Item.Settings().group(ItemGroup.MISC)));+        Registry.register(Registries.ITEM, new Identifier("tutorial", "example_block"), new BlockItem(EXAMPLE_BLOCK, new Item.Settings()));
     }     }
 } }
 </code> </code>
  
-==== 自定义VoxelShape ====+==== 自定义形状 ====
  
-当使用不能''完整''填充一个方块的方块模型(例如铁砧、台阶、楼梯)时,邻近的方块隐藏面:+当使用不能完整填充一个方块的方块模型(例如铁砧、台阶、楼梯)而其形状却仍是完整的时,邻近的方块隐藏面就会暴露
  
 {{:tutorial:voxelshape_wrong.png?200|}} {{:tutorial:voxelshape_wrong.png?200|}}
  
-要解决这个问题,我们需要定义方块的''VoxelShape''+要解决这个问题,我们需要定义方块的 ''VoxelShape''
  
-<code> +<code java
- @Override +public class ExambleBlock extends Block { 
- public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, ShapeContext context) { +    [...] 
-     return VoxelShapes.cuboid(0f, 0f, 0f, 1f, 1.0f, 0.5f); +    @Override 
- }+    public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, ShapeContext context) { 
 +        return VoxelShapes.cuboid(0f, 0f, 0f, 1f, 1.0f, 0.5f); 
 +    } 
 +}
 </code> </code>
  
-注意方块的//collision shape//默认为其描边形状,如果未被指定。+注意方块的//碰撞形状//默认为其描边形状,如果未被指定。
  
 {{:tutorial:voxelshape_fixed.png?200|}} {{:tutorial:voxelshape_fixed.png?200|}}
  
-==== 下一步 ====+You can also define other types of shapes for the block. The type of shapes of blocks include: 
 +  * **outline shape**: the shape used as default value for most type of shapes. In the worlds, when you points to the shape, the translucent black outline is displayed according to this shape. Most times it should not be empty. 
 +  * **collision shape**: the shape used to calculate collisions. When entities (including players) are moving, their collision box usually cannot intersect the collision shape of blocks. Some blocks, such as fences and walls, may have a collision shape higher than one block. Some blocks, such as flowers, have an empty collision shape. Apart from modifying ''getCollisionShape'' method, you can also call ''noCollision'' in the ''FabricBlockSettings'' when creating the block. 
 +  * **raycasting shape**: the shape used to calculate raycasting (the process judging which block you are pointing to). You usually do not need to specify it. 
 +  * **camera collision shape**: the shape used to calculate the position of camera in third-party view. Glass and powder snow have an empty camera collision shape. 
 + 
 +===== 下一步 =====
 [[zh_cn:tutorial:blockstate|向方块添加简单状态,例如整数和布尔值]]。 [[zh_cn:tutorial:blockstate|向方块添加简单状态,例如整数和布尔值]]。
  
-[[zh_cn:tutorial:blockentity|给块一个方块实体,使它们可以具有物品栏之类的的高级状态]]。此外,还需要像GUI和自定义块渲染很多东西+[[zh_cn:tutorial:blockentity|给块一个方块实体,使它们可以具有物品栏之类的的高级状态]]。此外,还需要像 GUI 和自定义块渲染。 
 + 
 +要让方块可燃(也就是说,可以被火燃烧),可使用 ''FlammableBlockRegistry''
zh_cn/tutorial/blocks.txt · Last modified: 2024/04/15 01:52 by solidblock