NeoForge P2 - 物品注册
1114 字
6 分钟
NeoForge P2 - 物品注册
一、相关文档与介绍
NeoForge 官方文档:https://docs.neoforged.net/docs/items/
那么对于物品(Item),要明白它是分别存在 属性(Properties) 与 行为(Methods) 的。
在 Minecraft Datapack,自然对 /attritube 并不陌生,它则用于控制物品的属性,而大部分数据包中的基础行为则需要使用 数据组件(Component) 进行定义,而部分高级行为,都是通过对指定名称或包含指定标签的物品进行 检测(execute),而后触发指定的 函数(function) 实现具体功能。
那么在模组开发中,属性则使用 Item.Properties 链式调用,它是用于描述物品的 静态特征 ,如堆叠、耐久、是否防火等。而行为则是用于描述物品的 动态特征,如左键功能(攻击指定实体、破坏指定方块等)、右键功能(右键空气、放置方块等)、定时检测(每 Tick 执行检测、物品掉落到地上)、甚至是被玩家丢弃、拾取、耐久消耗完毕、合成都是可以进行侦测的。
二、注册第一个物品
既然介绍了物品的属性与行为,那么就创造第一个属于自己的物品吧。
name: super_stone# 定义:如 lang 语言文件、材质 modules 等assest: lang: - zh_cn: "超级石头" - en_us: "SUPERSTONE" models: item: super_stone.json: { "parent": "minecraft:item/stone" }# 属性properties: # 最大堆叠32 - .stacksTo(32) # 掉入岩浆不会被烧毁 - .fireResistant()
method: # 可被食用,饱食度10点 # 可被放置在地上,被放置后变成普通的石头(minecraft:stone) # 被丢出的时候召唤一条闪电2.1 基本定义
那么,就让我们开始一步步实现吧。首先则是基本定义。
# 在 resources.assets.helloworld.lang.en_us.json 定义英文名# 在 resources.assets.helloworld.lang.zh_cn.json 定义中文名"item.helloworld.super_stone": "超级石头"# 在 resources.assets.helloworld.models.item.super_stone.json 定义材质# 这里继承原版的材质即可"parent": "minecraft:item/stone"2.2 属性实现
public static final DeferredHolder<Item, Item> SUPER_STONE = ITEM.register("super_stone", () -> new Item(new Item.Properties() .stacksTo(32) .fireResistant() .component(DataComponents.FOOD, new FoodProperties.Builder() .nutrition(10) // 定义食物点 .saturationModifier(1.0f) //定义饱和度 .build()) //构建食物 ));2.3 行为实现
2.3.1 行为实现(可放置)
public class Item_SuperStone extends Item {
public Item_SuperStone(Properties properties) { super(properties); }
@Override public @NotNull InteractionResult useOn(UseOnContext ctx) { Level level = ctx.getLevel(); BlockPos pos = ctx.getClickedPos().relative(ctx.getClickedFace()); ItemStack stack = ctx.getItemInHand(); Player player = ctx.getPlayer();
if (!level.getBlockState(pos).isAir()) { return InteractionResult.FAIL; }
if (!level.isClientSide && player != null) { level.setBlock(pos, Blocks.STONE.defaultBlockState(),3);
SoundType soundType = Blocks.STONE.defaultBlockState().getSoundType(); level.playSound(null, pos, soundType.getPlaceSound(), SoundSource.BLOCKS, (soundType.getVolume() + 1.0F) / 2.0F, (soundType.getPitch() * 0.8F) );
stack.shrink(1); } return InteractionResult.SUCCESS; }}由于初次编写,可能有些不懂的地方,这里将会给予详细注释:
UseOnContext ctx# 它则意味着是 UseOnContext = "右键点击的上下文" 将其赋予 ctx,而后 Player 在 右键这个方块的时候,会将信息打包给这个 对象。内容如下:UseOnContext 里装着: ├─ 哪只手点的?(InteractionHand) ├─ 点在了哪个方块上?(BlockPos + BlockState) ├─ 点在了方块的哪一面?(Direction) ├─ 点击位置的具体坐标?(Vec3) ├─ 谁点的?(Player) ├─ 在哪个世界?(Level) └─ 手里拿的是什么?(ItemStack)
而在右键方块时,则执行以下流程:
air ← pos(你要放石头的位置) ↑ ┌─────────┐ │ 草方块 │ ← ctx.getClickedPos()(被点的方块) │ grass │ └─────────┘ ↑ 玩家右键草方块顶面 → ctx.getClickedFace() = UP .relative(UP) 往上一格 = pos
这就解释了为什么 useOn 里先取 pos,再检查 pos 是不是空气,得确保那里没方块才能放。
后者的 soundType 则定义了放置方块所发出的声音。2.3.2 行为实现(丢出后在当前位置召唤闪电)
@EventBusSubscriber(modid = HelloWorld.MODID)public class Item_SuperStone {
@SubscribeEvent public static void onItemToss(ItemTossEvent event) { var stack = event.getEntity().getItem();
if (stack.is(InitItems.Item_SuperStone.get())) { var level = event.getEntity().level(); var bolt = new LightningBolt(EntityType.LIGHTNING_BOLT, level); bolt.setPos(event.getPlayer().position()); level.addFreshEntity(bolt); } }}由于初次编写,可能有些不懂的地方,这里将会给予详细注释:
@EventBusSubscriber:在 NeoForge 启动时,自行组测物品的组件。var stack = event.getEntity().getItem(); -> 找到被丢出物品实体的 ItemStack使用 if 检查是否为指定目标:如果是,则在当前世界内创建闪电实体(new LightningBolt(EntityType.LIGHTNING_BOLT, level))并把闪电实体置入此位置(bolt.setPos(event.getEntity().position());)而后加入世界生效(level.addFreshEntity(bolt);)。2.4 置入创造物品栏
那么最后,模组的第一个物品,要将其置入自己的创造物品栏吧!
.displayItems((parameters, output) -> { output.accept(InitItems.Item_SuperStone.get());})只需要在创造物品栏下的注册物品,添加 output.accept() 的物品即可。
三、小结
那么今天学习了物品的注册方法,与定义物品的属性与行为的实现方法。
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!
NeoForge P2 - 物品注册
https://springtsuki.xucjno.com/posts/springtsuki/notes/java/2026/810-2/












