食物 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
中,然后就可以启动游戏进行测试了