本篇教程的视频
本篇教程的源代码
介绍
在游戏中,有我们常见的盔甲,分别是头盔
、胸甲
、护腿
、靴子
四类盔甲
它们和工具一样,都是物品,不过能为玩家提供一定的护甲值,减少其受到的伤害
除了乌龟壳单独可以作为头盔之外,其他的盔甲都是由基本的五种材质制成的,这个和工具是一样的
在这篇教程中,我们将会制作四种盔甲,分别是头盔
、胸甲
、护腿
、靴子
查看源代码
物品注册
这里我们先看一下Items
类中的DIAMOND_XXX
这类盔甲
1 2 3 4 5 6 7 8 9 10 11 12 13
| public static final Item DIAMOND_HELMET = register( "diamond_helmet", new ArmorItem(ArmorMaterials.DIAMOND, ArmorItem.Type.HELMET, new Item.Settings().maxDamage(ArmorItem.Type.HELMET.getMaxDamage(33))) ); public static final Item DIAMOND_CHESTPLATE = register( "diamond_chestplate", new ArmorItem(ArmorMaterials.DIAMOND, ArmorItem.Type.CHESTPLATE, new Item.Settings().maxDamage(ArmorItem.Type.CHESTPLATE.getMaxDamage(33))) ); public static final Item DIAMOND_LEGGINGS = register( "diamond_leggings", new ArmorItem(ArmorMaterials.DIAMOND, ArmorItem.Type.LEGGINGS, new Item.Settings().maxDamage(ArmorItem.Type.LEGGINGS.getMaxDamage(33))) ); public static final Item DIAMOND_BOOTS = register( "diamond_boots", new ArmorItem(ArmorMaterials.DIAMOND, ArmorItem.Type.BOOTS, new Item.Settings().maxDamage(ArmorItem.Type.BOOTS.getMaxDamage(33))) );
|
我们可以发现它和我们之前制作的工具类似,实例化了各自的盔甲类,也有对应自己的材质
盔甲材质
那么我们废话不多说,先来看一下ArmorMaterials
这个类
1 2 3 4 5 6 7
| public static final RegistryEntry<ArmorMaterial> DIAMOND = register("diamond", Util.make(new EnumMap(ArmorItem.Type.class), map -> { map.put(ArmorItem.Type.BOOTS, 3); map.put(ArmorItem.Type.LEGGINGS, 6); map.put(ArmorItem.Type.CHESTPLATE, 8); map.put(ArmorItem.Type.HELMET, 3); map.put(ArmorItem.Type.BODY, 11); }), 10, SoundEvents.ITEM_ARMOR_EQUIP_DIAMOND, 2.0F, 0.0F, () -> Ingredient.ofItems(Items.DIAMOND));
|
这是其中的DIAMOND
这个材质
(如果你是从1.20.X及其以下版本过来的)
我们还可以发现一点,这个类不再是枚举类
了,而变成了一个普通的类,这里的材质也都变成了注册语句
那么我们现在来看这里的注册语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| private static RegistryEntry<ArmorMaterial> register( String id, EnumMap<ArmorItem.Type, Integer> defense, int enchantability, RegistryEntry<SoundEvent> equipSound, float toughness, float knockbackResistance, Supplier<Ingredient> repairIngredient ) { List<ArmorMaterial.Layer> list = List.of(new ArmorMaterial.Layer(Identifier.ofVanilla(id))); return register(id, defense, enchantability, equipSound, toughness, knockbackResistance, repairIngredient, list); }
private static RegistryEntry<ArmorMaterial> register( String id, EnumMap<ArmorItem.Type, Integer> defense, int enchantability, RegistryEntry<SoundEvent> equipSound, float toughness, float knockbackResistance, Supplier<Ingredient> repairIngredient, List<ArmorMaterial.Layer> layers ) { EnumMap<ArmorItem.Type, Integer> enumMap = new EnumMap(ArmorItem.Type.class);
for (ArmorItem.Type type : ArmorItem.Type.values()) { enumMap.put(type, (Integer)defense.get(type)); }
return Registry.registerReference( Registries.ARMOR_MATERIAL, Identifier.ofVanilla(id), new ArmorMaterial(enumMap, enchantability, equipSound, repairIngredient, layers, toughness, knockbackResistance) ); }
|
这里一共是两个注册方法,前一个是除了皮革
之外的材质的注册,它也调用了后一个注册方法;而后一个注册方法是皮革
直接使用的注册方法,也是我们这里的主要注册方法
其实比较一下,下面的那个注册方法多了一个List<ArmorMaterial.Layer> layers
参数,这个参数是用来指定这个材质的层
的,为什么呢?
我们想一下,皮革材质的这些盔甲是不是可以被染色?翻过盔甲的那些材质文件的同学也可以发现,皮革盔甲的材质是灰白色的,并没有像别的材质那样直接给了颜色
所以皮革的颜色是后期渲染的时候设置的,也可以根据染料的颜色来设置
那么现在我们来看看这里注册方法的参数
String id
,材质的ID
EnumMap<ArmorItem.Type, Integer> defense
,护甲值,这个不是耐久值,而是护甲值,在游戏中也就是显示在生命值上面的那个衣服形状的HUD
int enchantability
,附魔能力,这个和工具的附魔能力是一样的,是指这个物品在附魔台上获得更好、更高级附魔的概率
RegistryEntry<SoundEvent> equipSound
,装备声音,这个是指装备这个盔甲的时候会发出的声音
float toughness
,韧性,这个是指这个盔甲的韧性,也就是抵抗伤害的能力(原版只有钻石和下界合金有)
float knockbackResistance
,击退抗性,这个是指这个盔甲的击退抗性,也就是抵抗击退的能力(原版只有下界合金有)
Supplier<Ingredient> repairIngredient
,修复用材料,这个是指这个盔甲的修复用材料
List<ArmorMaterial.Layer> layers
,层,这个可参考皮革的写法
然后里面的defense
,各个护甲部位的护甲值是不一样的。新版本有一个BODY
,这个是狼铠用的那个护甲值,这里我单独说一下,因为视频里面没讲
注册盔甲
那么现在我们来写我们的盔甲
创建ModArmorMaterials类
1 2 3
| public class ModArmorMaterials { }
|
然后我们把ArmorMaterials
的注册方法搬过来,然后修改一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| private static RegistryEntry<ArmorMaterial> register( String id, EnumMap<ArmorItem.Type, Integer> defense, int enchantability, RegistryEntry<SoundEvent> equipSound, float toughness, float knockbackResistance, Supplier<Ingredient> repairIngredient ) { List<ArmorMaterial.Layer> list = List.of(new ArmorMaterial.Layer(Identifier.of(TutorialMod.MOD_ID, id))); return register(id, defense, enchantability, equipSound, toughness, knockbackResistance, repairIngredient, list); }
private static RegistryEntry<ArmorMaterial> register( String id, EnumMap<ArmorItem.Type, Integer> defense, int enchantability, RegistryEntry<SoundEvent> equipSound, float toughness, float knockbackResistance, Supplier<Ingredient> repairIngredient, List<ArmorMaterial.Layer> layers ) { EnumMap<ArmorItem.Type, Integer> enumMap = new EnumMap(ArmorItem.Type.class);
for (ArmorItem.Type type : ArmorItem.Type.values()) { enumMap.put(type, (Integer)defense.get(type)); }
return Registry.registerReference( Registries.ARMOR_MATERIAL, Identifier.ofVanilla(id), new ArmorMaterial(enumMap, enchantability, equipSound, repairIngredient, layers, toughness, knockbackResistance) ); }
|
一定一定要把Identifier.ofVanilla
改掉!!!
写上我们自己的MOD_ID
然后我们来写我们的盔甲材质
1 2 3 4 5 6 7
| public static final RegistryEntry<ArmorMaterial> ICE_ETHER = register("ice_ether", Util.make(new EnumMap(ArmorItem.Type.class), map -> { map.put(ArmorItem.Type.BOOTS, 3); map.put(ArmorItem.Type.LEGGINGS, 6); map.put(ArmorItem.Type.CHESTPLATE, 8); map.put(ArmorItem.Type.HELMET, 3); map.put(ArmorItem.Type.BODY, 11); }), 15, SoundEvents.ITEM_ARMOR_EQUIP_NETHERITE, 3.0F, 0.1F, () -> Ingredient.ofItems(ModItems.ICE_ETHER));
|
这里我们注册了一个ICE_ETHER
的盔甲材质,这里面的参数按照上面的解释自己写好了,这里我就不再赘述
注册盔甲
然后我们来注册我们的盔甲
1 2 3 4 5 6 7 8
| public static final Item ICE_ETHER_HELMET = registerItems("ice_ether_helmet", new ArmorItem(ModArmorMaterials.ICE_ETHER, ArmorItem.Type.HELMET, new Item.Settings().maxDamage(ArmorItem.Type.HELMET.getMaxDamage(37)))); public static final Item ICE_ETHER_CHESTPLATE = registerItems("ice_ether_chestplate", new ArmorItem(ModArmorMaterials.ICE_ETHER, ArmorItem.Type.CHESTPLATE, new Item.Settings().maxDamage(ArmorItem.Type.CHESTPLATE.getMaxDamage(37)))); public static final Item ICE_ETHER_LEGGINGS = registerItems("ice_ether_leggings", new ArmorItem(ModArmorMaterials.ICE_ETHER, ArmorItem.Type.LEGGINGS, new Item.Settings().maxDamage(ArmorItem.Type.LEGGINGS.getMaxDamage(37)))); public static final Item ICE_ETHER_BOOTS = registerItems("ice_ether_boots", new ArmorItem(ModArmorMaterials.ICE_ETHER, ArmorItem.Type.BOOTS, new Item.Settings().maxDamage(ArmorItem.Type.BOOTS.getMaxDamage(37))));
|
注册的时候用maxDamage
方法来设置最大耐久,这里的数值是一个乘数
,并不是其最大的耐久值
我们跳到ArmorItem.Type.XXX
去看看
1 2 3 4 5
| HELMET(EquipmentSlot.HEAD, 11, "helmet"), CHESTPLATE(EquipmentSlot.CHEST, 16, "chestplate"), LEGGINGS(EquipmentSlot.LEGS, 15, "leggings"), BOOTS(EquipmentSlot.FEET, 13, "boots"), BODY(EquipmentSlot.BODY, 16, "body");
|
这里的几行语句中的数值是baseMaxDamage
,也就是基础的最大耐久值
那么我们最终的耐久值是baseMaxDamage
乘以我们传入的数值,比如以头盔为例,它的baseMaxDamage
是11
,我们传入的数值是37
,那么最终的耐久值就是407
,这个也是下界合金头盔的耐久值
写入物品栏
记得把我们的盔甲写入物品栏
1 2 3 4
| entries.add(ModItems.ICE_ETHER_HELMET); entries.add(ModItems.ICE_ETHER_CHESTPLATE); entries.add(ModItems.ICE_ETHER_LEGGINGS); entries.add(ModItems.ICE_ETHER_BOOTS);
|
这样我们的盔甲就注册完了
数据文件
语言文件
1 2 3 4
| translationBuilder.add(ModItems.ICE_ETHER_HELMET, "Ice Ether Helmet"); translationBuilder.add(ModItems.ICE_ETHER_CHESTPLATE, "Ice Ether Chestplate"); translationBuilder.add(ModItems.ICE_ETHER_LEGGINGS, "Ice Ether Leggings"); translationBuilder.add(ModItems.ICE_ETHER_BOOTS, "Ice Ether Boots");
|
模型文件
盔甲的模型文件是要注意一下的,它们有单独的注册方法,这里的语句也会生成最终三维(也就是穿到身上的)模型文件
1 2 3 4
| itemModelGenerator.registerArmor((ArmorItem) ModItems.ICE_ETHER_HELMET); itemModelGenerator.registerArmor((ArmorItem) ModItems.ICE_ETHER_CHESTPLATE); itemModelGenerator.registerArmor((ArmorItem) ModItems.ICE_ETHER_LEGGINGS); itemModelGenerator.registerArmor((ArmorItem) ModItems.ICE_ETHER_BOOTS);
|
盔甲可以被锻造,而要想让我们的盔甲实现这个功能,我们就得写Tag
1 2
| getOrCreateTagBuilder(ItemTags.TRIMMABLE_ARMOR) .add(ModItems.ICE_ETHER_HELMET, ModItems.ICE_ETHER_CHESTPLATE, ModItems.ICE_ETHER_LEGGINGS, ModItems.ICE_ETHER_BOOTS);
|
随后跑数据生成的时候,我们会发现它生成了一堆文件,毕竟锻造模板挺多的,所以各种各样的花纹也很多
材质文件
这里的材质文件是要注意一下的,它们的材质文件是分开成两个的(上半身和下半身分开的),也是单独在特定的文件夹下的