用户:MashKJo/1.21.1模组开发教程/5.1.第一个物品

为模组添加新物品可以说是Modder最常见也是最简单的需求了。对于没有什么额外行为的物品,直接用Item类即可;如果需要有额外的逻辑,则需要先继承Item类,并覆写相应的方法。读者可以自行翻阅Item和IItemExtension的源码。

Item的构造方法接受一个Item.Properties,这个对象指定了物品的一些基本属性,如最大堆叠数、耐久值等等。

注册物品当然是用延迟注册机制:

public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(TutorialMod.MODID);

//一个最简单的物品注册。
//这个物品的注册名是<modid>:one_example_item。
public static final DeferredItem<Item> ONE_EXAMPLE_ITEM = ITEMS.registerSimpleItem("one_example_item");

//registerSimpleItem的另一个重载,第2个参数传入该物品的属性。
public static final DeferredItem<Item> ANOTHER_EXAMPLE_ITEM = ITEMS.registerSimpleItem("another_example_item", new Item.Properties(). ...);

//对于复杂的物品(表现为先继承Item类再实例化),调用registerItem。
public static final DeferredItem<ItemSubClass> ONE_SUBCLASS_ITEM = ITEMS.registerItem("one_subclass_item", ItemSubClass::new, new Item.Properties(). ...);

//别忘了在你的入口类构造方法中调用它!
public static void register(IEventBus bus) {
	ITEMS.register(bus);
}

运行runClient进入游戏,用/give命令就可以得到你注册进游戏的物品了。

模型文件和纹理

为了让我们的物品的外观不是紫黑块,我们需要给物品指定模型文件和纹理。

物品的模型文件位于路径assets/<modid>/models/item下,新建一个名为你的物品的注册名的path的JSON文件(如对示例代码中的ONE_EXAMPLE_ITEM而言,模型文件名就是one_example_item.json)。物品模型文件的格式在中文 Minecraft Wiki上有详尽的说明,这里只做简要示例:

{
  "parent": "minecraft:item/generated",
	"textures": {
		"layer0": "tutorialmod:item/one_example_item"
	}
}

parent父模型我们设定为minecraft:item/generated,这是物品的通用父模型;再在textures下指定该物品模型的第0层纹理为assets/<modid>/textures/item/<your_item_name>.png

将准备好的纹理PNG文件放入指定的位置,runClient打开游戏,你应该能看到你的新物品不是紫黑块了。

数据生成

鉴于作者还没研究明白物品/方块模型的数据生成,且复杂的物品/方块模型的数据生成很复杂,一般是在Blockbench中制作,直接导出为JSON,因此作者仍习惯于手写物品/方块模型的JSON,这里就不教数据生成了。

语言文件

你可能会注意到你的物品的名称是类似于item.<modid>.xxx这种形式,这是物品的本地化键名,代表我们还没有对物品进行本地化。

语言文件在assets/<modid>/lang下,也是JSON文件,我们先创建英文语言文件: en_us.json:

{
	"item.tutorialmod.one_example_item": "One Example Item"
}

英文语言文件在其他语言文件缺失时会被使用,就以本系列教程的受众来说,我们还应该添加简体中文(zh_cn.json)的语言文件:

{
	"item.tutorialmod.one_example_item": "一个示例物品"
}

好了,现在这个物品看上去真的没什么问题了。

数据生成

public class ENLanguageProvider extends LanguageProvider {

   public ENLanguageProvider(PackOutput output) {
       super(output, TutorialMod.MODID, "en_us");
       //第二个参数是你的MODID,第三个参数是生成的语言文件的对应语言的代码。
   }

   @Override
   protected void addTranslations() {
       addItem(ModItems.EXAMPLE_ITEM, "Example Item");
       //添加某物品的本地化名。
       //还有其他一些辅助方法,如addBlock、addDimension之类的。
       //还可以直接调用add方法,用于自定义本地化键名的本地化。
   }
}

最后不要忘了在GatherDataEvent监听器中添加你的LanguageProvider!