食物 1.21 Fabric
本篇教程的视频
本篇教程的源代码
GitHub地址:TutorialMod-Food-1.21
介绍
食物Food
是Minecraft中的一种物品,可以用来恢复玩家的饥饿值和饱食度
一些食物可以让玩家获得一些效果,正面的亦或是负面的。比如生食直接食用可能导致中毒,让玩家更加饥饿;附魔金苹果可以提供大量正面效果
其具体的内容可在Wiki上查看
查看源代码
食物说白了本质还是物品,只是这种物品可以吃(蛋糕是个例外,它是方块,感兴趣的同学可以自行研究)。我们这里依旧来查阅Items
中的食物注册,以APPLE
为例
物品注册
1 | public static final Item APPLE = register("apple", new Item(new Item.Settings().food(FoodComponents.APPLE))); |
注册什么的我们就不再赘述了,这里主要看后面的food(FoodComponents.APPLE)
,它使用了food
方法,这个方法是Item.Settings
中的一个方法,用于设置食物的属性。
它里面的参数是FoodComponent
,这个类是用于设置食物的属性的,比如饥饿值、饱食度、吃完后的效果等等
所以现在我们来查看FoodComponents
中的APPLE
食物组件
1 | public static final FoodComponent APPLE = new FoodComponent.Builder().nutrition(4).saturationModifier(0.3F).build(); |
这里的方法是链式调用,nutrition
是饥饿值,saturationModifier
是饱食度乘数,build
是构建这个FoodComponent
对象
这里我们来谈谈饥饿值
和饱食度
这两个东西:
饥饿值
是我们在游戏中能看到的那个鸡腿
(HUD),它的最大值是20
饱食度
是我们在游戏中看不到的,不过有模组可以将其显示出来,它的初始值为5,并且其值不能超过目前的饥饿值,在消耗饥饿值之前,它是最先被消耗的
更详细的说明同样可以在Wiki上查看
不过在这里的饱食度
(saturationModifier)是一个乘数,并不是饱食度的具体值,因为这个饱食度是根据一定的算法计算得到的。
1 | public static final FoodComponent GOLDEN_CARROT = new FoodComponent.Builder().nutrition(6).saturationModifier(1.2F).build(); |
如果你看到Wiki上的例子,金胡萝卜(回6点饥饿值,14.4饱和度),但在相关代码中却是这样
回6点饥饿值,这倒是没错;但14.4饱和度,这个值是怎么算出来的呢?
我们可以进一步追溯至HungerConstants
类
1 | public static float calculateSaturation(int nutrition, float saturationModifier) { |
这个方法就是用来计算饱和度的,nutrition
是饥饿值,saturationModifier
是饱食度乘数,这个方法返回的值就是饱食度
而金胡萝卜的饱食度就是6 * 1.2 * 2 = 14.4
,便是这么来的
那么除了简简单单写一个饥饿值和一个饱和度乘数,还有其他的参数可以加
1 | public static final FoodComponent GOLDEN_APPLE = new FoodComponent.Builder() |
比如附魔金苹果,它除了回4
点饥饿值,1.2
倍饱食度乘数外,
还有两个效果,一个是生命恢复REGENERATION
,一个是伤害吸收ABSORPTION
,
这两个效果的参数分别是持续时间
(tick)和等级
,最后一个是alwaysEdible
,
这个方法是用来设置食物是否可以在饥饿值满的时候依旧可以食用
另外,还有像谜之炖菜
、蘑菇煲
等这类带碗
的食物
1 | public static final FoodComponent MUSHROOM_STEW = createStew(6).build(); |
这类食物单独列出来了,因为它们除了要设置饥饿值和饱和度乘数之外,还要把碗
返回回来(毕竟你不能把碗吃了吧?)这里就是用usingConvertsTo
方法来设置的
谜之炖菜
是一个有趣的食物,它的效果根据制作的材料自带的效果来决定的,可能是正面效果,也可能是负面效果,比如后面讲到花
的时候,我们会讲到
编写食物
创建ModFoodComponents类
首先我们创建一个ModFoodComponents
类,用于存放我们的食物属性
1 | public class ModFoodComponents { |
注册食物组件
我们在ModFoodComponents
类中注册我们的食物组件,直接参考FoodComponents
中的写法
1 | public static final FoodComponent CHEESE = new FoodComponent.Builder().nutrition(8).saturationModifier(0.8f).build(); |
这里我们注册了两个食物组件,一个是CHEESE
,一个是STRAWBERRY
,CHEESE
回8
点饥饿值,0.8
倍饱食度乘数,STRAWBERRY
回4
点饥饿值,0.6
倍饱食度乘数,带有抗火保护
效果,持续600
tick,获得几率0.5
这个类可以不写初始化方法,因为这个类的东西是在注册物品的时候还会调用的
注册食物
接下来我们在Items
中注册我们的食物,同样参考Items
中的写法
1 | public static final Item CHEESE = registerItems("cheese", new Item(new Item.Settings().food(ModFoodComponents.CHEESE))); |
这里我们注册了两个食物,一个是CHEESE
,一个是STRAWBERRY
,CHEESE
使用了CHEESE
的食物组件,STRAWBERRY
使用了STRAWBERRY
的食物组件
加入物品栏
1 | entries.add(ModItems.CHEESE); |
这里我们把CHEESE
和STRAWBERRY
加入到物品栏中
语言文件数据生成
1 | translationBuilder.add(ModItems.STRAWBERRY, "Strawberry"); |
模型文件数据生成
1 | itemModelGenerator.register(ModItems.CHEESE, Models.GENERATED); |
这两个物品也是使用GENERATED
模型,和一般物品一样
测试
跑玩数据生成以后,放好对应的材质文件,我们就可以在游戏中看到我们的食物了
在你饥饿值未满的情况下,应该可以正常食用,食用后应该可以回复对应的饥饿值和饱食度,以及获得对应的效果