User Tools

Site Tools


zh_cn:tutorial:items

添加物品

介绍

添加一个基本的物品是编写模组的第一步。你将需要创建一个 Item 对象,注册,并提供一个纹理。要向物品添加其他行为,你将需要一个自定义的 Item 类。在本教程以及以后的所有教程中,均使用 tutorial 作为命名空间。如果你有单独的模组 ID,那就直接使用它。

注册物品

首先,创建一个 Item 的实例,存储为静态常量字段。Item 的构造方法接受一个 Item.Settings(或 FabricItemSettings,除非是 1.20.5 以上版本)对象,该对象用于设置物品属性,例如耐久和堆叠数量。

  1. public class ExampleMod implements ModInitializer {
  2.  
  3. // 新物品的实例
  4. // 对于 1.20.4 以下版本
  5. public static final Item CUSTOM_ITEM = new Item(new FabricItemSettings());
  6. // 对于 1.20.5 之后的版本
  7. public static final Item CUSTOM_ITEM = new Item(new Item.Settings());
  8. [...]
  9. }

注册物品

我们创建了基本的物品,但是在 Minecraft 中还不存在,因为还没有注册。在 Minecraft 中,几乎所有东西都有注册表,物品也不例外。

注册新的内容使用原版的注册表,基本语法为 Registry.register(注册表类型, Identifier, 内容)。注册表类型存储为 RegistriesRegistry 类的静态字体中,ID(identifier)则是标注你的内容的。内容是你添加的东西的实例。对于物品而言,语法就是 Registry#register(Registries.ITEM, Identifier, Item)。可以在初始化过程的任何地方调用它,方法本身会返回物品的实例。

