我的世界Java版1.21.4的Fabric模组开发教程(六)创建自定义物品组

这是适用于Minecraft Java版1.21.4的Fabric模组开发系列教程专栏第六章——创建自定义物品组。想要阅读其他内容,请查看或订阅上面的专栏。

物品组是创造模式物品栏中存储物品的一个标签页。 在本章中,我们将创建自定义的物品组并将所自定义物品添加到这个物品组中。

创建自定义物品组,通常要完成以下步骤:

  • 创建物品组对象;
  • 创建物品组注册键对象;
  • 在游戏注册表中注册物品组;
  • 将物品添加到自定义物品组中。

创建物品组对象

一般,创建一个自定义物品组的代码量较小,因此相关代码可以直接写在入口点类中。


物品组类ItemGroup

ItemGroup类用于组织、管理和创建游戏中创造模式物品栏中的每个标签页,是创建自定义物品组务必要创建的对象。在ItemGroup类中有构造ItemGroup对象的构造器内部类ItemGroup.Builder

物品组构造器内部类ItemGroup.Builder

ItemGroup.Builder是Minecraft API提供的用于创建ItemGroup对象的内部类。ItemGroup.Builder提供了几个方法用于配置物品组相关属性,这些方法均支持链式编程;

  • displayName():指定物品组的名称。传递一个Text对象;
  • icon():指定物品组的图标。传递一个Supplier<ItemStack>对象;
  • entries():指定物品组中的物品。传递一个ItemGroup.EntryCollector对象;
  • build():构造ItemGroup对象,必须在链式编程结尾调用;

但是,Fabric对此构造器进行了封装,要创建ItemGroup对象,现在可以使用FabricItemGroup类。

Fabric物品组类FabricItemGroup和Fabric物品组构造器实现类FabricItemGroupBuilderImpl

FabricItemGroupFabricItemGroupBuilderImpl两个类均对ItemGroup.Builder进行了封装,改变了使用ItemGroup.Builder创建ItemGroup对象的繁琐步骤。

FabricItemGroup类用于创建ItemGroup.Builder对象,其中只有一个静态方法builder(),返回一个ItemGroup.Builder对象;

public static ItemGroup.Builder builder() {
	return new FabricItemGroupBuilderImpl();
}

不过在这期间,builder()方法首先调用了FabricItemGroupBuilderImpl类的构造方法,用于返回ItemGroup.Builder对象;

FabricItemGroupBuilderImpl类继承了ItemGroup.Builder类,是Fabric对其父类的封装,从而使开发者避免了调用ItemGroup.Builder类中的构造方法来创建自定义物品组。FabricItemGroupBuilderImpl类中重写了其父类的build()等方法,改进了父类中的代码逻辑。

物品收集器内部函数式接口ItemGroup.EntryCollector

ItemGroup.EntryCollector接口在ItemGroup类内部声明,是调用ItemGroup.Builder对象的方法entries()时传递的参数,旨在将物品添加物品组当中ItemGroup.EntryCollector@FunctionalInterface注解修饰,因此调用接口时可以写成一个函数表达式;

@FunctionalInterface
public interface EntryCollector {
	void accept(ItemGroup.DisplayContext displayContext, ItemGroup.Entries entries);
}

内部接口中只有一个accept()方法,添加物品时需要调用ItemGroup.Entries对象的add()方法。当然,也可以使用原始的ItemGroupEvents.modifyEntriesEvent()方法将物品添加到指定物品栏。


在入口点类声明静态常量CUSTOM_ITEM_GROUP,类型为ItemGroup作为物品组对象。使用FabricItemGroup.builder()方法创建继承了ItemGroup.Builder类的FabricItemGroupBuilderImpl对象。

public static final ItemGroup CUSTOM_ITEM_GROUP = FabricItemGroup.builder()
		.icon(() -> new ItemStack(BEST_SWORD))
		.displayName(Text.literal("我的物品"))
		.build();

调用icon()方法设置物品栏图标为“究极神剑”的图标,传递一个Supplier接口函数式,在接口的get方法中返回一个ItemStack对象;调用displayName()方法设置物品栏的名称,传递一个Text类的对象,使用静态方法Text.literal()将字符串转换为Text对象,最后使用build()方法构造ItemGroup对象;

同时,也可以将Supplier接口函数式改写为匿名内部接口,功能与使用函数式相同;

public static final ItemGroup CUSTOM_ITEM_GROUP = FabricItemGroup.builder()
		.icon(new Supplier<ItemStack>() {
			@Override
			public ItemStack get() {
				return new ItemStack(BEST_SWORD);
			}
		})
		.displayName(Text.literal("我的物品"))
		.build();

