这是适用于Minecraft Java版1.21.4的Fabric模组开发系列教程专栏第五章——创建高级物品:盔甲。想要阅读其他内容,请查看或订阅上面的专栏。
通常,盔甲的创建流程与常规物品创建流程有两点不同。一是依然需要在自定义物品类中添加自定义行为和属性,二是需要额外添加盔甲穿在身上的展开纹理图,部分文件目录与其他纹理图存放位置有所不同。关于详细的常规物品创建流程,请参考我的世界Java版1.21.4的Fabric模组开发教程(二)创建物品。
在本章,我们将创建“究极盔甲(armor_suite)”系列套装,包含“究极头盔(armor_suite_helmet)”、“究极胸甲(armor_suite_chestplate)”、“究极护腿(armor_suite_leggings)”和“究极靴子(armor_suite_boots)”四件装备。
创建盔甲套装物品类并添加自定义属性
虽然盔甲套装中有头盔、胸甲、护腿和靴子四种装备,但只需要创建一个盔甲类,在注册盔甲时区分创建的装备类型即可。
1.创建com/example/test/item/ModArmorMaterials.java
,使其继承ArmorItem
并实现相关方法;
public class ModArmorMaterials extends ArmorItem {
public ModArmorMaterials(ArmorMaterial material, EquipmentType type, Settings settings) {
super(material, type, settings);
}
@Override
public void appendTooltip(ItemStack stack, TooltipContext context, List<Text> tooltip, TooltipType type) {
tooltip.add(Text.literal("柯威机啊们").formatted(Formatting.DARK_GREEN));
}
}
盔甲套装类需要继承Item
类的子类ArmorItem
。ArmorItem
类的构造方法可以更便捷地配置盔甲套装的一些属性。
盔甲材料记录ArmorMaterial
ArmorMaterial
记录用于定义一套盔甲的公有属性,并创建盔甲材料对象。通常需要使用ArmorMaterial
记录的构造方法;
public ArmorMaterial(int i, Map<EquipmentType, Integer> map, int j, RegistryEntry<SoundEvent> registryEntry,
float f,float g, TagKey<Item> tagKey, RegistryKey<EquipmentAsset> registryKey) {
this.durability = i;
this.defense = map;
this.enchantmentValue = j;
this.equipSound = registryEntry;
this.toughness = f;
this.knockbackResistance = g;
this.repairIngredient = tagKey;
this.assetId = registryKey;
}
其中,提供了详细的盔甲属性配置:
-
int i
:指定基础耐久值。用于计算盔甲各部位实际耐久值。实际耐久值等于:根据不同部位,实际耐久值的计算公式分别为:
头盔 = 基础耐久值 * 11;胸甲 = 基础耐久值 * 16;护腿 = 基础耐久值 * 15;靴子 = 基础耐久值 * 13例如,钻石盔甲的基础耐久值为33,经过计算可知钻石胸甲的实际耐久值为528(33 * 16);
-
Map<EquipmentType, Integer> map
:指定护甲防御值映射。需要传递Map.of(...)
方法返回的映射值。护甲防御值指的是盔甲可以减免的伤害,数值以血量上方白色盔甲图标的数量在游戏中体现,每个盔甲图标代表2点护甲防御值。在Map.of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4)
方法中:k
:指定装备类型。需要传递枚举类EquipmentType
中的枚举常量EquipmentType.HELMET
、EquipmentType.CHESTPLATE
、EquipmentType.LEGGINGS
和EquipmentType.BOOTS
其中之一,分别代表头盔、胸甲、护腿和靴子四种盔甲类型;v
:指定对应装备类型的护甲防御值。确保四种类型的值相加不大于20;
每1点护甲防御值可以减免4%的伤害,最多能减免80%的伤害。根据Minecraft API
ArmorMaterials.java
中的部分代码所示,游戏中钻石盔甲各部位的护甲防御值分别为3、8、6、3;ArmorMaterial DIAMOND = new ArmorMaterial(33, Util.make(new EnumMap(EquipmentType.class), map -> { map.put(EquipmentType.BOOTS, 3); map.put(EquipmentType.LEGGINGS, 6); map.put(EquipmentType.CHESTPLATE, 8); map.put(EquipmentType.HELMET, 3); map.put(EquipmentType.BODY, 11); }), 10, SoundEvents.ITEM_ARMOR_EQUIP_DIAMOND, 2.0F, 0.0F, ItemTags.REPAIRS_DIAMOND_ARMOR, EquipmentAssetKeys.DIAMOND);
所以,当玩家穿戴全套钻石盔甲时,可以减免的伤害为80%((3+8+6+3)*4),成为了游戏中护甲防御值最高的盔甲套装。当然,由于源代码直接硬编码了盔甲属性值,其中使用了其他API,与自定义盔甲类中使用构造方法构造
ArmorMaterial
对象相比,其中部分参数传递的写法不太相同; -
int j
:指定附魔权重。确定了使用附魔台给盔甲附魔时,出现高等级的附魔条目的概率; -
RegistryEntry<SoundEvent> registryEntry
:指定穿戴音效。需要传递一个声音事件类型的注册表项,一般使用SoundEvents
类中提供的部分静态常量; -
float f
:指定坚硬度。确定了盔甲会吸收多少伤害。 数字越高,盔甲吸收的伤害越多。例如,钻石盔甲的坚硬度为2.0; -
float g
:指定击退抗性。确定了玩家被攻击时可以吸收多少击退值。数值越大,玩家被攻击时击退的距离就越小。取值范围在0.0-1.0之间,例如,1.0代表完全免疫击退; -
TagKey<Item> tagKey
:指定修复材料。确定了使用铁砧修复盔甲时使用的材料。传递一个物品标签,一般使用ItemTags
类中提供的部分静态常量; -
RegistryKey<EquipmentAsset> registryKey
:指定盔甲资源ID注册键,是一个重要参数。用于定位盔甲的纹理和模型系列文件。与物品标识符类似,需要指定一个字符串作为资源文件名前缀。
盔甲资源ID注册键对象
盔甲资源ID注册键用于管理和定位盔甲的纹理、展开图和模型等资源,类型为RegistryKey<EquipmentAsset>
,因此创建RegistryKey<EquipmentAsset>
对象需要使用Registery.of()
方法;
public static <T> RegistryKey<T> of(RegistryKey<? extends Registry<T>> registry, Identifier value) {
return of(registry.value, value);
}
其中传递两个参数:
RegistryKey<? extends Registry<T>> registry
:指定注册表键。此处应固定地采用最新写法EquipmentAssetKeys.REGISTRY_KEY
;Identifier value
:指定注册表值。传递一个Identifier
对象,即标识符,应当使用模组Id和路径的组合。关于Identifier
类的详细用法说明请参考我的世界Java版1.21.4的Fabric模组开发教程(二)创建物品。
盔甲资源ID注册键对象需要在ArmorMaterial
类的构造方法中使用。
2.声明静态常量ARMOR_ASSET_KEY
作为盔甲资源ID注册键对象,类型为RegistryKey<EquipmentAsset>
;
public static final RegistryKey<EquipmentAsset> ARMOR_ASSET_KEY =
RegistryKey.of(EquipmentAssetKeys.REGISTRY_KEY, Identifier.of(FabricDocsReference.MOD_ID, "armor_suite"));
使用RegistryKey.of
方法创建注册键对象,第一个参数固定传递EquipmentAssetKeys.REGISTRY_KEY
,代表注册表键;第二个参数使用Identifier.of
方法返回一个Identifier
对象,使用模组Id和自定义路径构造标识符,此处设置的自定义路径为“armor_suite”;
3.声明静态常量ARMOR_SUITE_MATERIAL
用于设置盔甲属性并创建盔甲材料对象,类型为RegistryKey<EquipmentAsset>
;
public static final ArmorMaterial ARMOR_SUITE_MATERIAL = new ArmorMaterial(
25,Map.of(
EquipmentType.HELMET,3,
EquipmentType.CHESTPLATE,8,
EquipmentType.LEGGINGS,6,
EquipmentType.BOOTS,3
),12,SoundEvents.ITEM_ARMOR_EQUIP_DIAMOND,2.5F,0.5F,ItemTags.REPAIRS_IRON_ARMOR,ARMOR_ASSET_KEY
);
构造方法中的参数按照先后顺序分别配置了基础耐久值为25、四种盔甲类型的护甲防御值映射、附魔权重为12、穿戴声音为SoundEvents.ITEM_ARMOR_EQUIP_DIAMOND
(钻石盔甲穿戴的声音)、盔甲坚硬度为2.5、击退抗性为0.5、修复材料为ItemTags.REPAIRS_IRON_ARMOR
(铁锭)以及盔甲资源ID注册键对象。
创建盔甲纹理文件、模型文件和模型描述文件
首先,我们需要创建头盔、胸甲、护腿和靴子四种盔甲在物品栏中的纹理图。
1.在assets/test/textures
分别创建armor_suite_helmet.png
、armor_suite_chestplate.png
、armor_suite_leggings.png
和armor_suite_boots.png
,代表头盔、胸甲、护腿和靴子四种盔甲的纹理图。此处的图片名称是最后在入口点注册四种盔甲时使用的路径;
例如,头盔纹理文件的名为armor_suite_helmet.png
,由路径armor_suite
+盔甲部位名helmet
+文件扩展名.png
组成;
2.模型文件和模型描述文件的创建与常规物品的创建方式相同;
- 在
assets/test/models/item
目录中分别分别创建armor_suite_helmet.json
、armor_suite_chestplate.json
、armor_suite_leggings.json
和armor_suite_boots.json
,代表四种盔甲的模型文件;armor_suite_helmet.json
{ "parent": "minecraft:item/generated", "textures": { "layer0": "test:item/armor_suite_helmet" } }
armor_suite_chestplate.json
{ "parent": "minecraft:item/generated", "textures": { "layer0": "test:item/armor_suite_chestplate" } }
armor_suite_leggings.json
{ "parent": "minecraft:item/generated", "textures": { "layer0": "test:item/armor_suite_leggings" } }
armor_suite_boots.json
{ "parent": "minecraft:item/generated", "textures": { "layer0": "test:item/armor_suite_boots" } }
- 在
assets/test/items
目录中分别分别创建armor_suite_helmet.json
、armor_suite_chestplate.json
、armor_suite_leggings.json
和armor_suite_boots.json
,代表四种盔甲的模型描述文件;armor_suite_helmet.json
{ "model": { "type": "minecraft:model", "model": "test:item/armor_suite_helmet" } }
armor_suite_chestplate.json
{ "model": { "type": "minecraft:model", "model": "test:item/armor_suite_chestplate" } }
armor_suite_leggings.json
{ "model": { "type": "minecraft:model", "model": "test:item/armor_suite_leggings" } }
armor_suite_boots.json
{ "model": { "type": "minecraft:model", "model": "test:item/armor_suite_boots" } }
创建盔甲的展开纹理图
与常规物品不同的是,盔甲装备需要单独创建一套纹理图,供玩家穿戴盔甲时在游戏中显示。
展开纹理图的文件类型与其他图片无异,均为.png文件,但其文件大小要比其他资源图片大,且看起来显得杂乱无章;
在Fabric模组开发中,展开纹理图被拆分成两张图片。一张是头盔和胸甲的展开图,另外一张则是护腿和靴子的展开图。例如,下面这张图是头盔和胸甲的展开图,其中包含头盔和胸甲的正面、后面、左面、右面和上面(不含胸甲)的平面图;
下面这张图是护腿和靴子的展开图,其中包含护腿和靴子的正面、后面、左面和右面的平面图;
此外,展开纹理图的存放位置也比较特殊,且还需要一个JSON配置文件来定位展开纹理图的位置;
1.在assets/test/textures
目录中创建“entity/equipment”目录,在其中创建两个文件夹humanoid
和humanoid_leggings
,humanoid
文件夹中存放头盔和胸甲的展开图;humanoid_leggings
文件夹中存放护腿和靴子的展开图,将两个展开图分别移动到对应文件夹中。
虽然是不同部位的展开图,但是文件名是相同的,为盔甲资源Id中配置的路径;
2.在assets/test
目录中创建equipment
文件夹,用于存放定位展开纹理图的JSON配置文件。同样地,文件名为盔甲资源Id中配置的路径;
展开纹理图配置文件的写法应当为:
{
"layers": {
"humanoid": [
{
"texture": "test:armor_suite"
}
],
"humanoid_leggings": [
{
"texture": "test:armor_suite"
}
]
}
}
layers
配置项中添加两个字段humanoid
和humanoid_leggings
,代表assets/test/textures/entity/equipment
目录中两个文件夹的名字,然后在两个字段中配置纹理图文件名为盔甲资源Id的标识符test:armor_suite
。
在语言文件中为盔甲提供翻译键值对
这里要给四种盔甲分别添加翻译键值对,此处翻译键最后的路径是下一小节在入口点类注册时使用的路径。
打开zh-cn.json
,添加四个翻译键值对;
{
...
"item.test.armor_suite_helmet": "究极头盔",
"item.test.armor_suite_chestplate": "究极胸甲",
"item.test.armor_suite_leggings": "究极护腿",
"item.test.armor_suite_boots": "究极靴子"
}
在游戏注册表中注册盔甲套装并将其添加到物品组中
所有纹理图、配置文件和自定义盔甲类都已经编写完毕,可以开始在注册表中注册盔甲了。
1.首先,使用ModItems.register()
方法分别注册四种盔甲。在入口点类声明静态常量ARMOR_SUITE_HELMET
、ARMOR_SUITE_CHESTPLATE
、ARMOR_SUITE_LEGGIINGS
和ARMOR_SUITE_BOOTS
,分别代表“究极头盔”、“究极胸甲”、“究极护腿”和“究极靴子”;
public static final ArmorItem ARMOR_SUITE_HELMET = (ArmorItem) ModItems.register("armor_suite_helmet",
settings -> new ModArmorMaterials(ModArmorMaterials.ARMOR_SUITE_MATERIAL,
EquipmentType.HELMET,
settings),
new Item.Settings());
public static final ArmorItem ARMOR_SUITE_CHESTPLATE = (ArmorItem) ModItems.register("armor_suite_chestplate",
settings -> new ModArmorMaterials(ModArmorMaterials.ARMOR_SUITE_MATERIAL,
EquipmentType.CHESTPLATE,
settings),
new Item.Settings());
public static final ArmorItem ARMOR_SUITE_LEGGINGS = (ArmorItem) ModItems.register("armor_suite_leggings",
settings -> new ModArmorMaterials(ModArmorMaterials.ARMOR_SUITE_MATERIAL,
EquipmentType.LEGGINGS,
settings),
new Item.Settings());
public static final ArmorItem ARMOR_SUITE_BOOTS = (ArmorItem) ModItems.register("armor_suite_boots",
settings -> new ModArmorMaterials(ModArmorMaterials.ARMOR_SUITE_MATERIAL,
EquipmentType.BOOTS,
settings),
new Item.Settings());
此处需要强制类型转换。在第二个参数使用自定义盔甲类ModArmorMaterials
的构造方法和默认配置对象的函数式,传递ModArmorMaterials
对象以及枚举类EquipmentType
中的枚举常量EquipmentType.HELMET
、EquipmentType.CHESTPLATE
、EquipmentType.LEGGINGS
和EquipmentType.BOOTS
分别设置盔甲类型;
2.在入口点类的onInitialize()
方法中,将四种盔甲添加到“战斗用品”物品组中;
ItemGroupEvents.modifyEntriesEvent(ItemGroups.COMBAT).register(entries -> entries.add(ARMOR_SUITE_HELMET));
ItemGroupEvents.modifyEntriesEvent(ItemGroups.COMBAT).register(entries -> entries.add(ARMOR_SUITE_CHESTPLATE));
ItemGroupEvents.modifyEntriesEvent(ItemGroups.COMBAT).register(entries -> entries.add(ARMOR_SUITE_LEGGINGS));
ItemGroupEvents.modifyEntriesEvent(ItemGroups.COMBAT).register(entries -> entries.add(ARMOR_SUITE_BOOTS));
启动游戏测试
1.打开物品栏,找到“战斗物品组”最后的“究极盔甲套装”;
相关配置显示正确;
2.穿戴所有盔甲,切换视角查看纹理图;
各部位的纹理正常显示,护甲防御值为满格。如果穿戴盔甲后不显示,说明某些配置没有完成或者出现错误;
本章小结
本章详细阐述了在游戏中添加自定义盔甲的具体流程,和创建常规自定义物品的流程有一定出入,难度较大,需要配置的内容较多,和前几章节相比,本章篇幅也更大,学习时需要开发者有一定耐心。感谢各位的阅读,有兴趣可以订阅此专栏!