概述
本部分以制作一个红石苹果为例,讲述如何做出一个新的食物,并设置其食用后的效果。
制作一个崭新的食物
在包com.github.ustc_zzzz.fmltutor.item下新建一个文件ItemRedstoneApple.java,并让ItemRedstoneApple类继承ItemFood类:
src/main/java/com/github/ustc_zzzz/fmltutor/item/ItemRedstoneApple.java:
package com.github.ustc_zzzz.fmltutor.item;
import net.minecraft.item.ItemFood;
import com.github.ustc_zzzz.fmltutor.creativetab.CreativeTabsLoader;
public class ItemRedstoneApple extends ItemFood
{
    public ItemRedstoneApple()
    {
        super(4, 0.6F, false);
        this.setAlwaysEdible();
        this.setUnlocalizedName("redstoneApple");
        this.setCreativeTab(CreativeTabsLoader.tabFMLTutor);
    }
}
ItemFood类的构造方法一共有三个参数:
- 第一个参数amount表示该食物所能回复的饥饿值,这里被设定成和苹果相同,即4。
- 第二个参数saturation表示该食物所能添加的相对饱和度,其正比于饱和度和饥饿值的比值,这里设定为0.6F。
- 最后一个参数isWolfFood表示该食物能否被狼食用,这里简单地设置为false就可以了。
饱和度的计算:2 * amount * saturation。如面包的amount为5,其saturation为0.6F,对应的饱和度为2  5  0.6 = 6
为了方便读者,我们在这里列了一个常见食物对应的amount和saturation表。
| 食物 | amount | saturation | 
|---|---|---|
| 苹果 | 4 | 0.3F | 
| 面包 | 5 | 0.6F | 
| 生猪排 | 3 | 0.3F | 
| 熟猪排 | 8 | 0.8F | 
| 曲奇 | 2 | 0.1F | 
| 西瓜片 | 2 | 0.3F | 
| 生牛肉 | 3 | 0.3F | 
| 牛排 | 8 | 0.8F | 
| 生鸡肉 | 2 | 0.3F | 
| 熟鸡肉 | 6 | 0.6F | 
| 腐肉 | 4 | 0.1F | 
| 蜘蛛眼 | 2 | 0.8F | 
| 烤马铃薯 | 5 | 0.6F | 
| 毒马铃薯 | 2 | 0.3F | 
| 金萝卜 | 6 | 1.2F | 
| 南瓜派 | 8 | 0.3F | 
方法setAlwaysEdible表示该食物何时何地都可以被食用,即便玩家不需要回复饥饿度和饱和值。
下面就是一些例行公事了(模型、贴图、语言文件、以及注册)(贴图同为金苹果调色=_=||):
src/main/resources/assets/fmltutor/models/item/redstone_apple.json:
{
    "parent": "builtin/generated",
    "textures": {
        "layer0": "fmltutor:items/redstone_apple"
    },
    "display": {
        "thirdperson": {
            "rotation": [ 0, 90, -35 ],
            "translation": [ 0, 1.25, -3.5 ],
            "scale": [ 0.85, 0.85, 0.85 ]
        },
        "firstperson": {
            "rotation": [ 0, -135, 25 ],
            "translation": [ 0, 4, 2 ],
            "scale": [ 1.7, 1.7, 1.7 ]
        }
    }
}
src/main/resources/assets/fmltutor/textures/items/redstone_apple.png:

src/main/resources/assets/fmltutor/lang/en_US.lang(部分):
item.redstoneApple.name=Redstone Apple
src/main/resources/assets/fmltutor/lang/zh_CN.lang(部分):
item.redstoneApple.name=红石苹果
src/main/java/com/github/ustc_zzzz/fmltutor/item/ItemLoader.java(部分):
    public static Item goldenEgg = new ItemGoldenEgg();
    public static ItemPickaxe redstonePickaxe = new ItemRedstonePickaxe();
    public static ItemFood redstoneApple = new ItemRedstoneApple();
    public ItemLoader(FMLPreInitializationEvent event)
    {
        register(goldenEgg, "golden_egg");
        register(redstonePickaxe, "redstone_pickaxe");
        register(redstoneApple, "redstone_apple");
    }
    @SideOnly(Side.CLIENT)
    public static void registerRenders()
    {
        registerRender(goldenEgg);
        registerRender(redstonePickaxe);
        registerRender(redstoneApple);
    }
当然我们也可以加上合成表:
src/main/java/com/github/ustc_zzzz/fmltutor/crafting/CraftingLoader.java(部分):
        GameRegistry.addShapedRecipe(new ItemStack(ItemLoader.redstoneApple), new Object[]
        {
                "###", "#*#", "###", '#', Items.redstone, '*', Items.apple
        });
打开游戏试试吧~
为食物添加食用后的药水效果
实际上,ItemFood类本身就预置了药水效果的轮子,我们在构造函数中加上这么一句:
src/main/java/com/github/ustc_zzzz/fmltutor/item/ItemRedstoneApple.java(部分):
        this.setPotionEffect(Potion.absorption.id, 10, 1, 1.0F);
setPotionEffect方法共有四个参数:
- 第一个参数表示对应药水效果的potionId,读者可以去net.minecraft.potion.Potion类中查看MC提供的二十四种药水效果,这里为伤害吸收。
- 第二个参数表示对应药水效果的持续时间,以秒计数,这里为十秒。
- 第三个参数表示对应药水效果的等级,很明显,0为一级,1为二级,2为三级,以此类推,这里为二级。
- 最后一个参数表示产生该药水效果的概率,这里为100%。
到这里我们就完成了对于添加食用食物后的药水效果的设置,这对大部分的食物设定来说,是够用了的。事实上,MC游戏本身的大部分食物,它们食用后的药水效果(如食用腐肉后产生的饥饿效果,食用蜘蛛眼后产生的中毒效果)都是这么设定的。
为食物添加食用后的更多效果
当然,总有例外,例如食用河豚或金苹果后产生的多种药水效果,就不能通过上面的方法完成。
ItemFood类提供了一个方法onFoodEaten,我们可以把它覆写掉:
src/main/java/com/github/ustc_zzzz/fmltutor/item/ItemRedstoneApple.java(部分):
    @Override
    public void onFoodEaten(ItemStack stack, World worldIn, EntityPlayer player)
    {
        if (!worldIn.isRemote)
        {
            player.addPotionEffect(new PotionEffect(Potion.saturation.id, 200, 1));
            player.addExperience(10);
        }
        super.onFoodEaten(stack, worldIn, player);
    }
这段代码的意思可能已经比较明显了:除了伤害吸收二,食用该食物还会给玩家带来十秒的饱和二效果,和十点经验。这里有一点不同的地方,就是PotionEffect的构造函数使用的时间是以gametick计数的。
打开游戏试试吧~