zh_cn:tutorial:items
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| zh_cn:tutorial:items [2021/01/16 06:26] – [创建物品类] solidblock | zh_cn:tutorial:items [2025/07/22 15:18] (current) – fix typo [注册物品的最佳实践(1.21.2 之前)] solidblock | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== 添加一个物品 ====== | + | ====== 添加物品 ====== |
| - | ==== 介绍 ==== | + | ===== 介绍 ===== |
| + | |||
| + | 添加基本的物品是编写模组的第一步。你将需要创建 '' | ||
| + | ===== 创建物品实例(1.21.2 之前) ===== | ||
| + | :!: 如果是使用的 1.21.2 之后的版本,请直接跳到[[# | ||
| + | |||
| + | 首先,创建 '' | ||
| + | |||
| + | < | ||
| + | public class ExampleMod implements ModInitializer { | ||
| - | 添加一个基本的物品是编写模组的第一步。 你将需要创建一个'' | ||
| - | ==== 注册物品 ==== | ||
| - | 首先,创建一个'' | ||
| - | <code java [enable_line_numbers=" | ||
| - | public class ExampleMod implements ModInitializer | ||
| - | { | ||
| // 新物品的实例 | // 新物品的实例 | ||
| - | public static final Item FABRIC_ITEM | + | |
| + | | ||
| + | // 对于 1.20.5 之后,1.21.2 之前的版本 | ||
| + | public static final class_1792 CUSTOM_ITEM = new class_1792(new class_1792.class_1793()); | ||
| [...] | [...] | ||
| } | } | ||
| - | </code> | + | </yarncode> |
| - | 这里使用原版注册方式来注册,基本语法是'' | + | |
| - | <code java [enable_line_numbers=" | + | ===== 注册物品(1.21.2 之前) ===== |
| - | public class ExampleMod implements ModInitializer | + | |
| - | { | + | 我们创建了基本的物品,但是在 Minecraft 中还不存在,因为还没有注册。在 Minecraft 中,几乎所有东西都有注册表,物品也不例外。 |
| + | |||
| + | 注册新的内容使用原版的注册表,基本语法为 '' | ||
| + | |||
| + | 对于 1.21 之后的版本,'' | ||
| + | |||
| + | <yarncode | ||
| + | public class ExampleMod implements ModInitializer { | ||
| // 新物品的实例 | // 新物品的实例 | ||
| - | public static final Item FABRIC_ITEM | + | public static final class_1792 CUSTOM_ITEM |
| - | + | ||
| @Override | @Override | ||
| - | public void onInitialize() | + | public void onInitialize() { |
| - | | + | |
| - | | + | class_2378.method_10230(class_7923.field_41178, Identifier.of(" |
| - | } | + | } |
| + | </ | ||
| + | |||
| + | 现在新物品已添加到 Minecraft 中,运行“Minecraft Client”运行配置或者 '' | ||
| + | |||
| + | ===== 注册物品的最佳实践(1.21.2 之前) ===== | ||
| + | |||
| + | 在上面的代码中,简直创建了// | ||
| + | |||
| + | 在这个例子中,创建一个 '' | ||
| + | |||
| + | < | ||
| + | public final class TutorialItems { | ||
| + | |||
| + | private TutorialItems() {} | ||
| + | |||
| + | // 新物品的实例 | ||
| + | public static final class_1792 CUSTOM_ITEM = register(" | ||
| + | |||
| + | public static <T extends Item> T register(String path, T item) { | ||
| + | // 对于 1.21 之前的版本,请将 '' | ||
| + | return class_2378.method_10230(class_7923.field_41178, | ||
| + | } | ||
| + | |||
| + | public static void initialize() { | ||
| + | } | ||
| } | } | ||
| + | </ | ||
| + | |||
| + | 记得在模组初始化过程中引用模组的一些方法或字段,从而静态加载 '' | ||
| + | < | ||
| + | public class ExampleMod implements ModInitializer { | ||
| + | @Override | ||
| + | public void onInitialize() { | ||
| + | TutorialItems.initialize(); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | > **注意:**一些有经验的用户也可能会决定使用反射来自动注册一个类的所有静态字段。这也可以,但是请小心使用。 | ||
| + | |||
| + | ===== 在 1.21.2+ 中创建物品 ===== | ||
| + | |||
| + | 从 1.21.2 开始,物品注册重写了。你需要把 '' | ||
| + | |||
| + | < | ||
| + | java.lang.NullPointerException: | ||
| </ | </ | ||
| - | 现在新物品已添加到Minecraft中,运行'' | ||
| - | {{: | + | 要让它正常运行,就要像下面这样写: |
| - | ==== 添加物品材质 ==== | + | <code java> |
| + | public final class TutorialItems { | ||
| + | private TutorialItems() { | ||
| + | } | ||
| - | 为物品注册材质需要物品模型.json文件和材质图像文件。 您将需要将它们添加到资源目录中。每个的直接路径是: | + | public static final Item CUSTOM_ITEM = register(" |
| - | 物品模型: | + | public static Item register(String path, Function<Item.Settings, |
| - | 物品材质: < | + | final RegistryKey< |
| - | 我们将使用[[https:// | + | return Items.register(registryKey, |
| + | } | ||
| + | |||
| + | public static void initialize() { | ||
| + | } | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | 在方法 '' | ||
| + | |||
| + | ===== 添加物品模型、纹理和模型映射 ===== | ||
| + | |||
| + | 如果第一步成功注册了你的物品,就可以成输入命令 ''/ | ||
| + | |||
| + | [Server-Worker-1/WARN]: Unable to load model: 'tutorial: | ||
| + | |||
| + | 这是因为我们还没有给物品提供**纹理**(texture)、**烘焙模型**(baked module,以下简称模型)以及相应的**模型映射**(自 1.21.4 开始)。这些文件分别位于以下位置: | ||
| + | |||
| + | 为物品注册纹理需要物品模型.json文件和纹理图像文件。 您将需要将它们添加到资源目录中。每个的直接路径是: | ||
| - | 如果您在第一步中正确注册了物品,则游戏将以类似于以下方式的方式抱怨缺少材质文件: | + | * 物品模型:'' |
| + | * 物品纹理:'' | ||
| + | * 物品模型映射(自从 1.21.4):'' | ||
| - | | + | 我们将使用[[https://i.imgur.com/CqLSMEQ.png|这个示例纹理]]。 |
| - | 游戏能很方便地告诉你它想要的资源路径。遇事不决,日志解决。 | + | |
| 一个非常简单的物品模型长这个样子: | 一个非常简单的物品模型长这个样子: | ||
| - | < | + | < |
| { | { | ||
| - | " | + | " |
| " | " | ||
| - | " | + | " |
| } | } | ||
| } | } | ||
| </ | </ | ||
| - | 物品模型会将所有属性继承自父模型,例如对工具、方块等物品十分有用的自定义手持模型('' | ||
| - | 最终材质的结果: | + | 你的物品模型的 '' |
| - | {{: | + | 从 1.21.4 开始,还需要物品模型映射(1.21.4 之前不需要),其内容如下: |
| + | <code javascript / | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | | ||
| + | } | ||
| + | </ | ||
| - | ==== 创建物品类 ==== | + | 该物品模型映射将指定物品使用对应的物品模型。 |
| - | 要为物品添加自定义行为,则需要创建一个物品类。其默认的构造方法需要一个Item.Settings对象。 | + | |
| - | <code java [enable_line_numbers=" | + | |
| - | public class FabricItem extends Item { | + | |
| - | | + | > :!: 手动创建这些文件显然会很累。了解数据生成可看看 [[datagen_model]] 页面。 |
| + | |||
| + | |||
| + | ===== 创建物品类 ===== | ||
| + | |||
| + | 要为物品添加自定义行为,则需要创建一个物品类。其默认的构造方法需要一个 '' | ||
| + | |||
| + | < | ||
| + | public | ||
| + | |||
| + | public CustomItem(class_1793 | ||
| super(settings); | super(settings); | ||
| } | } | ||
| } | } | ||
| - | </code> | + | </yarncode> |
| 自定义物品类的一个实际用例是使该物品在右击时播放声音: | 自定义物品类的一个实际用例是使该物品在右击时播放声音: | ||
| - | <code java [enable_line_numbers=" | + | <yarncode |
| - | public class FabricItem | + | public class CustomItem |
| - | public | + | public |
| super(settings); | super(settings); | ||
| } | } | ||
| - | | + | |
| + | // 1.21.2 之前的版本,请这么写: | ||
| @Override | @Override | ||
| - | public | + | public |
| - | | + | |
| - | return | + | return |
| + | } | ||
| + | |||
| + | // 1.21.2 以及之后的版本,请这么写: | ||
| + | @Override | ||
| + | public ActionResult use(World world, PlayerEntity user, Hand hand) { | ||
| + | user.playSound(SoundEvents.BLOCK_WOOL_BREAK, | ||
| + | return ActionResult.SUCCESS; | ||
| } | } | ||
| } | } | ||
| - | </code> | + | </yarncode> |
| - | 用新物品类的实例替换旧的Item对象: | + | 用新物品类的实例替换旧的 |
| - | <code java [enable_line_numbers=" | + | <yarncode |
| public class ExampleMod implements ModInitializer { | public class ExampleMod implements ModInitializer { | ||
| - | | + | |
| - | public static final FabricItem FABRIC_ITEM | + | |
| + | |||
| + | // 对于 1.21.2 之前的版本: | ||
| + | public static final CustomItem CUSTOM_ITEM | ||
| + | // 对于 1.21.2 之后的版本: | ||
| + | public static final CustomItem CUSTOM_ITEM = register(" | ||
| [...] | [...] | ||
| } | } | ||
| - | </code> | + | </yarncode> |
| 如果你正确执行了所有操作,则使用该物品现在应该会播放声音。 | 如果你正确执行了所有操作,则使用该物品现在应该会播放声音。 | ||
| - | ==== 如果我想更改物品的堆叠大小怎么办? | + | ===== 物品组件 |
| + | 有时你会想给物品添加一些默认的物品组件,例如最大堆叠数量或防火。可以通过调用 '' | ||
| - | 使用' | + | 这个例子中,物品默认不可破坏,并隐藏关于这一点的物品提示: |
| - | <code java [enable_line_numbers=" | + | < |
| + | // 对于 1.21.2 之前的版本: | ||
| + | public static final CustomItem CUSTOM_ITEM = register(" | ||
| + | .component(DataComponentTypes.UNBREAKABLE, | ||
| + | |||
| + | // 对于从 1.21.2 及以后、1.21.4 之前的版本: | ||
| + | public static final Item CUSTOM_ITEM = register(" | ||
| + | .component(DataComponentTypes.UNBREAKABLE, | ||
| + | |||
| + | // 对于从 1.21.4 及以后: | ||
| + | public static final Item CUSTOM_ITEM = register(" | ||
| + | .component(DataComponentTypes.UNBREAKABLE, | ||
| + | </ | ||
| + | |||
| + | 特别地,最大堆叠数可使用 '' | ||
| + | |||
| + | <yarncode | ||
| public class ExampleMod implements ModInitializer { | public class ExampleMod implements ModInitializer { | ||
| + | // 我们新物品的实例,最大堆叠数为 16 | ||
| + | | ||
| + | // 对于 1.21.2 之前的版本: | ||
| + | public static final CustomItem CUSTOM_ITEM = register(" | ||
| + | | ||
| + | // 自从 1.21.2 开始: | ||
| + | public static final Item CUSTOM_ITEM = register(" | ||
| + | [...] | ||
| + | } | ||
| + | </ | ||
| - | //我们新物品的实例,最大堆叠大小为16 | + | |
| - | public | + | ===== 让物品能作为燃料或者可堆肥 ===== |
| + | |||
| + | 如果需要让物品能作为燃料在熔炉中燃烧,可以使用 '' | ||
| + | <code java> | ||
| + | public | ||
| [...] | [...] | ||
| + | | ||
| + | // 对于 1.21.2 之前的版本 | ||
| + | @Override | ||
| + | public void onInitialize() { | ||
| + | [...] | ||
| + | FuelRegistry.INSTANCE.add(CUSTOM_ITEM, | ||
| + | } | ||
| } | } | ||
| </ | </ | ||
| - | ==== 下一步 ==== | + | |
| - | 试着[[zh_cn: | + | 然而,在实践中,你可能有许多要注册的物品,注册大量物品可能会耗费精力而且乱,所以可以考虑把代码放到单独的方法中,而不是上面的写法。 |
| + | |||
| + | 在 1.21.2 之前的版本,需要使用 Fabric API 的 '' | ||
| + | <code java> | ||
| + | public final class TutorialItems { | ||
| + | [...] | ||
| + | |||
| + | // 对于 1.21.2 之前的版本 | ||
| + | public static void registerFuels() { | ||
| + | FuelRegistry.INSTANCE.add(CUSTOM_ITEM, | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 而自从 1.21.2 之后,使用的则是 Fabric API 的 '' | ||
| + | <code java> | ||
| + | public final class TutorialItems { | ||
| + | [...] | ||
| + | |||
| + | // 对于 1.21.2 之后的版本 | ||
| + | public static void registerFuels() { | ||
| + | FuelRegistryEvents.BUILD.register((builder, | ||
| + | // 可以一次在这个 lambda 中添加多个物品。 | ||
| + | builder.add(CUSTOM_ITEM, | ||
| + | }); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 然后在你的 '' | ||
| + | <code java> | ||
| + | public class ExampleMod implements ModInitializer { | ||
| + | [...] | ||
| + | |||
| + | @Override | ||
| + | public void onInitialize() { | ||
| + | [...] | ||
| + | TutorialItems.registerFuels(); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 类似地,你也可以使用 '' | ||
| + | ===== 下一步 | ||
| + | 试着[[itemgroup|将你的物品添加到一个物品组中]]。你的物品还没有名字,所以还可以看看[[lang|如何创建语言文件]]。 | ||
zh_cn/tutorial/items.1610778376.txt.gz · Last modified: 2021/01/16 06:26 by solidblock