此外,可以使用entries()方法在物品栏中添加物品;

public static final ItemGroup CUSTOM_ITEM_GROUP = FabricItemGroup.builder()
		.icon(() -> new ItemStack(BEST_SWORD))
		.displayName(Text.literal("我的物品"))
		.entries((displayContext, entries) -> entries.add(ARMOR_SUITE_CHESTPLATE))
		.build();

调用ItemGroup.Entries对象的add()方法将一个物品添加到物品组中,传递一物品对象。也可以在稍后使用ItemGroupEvents.modifyEntriesEvent()方法将物品添加到指定物品栏;

也可以改为匿名内部类new ItemGroup.EntryCollector(){...}的形式;

public static final ItemGroup CUSTOM_ITEM_GROUP = FabricItemGroup.builder()
		.icon(() -> new ItemStack(BEST_SWORD))
		.displayName(Text.literal("我的物品"))
		.entries(new ItemGroup.EntryCollector() {
			@Override
			public void accept(ItemGroup.DisplayContext displayContext, ItemGroup.Entries entries) {
				entries.add(ARMOR_SUITE_CHESTPLATE);
			}
		})
		.build();

创建物品组注册键对象

创建物品组的注册键对象就是要创建类型为RegistryKey<ItemGroup>的对象,因此需要使用Registry.of()方法;

关于Registry.of()方法的详细用法请参考我的世界Java版1.21.4的Fabric模组开发教程(五)创建高级物品:盔甲

在入口点类中声明静态常量CUSTOM_ITEM_GROUP_KEY,类型为RegistryKey<ItemGroup>作为自定义物品组键对象;

public static final RegistryKey<ItemGroup> CUSTOM_ITEM_GROUP_KEY =
			RegistryKey.of(RegistryKeys.ITEM_GROUP, Identifier.of(FabricDocsReference.MOD_ID, "lei_item_group"));

使用RegistryKey.of方法创建物RegistryKey<ItemGroup>对象,传递两个参数,第一个参数为注册键,创建类型为ItemGroup的注册键时固定使用静态常量RegistryKeys.ITEM_GROUP或方法Registries.ITEM_GROUP.getKey(),第二个参数为Identifier对象,即标识符,此处使用模组Id和路径作为标识符,路径为“lei_item_group”;

关于标识符类Identifier的详细用法说明,请参考我的世界Java版1.21.4的Fabric模组开发教程(二)创建物品

在游戏注册表中注册自定义物品组

这里需要使用原生Register.registry()方法注册自定义物品组,而不是之前封装的ModItems.registry()

在入口点类的onIntialize()方法中调用Registry.register()方法;

Registry.register(Registries.ITEM_GROUP,CUSTOM_ITEM_GROUP_KEY,CUSTOM_ITEM_GROUP);

第一个参数传递一个注册键,即要注册物品(方块、实体等)的类型,注册物品组固定的写法为Registries.ITEM_GROUP;第二个参数传递注册键对象,直接使用上一小节创建的静态常量CUSTOM_ITEM_GROUP_KEY;第三个参数传递要注册物品(方块、实体等)的对象,直接使用之前小节创建ItemGroup对象CUSTOM_ITEM_GROUP

关于原生Register.registry()方法的详细用法说明,请参考我的世界Java版1.21.4的Fabric模组开发教程(二)创建物品

将物品添加到自定义物品组中

将自己的物品添加到自定义物品组中可以使用前几个章节中提到的ItemGroupEvents.modifyEntriesEvent()方法,也是作者在本章中采用的方法;

ItemGroupEvents.modifyEntriesEvent(CUSTOM_ITEM_GROUP_KEY)
			.register((itemGroup) -> {
				itemGroup.add(DOG_POO);
				itemGroup.add(TOXIC_APPLE);
				itemGroup.add(BEST_SWORD);
				//...
			});

此时传递的参数是自定义物品组的注册键对象。当然,需要提前声明自定义物品的对象。

此外,也可以使用在之前小节中提到的其他方法,也就是创建ItemGroup对象时,调用ItemGroup.Builder中的entries()方法添加物品到物品组当中。

启动游戏测试

打开游戏,调整游戏模式为“创造模式”,按e键打开创造模式物品栏。
在这里插入图片描述
可以看到自定义物品组的标题、图标和其中的物品;如果没有找到自定义物品组,可以点击右上角的翻页按钮查看下一页物品组。
在这里插入图片描述

本章小结

本章详细阐述了创建自定义物品组的步骤,提供了部分代码解析,内容与前几章节的知识关联性不大,但期间使用到了许多新API,仍需要开发者慢慢学习。感谢各位的阅读,有兴趣可以订阅此专栏!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值