第一个方块
在Minecraft中,如果你想添加一个新的方块,你需要创建一个新的Java类来代表这个方块。这个类需要继承自Block类,并使用Properties类来设置方块的一些属性,如硬度、爆炸抗性等。在下面的代码中,我们创建了一个名为RubyBlock的类,这个类代表了一个新的方块,它的属性与石头相似,但硬度更高。
1 2 3 4 5 6 7 8 9 10
| package net.flandre923.examplemod.block.custom;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks;
public class RubyBlock extends Block { public RubyBlock() { super(Properties.ofFullCopy(Blocks.STONE).strength(5f)); } }
|
接下来,你需要注册这个新的方块,这样Minecraft才知道它的存在。这通常是通过创建一个DeferredRegister对象来完成的,这个对象会帮助你将方块注册到Minecraft的注册表中。在下面的代码中,我们创建了一个名为ModBlocks的类,这个类包含了我们的RubyBlock方块的注册代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package net.flandre923.examplemod.block;
import net.flandre923.examplemod.ExampleMod; import net.flandre923.examplemod.block.custom.RubyBlock; import net.minecraft.core.registries.Registries; import net.minecraft.world.level.block.Block; import net.neoforged.bus.api.IEventBus; import net.neoforged.neoforge.registries.DeferredRegister;
import java.util.function.Supplier;
public class ModBlocks { public static final DeferredRegister<Block> BLOCKS = DeferredRegister.create(Registries.BLOCK, ExampleMod.MODID);
public static final Supplier<Block> RUBY_BLOCK = BLOCKS.register("ruby_block", RubyBlock::new);
public static void register(IEventBus eventBus){ BLOCKS.register(eventBus); } }
|
然后,你需要为这个方块创建一个对应的物品形式,这样玩家才能在游戏中捡起和使用它。这通常是通过创建一个BlockItem对象来完成的,这个对象将方块和物品关联起来。在下面的代码中,我们创建了一个名为ModItems的类,这个类包含了我们的RubyBlock物品的注册代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| package net.flandre923.examplemod.item;
import net.flandre923.examplemod.ExampleMod; import net.flandre923.examplemod.block.ModBlocks; import net.minecraft.core.registries.Registries; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.Item; import net.neoforged.bus.api.IEventBus; import net.neoforged.neoforge.registries.DeferredRegister;
import java.util.function.Supplier;
public class ModItems { public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(Registries.ITEM, ExampleMod.MODID);
public static final Supplier<Item> RUBY = ITEMS.register("ruby",() -> new Item(new Item.Properties()));
public static final Supplier<Item> RUBY_BLOCK = ITEMS.register("ruby_block",()->new BlockItem(ModBlocks.RUBY_BLOCK.get(), new Item.Properties())); public static void register(IEventBus eventBus){ ITEMS.register(eventBus); } }
|
最后,你需要将这个物品添加到创造模式的物品栏中,这样玩家才能在游戏中找到它。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| package net.flandre923.examplemod.item;
import net.flandre923.examplemod.ExampleMod; import net.flandre923.examplemod.block.ModBlocks; import net.minecraft.core.registries.Registries; import net.minecraft.data.PackOutput; import net.minecraft.network.chat.Component; import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.CreativeModeTabs; import net.neoforged.bus.api.IEventBus; import net.neoforged.neoforge.registries.DeferredRegister;
import java.util.function.Supplier;
public class ModCreativeTab { public static final DeferredRegister<CreativeModeTab> CREATIVE_MODE_TABS = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, ExampleMod.MODID);
public static final String EXAMPLE_MOD_TAB_STRING = "creativetab.example_tab";
public static final Supplier<CreativeModeTab> EXAMPLE_TAB = CREATIVE_MODE_TABS.register("example_tab",() -> CreativeModeTab.builder() .withTabsBefore(CreativeModeTabs.COMBAT) .title(Component.translatable(EXAMPLE_MOD_TAB_STRING)) .icon(()->ModItems.RUBY.get().getDefaultInstance()) .displayItems((pParameters, pOutput) -> { pOutput.accept(ModItems.RUBY.get()); pOutput.accept(ModItems.RUBY_BLOCK.get()); }) .build());
public static void register(IEventBus eventBus){ CREATIVE_MODE_TABS.register(eventBus); } }
|
注册到总线
1 2 3 4 5 6 7 8
| public ExampleMod(IEventBus modEventBus) { modEventBus.addListener(this::commonSetup); ModItems.register(modEventBus); ModBlocks.register(modEventBus); ModCreativeTab.register(modEventBus); NeoForge.EVENT_BUS.register(this); }
|
Item和Block的区别
在Minecraft中,Item和Block是两个不同的概念。Item代表玩家可以捡起、放入背包、使用和丢弃的物品,如工具、食物和材料。Block代表游戏中固定在地面上的物体,如石头、木头和矿石。虽然Item和Block是不同的对象,但它们之间有紧密的联系。例如,当玩家破坏一个方块时,它通常会掉落一个对应的物品形式。同样,当玩家将一个物品放入世界中时,它通常会变成一个对应的方块形式。
Block 和Block State
Block是Minecraft中所有实体的基类,代表了一个基本的、不可再分的地形单元。每个Block都有其独特的属性和行为,如硬度、爆炸抗性、是否能被点燃等。在代码中,每个方块都由一个Block类的实例表示。当你创建一个新的方块时,你需要继承Block类并覆写一些方法来定义你的方块的行为。
例如,你可以通过覆写randomTick方法来让方块有几率在游戏世界中产生随机变化,或者通过覆写onPlace方法来定义方块被放置时的行为。
Block State指的是一个方块在其生命周期中的具体状态。由于Minecraft中的大多数方块都有多种形态,如木头的方向、石头的类型等,因此需要一个机制来存储和检索这些信息。Block State就是用来描述这些不同形态的。
每个Block都可以有多个Block State,每个Block State都有一个唯一的标识符和一组属性。属性是Block State的组成部分,它们定义了方块的外观和行为。例如,一个木台阶可以有六个不同的方向,每个方向都是一个不同的Block State。
在代码中,Block State由BlockState类表示,你可以通过这个类的实例来获取和设置方块的状态。例如,你可以通过调用getBlockState().with(Properties.HORIZONTAL_FACING, Direction.NORTH)来设置一个方块面向北方。
方块模型和材质
建立这样的目录结构

