1.4 自定义物品组
Part A. 实战
物品组可以形象地理解为创造模式物品栏的分栏。我们在最开始就提到的类 ItemGroup
,所以自定义物品组很简单——就写一个继承于 ItemGroup
类的子类就行。
这个继承的类只需要写两个地方,一个是构造函数,直接使用父类的即可,第一个参数是物品组的名称 String
。(这个组就以 “ObsidianGroup” 为例)
另一个是重写类里面的 createIcon()
实例方法(实际用途是创建物品栏的图标),要求返回一个 ItemStack
实例(毕竟需要将物品呈现在物品栏中),这个也很简单,用 ItemStack
构造函数构造个实例就行。ItemStack
构造函数的第一参数就是已注册的 Item
实例对象。
从哪获取已注册的
Item
实例?简单,之前我们注册完物品后,DeferredRegister::register
方法不是返回了一个RegisterObject<Item>
,它就是包裹了注册信息的Item
,直接用get()
实例方法就能返回已注册的Item
实例。
public class ObsidianGroup extends ItemGroup {
public ObsidianGroup() {
// 注意:这里是翻译键,如果需要本地化(后面介绍),请记住它
super("obsidian_group");
}
@Override
public ItemStack createIcon() {
// ItemRegistry.obsidianIngot 对象在 1.1 中定义,忘了回去看
return new ItemStack(ItemRegistry.obsidianIngot.get());
}
}
这个简单的物品组类就做好了。但是想要将它显示在游戏里,还要将它在合适的位置实例化。
我们再定义一个类,专门存放 mod 中实例化的 ItemGroup
的类,就叫 ModGroup
:
public class ModGroup {
public static final ItemGroup og_group = new ObsidianGroup();
}
这样在物品类初始化的时候,用 Properties::group()
实例方法将物品加入 og_group
这个实例即可。
public class ObsidianIngot extends Item {
public ObsidianIngot() {
super(new Properties().group(ModGroup.og_group));
}
}
Part B. 理论:ItemGroup
& ItemStack
对于 MC 中的物品组,创建方法比较简单,就是继承于原版的 ItemGroup
类型即可。
ItemGroup
提供构造方法:
public ItemGroup(String itemGroupName);
开发者可以自定义创建的物品组的属性,常见的是设置物品组的图标:
@Override
public ItemStack createIcon() {
/* do something to get an item stack / create an item stack containing the specific item (to use its icon) */
}
设置方法是重载父类的 createIcon
方法,要求返回一个包含指定 Item
(要显示图标的 Item
)的 ItemStack
即可,我们一般可以通过新建一个 ItemStack
对象,也可以引用已经存在的 ItemStack
对象来完成。这里涉及 ItemStack
的一个构造方法:
public ItemStack(Item containingItem);
怎么拿到 Item
对象呢?常见的做法是,获取在 mod 中注册过的物品,来作为 ItemStack
的包含对象。
为什么这里可以用我们之前注册的对象呢?因为调用这个方法的时候,一定是已经进入游戏了,也就是说其调用的生命周期一定在 mod 初始化结束后。
只有这种情况才能直接使用自己注册的对象。
回忆一下,deferred register 注册物品后会返回一个 RegisterObject<T>
,同时包含了被注册对象和一些注册信息。我们可以使用已注册对象 get
到完整的 Item
信息,然后传给 ItemStack
进行构造。
值得注意的是,ItemGroup
无需手动注册,只要有 Item
或者其他已注册的对象在设置 Properties
时,使用 .group()
指定这个新的 ItemGroup
实例后,这个新的实例就会自动被注册进入程序。