食物 1.20 Fabric 长线教程计划
本篇教程的视频
本篇教程的源代码
GitHub地址:TutorialMod-Food-1.20.1
本篇教程目标
- 理解原版
食物和食物组件相关注册、方法 - 学会创建
食物组件并为模组加入食物
查看源代码
这期教程我们来写食物,食物在游戏中是一类用来吃的物品(也有方块,如蛋糕)
一些食物不仅仅能为玩家回复饥饿值、饱和度,也还带有一些正面或者负面的效果
这里我们先来看看原版的食物是怎么写的
食物注册
这里我们先到Items类来看看食物相关的注册,这里以APPLE为例
1 | public static final Item APPLE = register("apple", new Item(new Item.Settings().food(FoodComponents.APPLE))); |
前面的不用管它了,我们也见得多了,我们可以看到最后有一个food方法,传入了一个FoodComponents.APPLE,这个就是食物组件
食物组件
接下来我们来看看食物组件是怎么写的
1 | public static final FoodComponent APPLE = new FoodComponent.Builder().hunger(4).saturationModifier(0.3F).build(); |
这里我们看到APPLE这个食物组件FoodComponent的实例化,用Builder来创建食物相关的一些属性
我们看后面几个方法,hunger用来设置食物的饥饿值,saturationModifier用来设置食物的饱和度系数,最后build()用来完成食物组件的创建
饥饿值就是在我们HUD上显示的那些鸡腿,而饱和度在你不加其他模组的情况下是看不见的
不过,在saturationModifier方法中设置的,并不是最终食物回复的饱和度
一路挖到HungerManager类中,我们可以看到饱和度最终的计算公式
1 | this.saturationLevel = Math.min(this.saturationLevel + (float)food * saturationModifier * 2.0F, (float)this.foodLevel); |
可以看到,最终回复的饱和度是食物饥饿值 * 饱和度系数 * 2,然后因为饱和度是不能大于当前的饥饿值,所有是要取它们两个值的最小值的
所以对于APPLE而言,回复的饥饿值是4,饱和度系数是0.3,所以回复的饱和度就是4 * 0.3 * 2 = 2
而金胡萝卜
1 | public static final FoodComponent GOLDEN_CARROT = new FoodComponent.Builder().hunger(6).saturationModifier(1.2F).build(); |
回复的饥饿值是6,饱和度系数是1.2,饱和度呢就来到了14.4
关于饥饿值、饱和度相关的内容可以在Wiki进一步查阅
只是Wiki上并没有写出饱和度具体的计算公式,所以这里就单独提一下
效果及其他的方法
这里我们再来看看其他的方法
1 | public static final FoodComponent ENCHANTED_GOLDEN_APPLE = new FoodComponent.Builder() |
最具代表性的就是附魔金苹果了
可以看到,除了hunger和saturationModifier方法,还有statusEffect方法,这个方法用来设置食物的效果,
传入一个StatusEffectInstance,设置效果、效果持续时间(tick)、效果等级,最后一个参数是效果的触发几率,100%就是1.0F
再一个这里的alwaysEdible()方法,这个方法用来设置食物可以在饥饿值满的情况下继续食用,没有这个方法的食物到玩家饥饿值满的时候就不能再食用了
1 | public static final FoodComponent BEEF = new FoodComponent.Builder().hunger(3).saturationModifier(0.3F).meat().build(); |
再比如这里有个meat方法,这个方法用来设置食物是肉类,也就是可以给你驯服后的狗食用
1 | public static final FoodComponent DRIED_KELP = new FoodComponent.Builder().hunger(1).saturationModifier(0.3F).snack().build(); |
再比如这里有个snack方法,这个方法用来设置食物是小吃,它可以让食物吃得更快
1 | public static final FoodComponent SUSPICIOUS_STEW = createStew(6).alwaysEdible().build(); |
还有就是像蘑菇煲、谜之炖菜这样的各种煲,它们这里有单独的方法,这倒是没什么特殊的
不过在1.21中,它改了一点,你将会发现还有个碗在下面的方法中,因为煲类食物总不能把碗也吃了吧,碗是得留下的
但在1.20中,倒是还没这样,返回空碗的方法是写在它们的类中的
另外,再多说几句,谜之炖菜的具体效果并不是在食物组件中定义的,它是根据合成谜之炖菜时使用的花所带的不同效果,来决定最终谜之炖菜的效果
嗯,花的效果我们将在未来的教程中讲到
那么食物组件大概就这些内容,接下来我们就开始写我们自己的食物
食物注册
创建食物组件
和原版一样,我们先创建一个ModFoodComponents类,用来注册食物组件
1 | public class ModFoodComponents { |
然后我们在里面创建食物组件
1 | public static final FoodComponent CORN = new FoodComponent.Builder().hunger(3).saturationModifier(0.7F).build(); |
这里我们创建CORN、STRAWBERRY、CHEESE三个食物组件,然后定义它们不同的饥饿值、饱和度还有效果
这里类的话,不用像物品、方块注册这样拿主类来调用完成初始化,因为我们待会注册食物物品的时候,还是会用到它们的
食物物品注册
接下来我们在ModItems类中注册食物物品
1 | public static final Item CORN = registerItems("corn", new Item(new Item.Settings().food(ModFoodComponents.CORN))); |
这里我们创建CORN、STRAWBERRY、CHEESE三个食物物品,然后设置它们的食物组件
加入物品栏
别忘了将我们创建的食物加入物品栏
1 | entries.add(ModItems.CORN); |
资源文件
接下来我们搞定它们的各种数据文件
语言文件数据生成
1 | translationBuilder.add(ModItems.CORN, "Corn"); |
食物物品模型数据生成
食物物品的模型和一般的物品一样,父模型也是GENERATED
1 | itemModelGenerator.register(ModItems.CORN, Models.GENERATED); |
那么其他的数据文件之类就不写了,大家可以根据自己的需求来编写
测试
数据生成记得跑一下,然后将贴图文件放到对应的textures中,然后就可以启动游戏进行测试了











