这是适用于Minecraft Java版1.21.4的Fabric模组开发系列教程专栏第三章——创建高级物品:食物。想要阅读其他内容,请查看或订阅上面的专栏。
总的来说,创建食物和创建物品的流程基本相同,唯一不同的是需要在食物的物品类中定义一些特有的行为和属性,并在注册物品时将这些内容应用。阅读本章内容前,需要有常规物品创建流程的知识基础,物品创建的常规流程会在本章中简化,详细的物品创建过程请参考我的世界Java版1.21.4的Fabric模组开发教程(二)创建物品。
在本章,我们将创建一个自定义食物——毒苹果(toxic_apple),使其可以食用,食用后恢复6点饥饿值并给予玩家中毒II效果。
创建食物的物品类
创建过程与常规物品类完全相同。
1.在com.example.test.item
目录中创建ToxicApple.java
;
2.使其继承Item
类,并重写appendTooltip()
方法,为其添加工具提示;
public class ToxicApple extends Item {
public ToxicApple(Settings settings) {
super(settings);
}
@Override
public void appendTooltip(ItemStack stack, TooltipContext context, List<Text> tooltip, TooltipType type) {
tooltip.add(Text.literal("吃完小心鼠掉哦!").formatted(Formatting.DARK_GREEN));
}
}
暂时不将其注册到注册表中。
为食物添加纹理、模型文件和模型描述文件
创建过程与常规物品完全相同。
- 寻找大小为16*16的纹理文件,并将其添加到
assets/test/textures/item
路径中,命名为toxic_apple.png
; - 创建模型描述文件
assets/test/items/toxic_apple.json
;{ "model":{ "type": "minecraft:model", "model": "test:item/toxic_apple" } }
- 创建模型文件
assets/test/models/item/toxic_apple.json
;{ "parent": "minecraft:item/generated", "textures": { "layer0": "test:item/toxic_apple" } }
完成后,项目结构应该如下图;
在语言文件中为食物添加翻译键值对
打开assets/test/lang/zh_cn.json
,在文件最后添加一条翻译键值对;
{
...
"item.test.toxic_apple":"毒苹果"
}
将标识符test:toxic_apple
翻译为“毒苹果”。
为食物添加属性和状态效果
现在,我们可以开始为食物添加可以食用、恢复6点饥饿值的属性和食用后的中毒效果。在开始前,可以了解一下相关API。
食物属性构造器内部类FoodComponent.Builder
FoodComponent.Builder
在记录FoodComponent
内部声明,用于为食物添加属性,其对象是创建食物时必须传递的参数。在这个内部类中有很多方法可以使用,所有方法都支持链式编程;
nutrition()
:指定食物恢复的饥饿值。传递一个整型(int)数据,1个🍗=2点饥饿值;saturationModifier()
:指定食物恢复的饱和度系数。传递一个浮点型(float)数据。在游戏中,经过计算后的饱和度优先于饥饿值消耗,决定了吃下食物后能够维持当前饥饿值的时间。在游戏中,这个值是不可见的;-
例如,根据Minecraft API的
FoodComponents
类中声明的“金胡萝卜”静态常量,确定了其在游戏中恢复的饥饿值和饱食度;public static final FoodComponent GOLDEN_CARROT = new FoodComponent.Builder() .nutrition(6) .saturationModifier(1.2F) .build()
可以看到,“金胡萝卜”恢复6点饥饿值(3个🍗);而恢复的饱和度为:
计算公式:饱和度 = 饥饿值 * 饱和度系数 * 2
计算可得恢复的饱和度为6 * 1.2 * 2 = 16.6,这使“金胡萝卜”成为了游戏中恢复饱和度最高的食物。与饥饿值相同,饱和度最大值为20;
-
alwaysEdible()
:指定当前食物能否在饥饿值满时食用。传递一个布尔值(boolean);build()
:用于构造FoodComponent
对象,必须在链式编程结尾调用。
可消耗物品属性记录ConsumableComponent
ConsumableComponent
记录用于定义玩家消耗物品时的交互效果,不仅仅是食物,它还可以配置玩家消耗药水、卷轴和其他物品时的高级行为。对于配置食物食用的自定义状态效果,ConsumableComponent
记录为其提供了终极解决方案。
要创建ConsumableComponent
对象为食物添加自定义状态效果,一般使用ConsumableComponents.food()
方法配置食物的基本属性;
public static ConsumableComponent.Builder food() {
return ConsumableComponent.builder().consumeSeconds(1.6F).useAction(UseAction.EAT).sound(SoundEvents.ENTITY_GENERIC_EAT).consumeParticles(true);
}
food()
方法的方法体中配置了物品的食用时长(consumeSeconds)、用户行为(useAction)、食用声音(sound)和食用时是否出现粒子效果(consumeParticles),间接地使一个物品成为了食物。这个方法返回了与食物属性构造器内部类FoodComponent.Builder
相似的内部类ConsumableComponent.Builder
的对象,是ConsumableComponent
对象的构造器;
ConsumableComponent.Builder
内部类也提供了许多方法,同样地,这些方法均支持链式编程。要设置状态效果,通常需要调用consumeEffect()
方法;
public ConsumableComponent.Builder consumeEffect(ConsumeEffect consumeEffect) {...}
方法传递了一个ConsumeEffect
接口,我们一般使用它的实现记录ApplyEffectsConsumeEffect
来创建其对象。
物品消耗状态效果应用记录ApplyEffectsConsumeEffect
ApplyEffectsConsumeEffect
记录实现了ConsumeEffect
接口,用于在消耗(食用)自定义物品(食物)时,为玩家应用指定的状态效果。要创建ConsumeEffect
对象,需要使用ApplyEffectsConsumeEffect
记录中的构造方法;
public ApplyEffectsConsumeEffect(StatusEffectInstance effect, float probability) {
this(List.of(effect), probability);
}
其中的参数包括:
StatusEffectInstance effect
:状态效果实例对象;float probability
:消耗物品(食物)触发状态效果的概率。取值范围在0.0-1.0之间,例如,0.7代表概率为70%。
状态效果实例类StatusEffectInstance
StatusEffectInstance
用于创建状态效果并设置其具体表现和行为,此小节内容是设置食物食用触发状态效果的核心代码片段。创建自定义状态效果,可以使用StatusEffectInstance
类的构造方法;
在StatusEffectInstance
类中有许多构造方法,构造方法中提供的参数越多,配置的状态效果就越详细;
public StatusEffectInstance(RegistryEntry<StatusEffect> effect, int duration, int amplifier) {
this(effect, duration, amplifier, false, true);
}
这里使用带有三个参数的构造方法即可,其中:
RegistryEntry<StatusEffect> effect
:指定状态效果注册键。值可以为StatusEffects.POISON
(中毒)、StatusEffects.WITHER
(凋零)或StatusEffects.INVISIBILITY(隐身)
等效果。更多效果请参考StatusEffects.java
;int duration
:指定状态效果持续时间。传递一个整型(int)数据,单位:游戏刻,1秒=20游戏刻。例如,5秒=100(5*20)游戏刻;int amplifier
:指定效果等级。传递一个整型(int)数据,等级越高,效果越强烈。级别从0开始,即0=I级。
1.打开ToxicApple.java
,在构造方法前声明静态常量TOXIC_APPLE_COMPONENT
,类型为FoodComponent
。使用食物属性构造器内部类FoodComponent.Builder
中的方法对其初始化;
public static final FoodComponent TOXIC_APPLE_COMPONENT = new FoodComponent.Builder()
.alwaysEdible()
.nutrition(6)
.saturationModifier(0.3f)
.build();
调用alwaysEdible()
方法设置食物可以在饥饿值满的情况下食用;调用nutrition()
方法设置食物恢复的饥饿值为6;调用saturationModifier()
方法设置食物的饱和度系数0.3,最后调用build()
方法构造对象。
2.此外还需要声明静态常量TOXIC_APPLE_CONSUMABLE_COMPONENT
,类型为ConsumableComponent
。使用ConsumableComponents.food()
返回的ConsumableComponent.Builder
构造器提供的方法对其初始化;
public static final ConsumableComponent TOXIC_APPLE_CONSUMABLE_COMPONENT =
ConsumableComponents.food()
.consumeEffect(
new ApplyEffectsConsumeEffect(
new StatusEffectInstance(StatusEffects.POISON, 6 * 20, 1), 1.0f))
.build();
首先使用ConsumableComponents.food()
方法返回ConsumableComponent.Builder
构造器,然后使用构造器的consumeEffect
方法设置物品(食物)消耗的状态效果。
构造方法中传递一个物品消耗状态效果应用记录ApplyEffectsConsumeEffect
对象,再使用ApplyEffectsConsumeEffect
记录的构造方法构造其对象,其中传递两个参数,第一个参数传递一个StatusEffectInstance
对象,用于设置具体的状态效果;第二个参数传递的值为1.0f,代表100%触发状态效果。
在第一个参数中,还需要使用StatusEffectInstance
类的构造方法构造一个状态效果对象。其中的几个参数按顺序分别设置了状态效果为中毒StatusEffects.POISON
、持续时间为6秒和效果等级为II。最后使用构造器的build()
方法构造ConsumableComponent
对象。
在游戏注册表中注册食物并将其添加到物品栏中
现在,可以使用ModItems.register()方法在注册表中注册食物物品,并应用相关自定义属性。
1.打开入口点类,在onInitialize()
方法前声明TOXIC_APPLE
为静态常量;
public static final Item TOXIC_APPLE = ModItems.register("toxic_apple"
, ToxicApple::new
,new Item.Settings().food(ToxicApple.TOXIC_APPLE_COMPONENT,ToxicApple.TOXIC_APPLE_CONSUMABLE_COMPONENT));
与常规物品不同的是,需要使用Item.Settings()
的food()
方法为食物添加自定义行为,其中传递两个参数;
public Settings food(FoodComponent foodComponent, ConsumableComponent consumableComponent) {...}
FoodComponent foodComponent
:食物属性对象;ConsumableComponent consumableComponent
:可消耗物品属性记录对象;
两个对象均已在ToxicApple.java
中声明,此处可以直接传递。此外,food()
方法在Item.Settings()
内部类中多个方法重载,如果不想设置任何状态效果,可以使用其他参数不同的food()
方法。例如,可以直接传递一个FoodComponent
对象,然后配置食物恢复的饥饿值和饱和度即可。详情请参考Item.java
。
2.在onInitialize()
方法中,将“毒苹果”添加到“食物与饮品”物品组中;
ItemGroupEvents.modifyEntriesEvent(ItemGroups.FOOD_AND_DRINK).register(entries -> entries.add(TOXIC_APPLE));
此处使用的物品组注册键为ItemGroups.FOOD_AND_DRINK
。
启动游戏测试
1.打开游戏测试“毒苹果”所在物品组。
可以看到“毒苹果”在“食物与饮品”物品组结尾。
2.修改游戏模式为生存模式,食用“毒苹果”测试状态效果和饥饿值恢复状况;
可以看到状态效果和饥饿值恢复均已生效。
本章小结
本章详细阐述了创建自定义食物的流程,部分内容基于上一章的创建物品所编写。实际上,食用食物的自定义行为还有很多,网友们可以参考更多文档来自行探索。感谢各位的阅读,有兴趣可以订阅此专栏!