创建简单物品
在开始之前,我们需要了解一下创建物品的一般步骤:
- 创建物品的类 (可选)
- 实例化并注册物品
- 给物品添加模型与材质
- 物品名称的本地化
- 给物品添加合成表/熔炉配方 (可选)
在阅读之前,建议你先翻看一下net.minecraft.item
包,顺便看看net.minecraft.item.Items
。如果你看不懂,也没有关系,稍后就会讲到。
我们可以看到,里面所有的物品都直接或间接地继承了Item
类。而且有些物品读者只能在Items
里看到,他们都是直接new Item(...)
的。其次,你或许会发现,那些只能在Items
里看到的物品,通常都比较简单,例如铁锭、木棍等。
既然我们的标题是『创建简单物品』,那你应该知道了我们会以什么方式创建了。
让我们开始吧
我们先在xyz.bzstudio.modderguide
下新建包item
。这里我建议,Mod的包结构最好按照Minecraft的包结构创建,这样可以增强Mod源代码的可读性。当然,这一点也不是必须。
然后在item
下新建类Items
。这里我建议,在类名前面添加Mod名的缩写,以避免和net.minecraft.item.Items
重复,方便以后的开发。因此,我改成了MGItems
。
由于是简单物品,我们不需要为物品创建类。只需创建物品的实例并注册它即可。注册物品有两种方法,对应的创建实例的方法也有两种。我这里使用第一种,第二种方法以及两种方法的优缺点将会在3.4章节进行详细讲解。
首先,在MGItems
新建一个常量,用于注册,代码如下:
public static final DeferredRegister<Item> ITEMS = new DeferredRegister<>(ForgeRegistries.ITEMS, ModderGuide.MODID);
这里没有什么好讲的。
然后,再新建另一个Item
类型的常量,这就是我们的物品的实例。(为了读者阅读方便,这里的代码不是最简形式,请你自己化简)
public static final RegistryObject<Item> TEST_ITEM = ITEMS.register("test_item", () -> {
return new Item(new Item.Properties().group(ItemGroup.MISC));
});
首先是ITEMS.register(...)
,这是DeferredRegister提供的用于注册实例的方法,第一个参数是物品ID,你应该懂。但需要注意:物品、方块等的ID用小写下划线。第二个参数是一个Supplier<Item>
,这显然不是Item
,因此我们用了lambda语句,返回了一个Item
实例。
然后就是我们物品实例的部分,也就是new Item(new Item.Properties().group(ItemGroup.MISC))
这一部分。至于『new Item()
』,你应该明白它的意思,但里面的参数『new Item.Properties()
』又是什么意思呢?Properties
是Item
里的一个类,它提供了很多方法,如food()
、maxStackSize()
、group()
等,用于规定这个物品最基本的属性。如所属的创造模式物品栏、食物属性、工具属性等,这里的.group(ItemGroup.MISC)
表示这个物品在创造模式下可以在“杂项”物品栏里找到,其余的就不多讲了,你应该可以理解。
这样,我们在创建物品实例的同时,也注册了这个物品。当然,其实物品还不会被注册,因为Forge发现不了这段代码。因此,我们应该向主类的构造函数中添加以下代码:
MGItems.ITEMS.register(FMLJavaModLoadingContext.get().getModEventBus());
注意:这里的ITEMS.register()与前面的不是同一个方法。
这样,我们就给我们的注册添加了事件监听。当『注册物品』的事件发生时,我们的物品将会被注册。
现在,主类的构造函数就变成了这样:
src/main/java/xyz/bzstudio/modderguide/ModderGuide.java (部分)
:
public ModderGuide() {
MGItems.ITEMS.register(FMLJavaModLoadingContext.get().getModEventBus());
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::enqueueIMC);
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::processIMC);
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::doClientStuff);
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onServerStarting);
MinecraftForge.EVENT_BUS.register(this);
}
一些注意事项
但读者或许会发现,我们物品的实例并不是一个Item
,而是一个RegistryObject
,那我们如何获取Item
形式的物品实例呢?
RegistryObject
提供了一个get()
方法,在需要这个物品的实例的时候,只需要MGItems.TEST_ITEM.get()
即可。但是,在物品完成注册之前,get()
方法只会返回null
,在不合适的时机调用会引发空指针异常 (Null Pointer Exception,简称NPE)。有关注册的问题将在3.4章节讲到。
打开游戏测试
至此,我们的物品就创建完毕了,打开游戏看看吧!
如果你指定了物品的ItemGroup
,那么你的物品就可以在对应的创造模式物品栏找到。如果你没有指定,则可以输入/give Dev <modid>:<item_id>
获取。
目前,这个物品的名字仅仅是item.<modid>.<item_id>
,材质也仅仅是紫黑块,但我们创建了我们自己的物品,不是吗?