我的世界Java版1.21.4的Fabric模组开发教程(三)创建高级物品:食物

这是适用于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.修改游戏模式为生存模式,食用“毒苹果”测试状态效果和饥饿值恢复状况;请添加图片描述
可以看到状态效果和饥饿值恢复均已生效。

本章小结

本章详细阐述了创建自定义食物的流程,部分内容基于上一章的创建物品所编写。实际上,食用食物的自定义行为还有很多,网友们可以参考更多文档来自行探索。感谢各位的阅读,有兴趣可以订阅此专栏!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值