1 2 3 4 5 6 7 8 9 10 11 12
| resources ├───assets │ └───examplemod │ ├───blockstates │ ├───lang │ ├───models │ │ ├───block │ │ └───item │ └───textures │ ├───block │ └───item
|

这段代码是JSON格式的数据,用于告诉Minecraft游戏,当渲染名为ruby_block的方块时,应该使用哪个模型文件。在这里,”model”: “examplemod:block/ruby_block_model”指定了模型的路径,examplemod是模组的名称,block/ruby_block_model是模型文件相对于模组资源文件夹的路径。这个模型文件将定义方块的外观和结构。
1 2 3 4 5
| { "variants": { "": { "model": "examplemod:block/ruby_block_model" } } }
|
这段代码同样使用JSON格式,它定义了一个模型文件的内容。”parent”: “block/cube_all”指定了这个模型是基于Minecraft内置的cube_all模型,这意味着它是一个简单的立方体。”textures”: {“all”: “examplemod:block/ruby_block”}定义了立方体六个面使用的纹理。这里,”all”表示六个面使用同一个纹理,纹理的路径是examplemod:block/ruby_block。
1 2 3 4 5 6
| { "parent": "block/cube_all", "textures": { "all": "examplemod:block/ruby_block" } }
|
这段代码用于定义物品的模型。在Minecraft中,物品和方块通常使用相同的模型。”parent”: “examplemod:block/ruby_block”表明物品模型将使用与ruby_block方块相同的模型。这意味着,当你在创造模式物品栏或者手中拿着这个物品时,它会看起来和它在世界中作为方块时一样。
1 2 3
| { "parent": "examplemod:block/ruby_block" }
|
ruby_block.png是一个纹理文件,通常是一个图片文件,它包含了方块的表面图案。在Minecraft中,纹理文件被用于给方块和物品提供详细的外观。这个文件应该放在模组的资源文件夹中对应于纹理路径examplemod:block/ruby_block的位置。纹理文件通常包含多个Minecraft方块的图案,每个方块的一部分通常被安排在一个大图中,通过纹理坐标来指定使用大图中的哪一部分。
ruby_block.png
下面我对相关的类做一个简单的介绍详细的内容可以自己查看
Block类
Block类是创建和定义新方块的地方
Block Behaviour Properties 类
BlockBehaviourProperties类用于设置方块的行为属性
Blocks 类
Blocks类则是一个方便的仓库,用于访问游戏中的所有方块。
简化我们注册Block的步骤
简化在Minecraft模组中注册方块和对应物品的过程。通过将这些步骤封装在方法中,更容易地添加新的方块,并确保每个方块都有一个对应的物品形式。
1 2 3 4 5 6 7 8 9 10 11 12 13
| public static final Supplier<Block> RUBY_BLOCK = registerBlock("ruby_block", RubyBlock::new);
public static Supplier<Block> registerBlock(String name,Supplier<Block> block){ Supplier<Block> toReturn = BLOCKS.register(name, block); registerBlockItem(name,toReturn); return toReturn; } public static void registerBlockItem(String name, Supplier<Block> block){ registerBlockItem(name, block, new Item.Properties()); } public static void registerBlockItem(String name, Supplier<Block> block, Item.Properties properties){ ITEMS.register(name, () -> new BlockItem(block.get(), properties)); }
|
现在创造模式物品栏中可以直接添加方块,以为方块实现了asitem这个接口
1 2 3 4 5 6 7 8 9
| public static final Supplier<CreativeModeTab> EXAMPLE_TAB = CREATIVE_MODE_TABS.register("example_tab",() -> CreativeModeTab.builder() .withTabsBefore(CreativeModeTabs.COMBAT) .title(Component.translatable(EXAMPLE_MOD_TAB_STRING)) .icon(()->ModItems.RUBY.get().getDefaultInstance()) .displayItems((pParameters, pOutput) -> { pOutput.accept(ModItems.RUBY.get()); pOutput.accept(ModBlocks.RUBY_BLOCK.get()); }) .build());
|
这样做简化Minecraft模组中方块和物品的注册过程。减少了重复代码。