对于 1.21 之后的版本,Identifier 是通过 Identifier.of("namespace", "path") 创建的。对于 1.21 之前的版本,是通过 new Identifier("namespace", "path")new Identifier("namespace:path")。当命名空间或路径包含非法字符(例如大写字母、中文)时,会失败。

  1. public class ExampleMod implements ModInitializer {
  2. // 新物品的实例
  3. public static final Item CUSTOM_ITEM = new Item(new Item.Settings());
  4.  
  5. @Override
  6. public void onInitialize() {
  7. // 对于 1.21 之前的版本,请将 ''Identifier.of'' 替换为 ''new Identifier''
  8. Registry.register(Registries.ITEM, Identifier.of("tutorial", "custom_item"), CUSTOM_ITEM);
  9. }

现在新物品已添加到 Minecraft 中,运行“Minecraft Client”运行配置或者 runClient Gradle任务以查看它的运行情况,在游戏内执行命令 /​give @s tutorial:​custom_item​。

注册物品的最佳实践

在上面的代码中,简直创建了一个物品。但是,如果模组有许多物品,则这样并不方块,因为你每次都需要注册、创建一个 Identifier。所以我们创建一个专门的类存储物品对象,例如 ModItems 或者 TutorialItems,然后简单的 register 方法便捷地注册物品。这在实际模组开发中很常见。你也可以看看原版的 Items 类以了解 Minecraft 中如何以类似方式完成的。

在这个例子中,创建一个 TutorialItems 类,并在 ModInitializer 中引用它。

  1. public final class TutorialItems {
  2.  
  3. private TutorialItems() {}
  4.  
  5. // 新物品的实例
  6. public static final Item CUSTOM_ITEM = register("custom_item", new Item(new Item.Settings()));
  7.  
  8. public static <T extends Item> T register(String path, T item) {
  9. // 对于 1.21 之前的版本,请将 ''Identifier.of'' 替换为 ''new Identifier''
  10. return Registry.register(Registries.ITEM, Identifier.of("tutorial", path), item);
  11. }
  12.  
  13. public static void initialize() {
  14. }
  15. }

记得在模组初始化过程中引用模组的一些方法或字段,从而静态加载 TutorialItems 类。

  1. public class ExampleMod implements ModInitializer {
  2. @Override
  3. public void onInitialize() {
  4. TutorialItems.initialize();
  5. }
  6. }

注意:一些有经验的用户也可能会决定使用反射来自动注册一个类的所有静态字段。这也可以,但是请小心使用。

添加物品纹理

如果第一步成功注册了你的物品,就可以成输入命令 /give @s tutorial:custom_item 成功得到你的物品。你会发现纹理缺乏,Minecraft 会像这样报错:

  [Server-Worker-1/WARN]: Unable to load model: 'tutorial:custom_item#inventory' referenced from: tutorial:custom_item#inventory: java.io.FileNotFoundException: tutorial:models/item/custom_item.json

这是因为我们还没有给物品提供纹理和模型。所以,你需要定义物品模组并提供纹理图像。你会需要将这些添加到你的资源的目的下,直接路径如下:

为物品注册纹理需要物品模型.json文件和纹理图像文件。 您将需要将它们添加到资源目录中。每个的直接路径是:

  • 物品模型:…/resources/assets/tutorial/models/item/custom_item.json
  • 物品纹理:…/resources/assets/tutorial/textures/item/custom_item.png

我们将使用这个示例纹理

一个非常简单的物品模型长这个样子:

{
  "parent": "item/generated",
  "textures": {
    "layer0": "tutorial:item/custom_item"
  }
}

你的物品模型的 parent改变了物品在手中以及在物品栏内等情形下的渲染。item/generated 用于许多简单的物品。item/handheld 用于手持其纹理左下角的物品。在 json 中,textures/layer0 是图像文件的位置。

创建物品类

要为物品添加自定义行为,则需要创建一个物品类。其默认的构造方法需要一个 Item.Settings 对象。

  1. public class CustomItem extends Item {
  2.  
  3. public CustomItem(Settings settings) {
  4. super(settings);
  5. }
  6. }

自定义物品类的一个实际用例是使该物品在右击时播放声音:

  1. public class CustomItem extends Item {
  2.  
  3. public CustomItem(Settings settings) {
  4. super(settings);
  5. }
  6.  
  7. @Override
  8. public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) {
  9. user.playSound(SoundEvents.BLOCK_WOOL_BREAK, 1.0F, 1.0F);
  10. return TypedActionResult.success(playerEntity.getStackInHand(hand));
  11. }
  12. }

用新物品类的实例替换旧的 Item 对象:

  1. public class ExampleMod implements ModInitializer {
  2.  
  3. // 新物品的实例
  4. public static final CustomItem CUSTOM_ITEM = new CustomItem(new Item.Settings());
  5. [...]
  6. }
如果你正确执行了所有操作,则使用该物品现在应该会播放声音。

如果我想更改物品的堆叠大小怎么办?

使用 Item.Settings 内的 maxCount(int size) 来指定最大堆叠数。请注意,如果你的物品是有耐久的(及耐久归零后会被破坏),那么此物品无法设置最大堆叠数,否则游戏将抛出 RuntimeException。

  1. public class ExampleMod implements ModInitializer {
  2.  
  3. // 我们新物品的实例,最大堆叠大小为16
  4. public static final CustomItem CUSTOM_ITEM = new CustomItem(new Item.Settings().maxCount(16));
  5. [...]
  6. }

让物品能作为燃料或者可堆肥

如果需要让物品能作为燃料在熔炉中燃烧,可以使用 FuelRegistry,例如:

public class ExampleMod implements ModInitializer {
    [...]
 
    @Override
    public void onInitialize() {
        [...]
        FuelRegistry.INSTANCE.add(CUSTOM_ITEM, 300)
    }
}

类似地,你也可以使用 CompostingChanceRegistry 来让它可以在堆肥桶中堆肥。

下一步

zh_cn/tutorial/items.txt · Last modified: 2024/08/26 01:24 by solidblock