创建简单物品

在开始之前,我们需要了解一下创建物品的一般步骤:

  • 创建物品的类 (可选)
  • 实例化并注册物品
  • 给物品添加模型与材质
  • 物品名称的本地化
  • 给物品添加合成表/熔炉配方 (可选)

在阅读之前,建议你先翻看一下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()』又是什么意思呢?PropertiesItem里的一个类,它提供了很多方法,如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>,材质也仅仅是紫黑块,但我们创建了我们自己的物品,不是吗?

results matching ""

    No results matching ""