forge教程

发布时间 2023-09-25 14:21:12作者: Cold的窝

物品Item

介绍:物品就是所有只能抓在手中的,不能手动防置在level(世界)中的统称为物品。如果你问,那我把Item丢到level中呢?是方块,但是这是每种物品都会自带的掉落状态!

创建一个物品

当我们创建一个物品,我们当然要继承Item

public class MyItem extends Item {

//在我们创建MyItem时必须要传入物品的属性给到Item
    public MyItem (Properties properties) {
        super(properties);
    }
}

物品属性

第一次我们可以直接调用Item的内部类new Item.Properties()

物品属性还有很多这里我们就留给大家进入源码中探索,我也会不时把我学到的更新到这一节!

物品注册

大部分的东西都是用DeferredRegister注册到Minecraft中的!

DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MODID);

这样我们就得到了Forge的方块注册表

 RegistryObject<Item> MyItem = ITEMS.register("myitem", () -> new MyItem(new Item.Properties()));

这里必须必须注意:ITEMS.register中第一个参数是物品的名称,最好是小写!

最后我们把这个Forge的物品注册表注册到游戏中去

 ITEMS.register(FMLJavaModLoadingContext.get().getModEventBus());

这里我们用到了是mod事件哦,为我事件那一节做铺垫!
这样完成后,你以为你的物品创建完了吗,并没有,不然你进入游戏就是这样的

这是我随便找的图,经供参考

物品材质

在textures目录的子文件夹Item中这里放置你的物品png
在models目录的子文件夹Item中防置你的物品模型json

在这里我给一个模型经供参考

{
	"parent": "minecraft:item/generated",
	"textures": {
		"layer0": "mymod:item/myitem"
	}
}

准备好这些,我们就可以进游戏体验我们的第一个物品了

方块Block

创建第一个方块

介绍:对于简单的方块,或者说那些没有特殊功能的方块(如圆石和木板等),你并不需要对它们单独创建一个类。你只需要实例化一个 Block 类并调用一些Setter方法,就能创建出很多不同种类的方块。

物品属性(Properties)

  • setHardness - 控制破坏方块所需要的时间。它可以是任意的值。方便参考起见,石头(Stone)的硬度(Hardness)为1.5,泥土(Dirt)的硬度为0.5。如果方块应该是不可破坏的,你可以直接调用 setBlockUnbreakable。
  • setResistance - 控制方块的爆炸抗性。虽然这个值是与硬度分开的,但是 setHardness 同样会将方块的爆炸抗性(Resistance)设置为5倍的硬度,如果爆炸抗性低于这个值的话。(译注:这个方法设置后的实际 blockResistance 是传入参数的3倍。 比如说石头的爆炸抗性(blockResistance)为30,但传入的参数为 10.0f。而setHardness 检测的是这个 blockResistance。但一般初始化方块的时候一般都先设置硬度再设置爆炸抗性)
  • setSoundType - 控制方块被击打、破坏、或放置时的声音。需要传入一个 SoundType 参数,具体请看音效那一节。
  • setLightLevel - 控制方块的发光程度。注意:这个方法接受一个0-1的值,而不是0-15。如果想要计算这个值,请用你需要的光亮等级除以16。比如说,如果一个方块的亮度为5,那么这里的参数需要为 5 / 16f。
  • setLightOpacity - 控制方块阻碍光线传播的程度。不像 setLightLevel,这个值的范围是0-15。比如说,将这个值设定为 3 时,每当光线穿过方块,光线的光亮等级将会减少3级。
  • setUnlocalizedName - 设置方块未本地化时(Unlocalized)的名字。这个名字会被前缀 “tile.”,并后缀 “.name” 以方便本地化。比如说,setUnlocalizedName("foo") 会将方块的本地化条目设置为 “tile.foo.name”。如果你需要更高级的本地化控制,那么你还需要一个自定义的物品(Item)类,我们将会在之后进行介绍。
  • setCreativeTab - 控制方块所在的创造面板。面板选项可以在 CreativeTabs 类下找到。

这里的物品属性我们要用BlockBehaviour.Properties这个内部类中的of方法

public static final RegistryObject<Block> myBlock = BLOCKS.register("myblock", () ->
            new Block(BlockBehaviour.Properties.of().strength(3.0f).sound(SoundType.CROP)));

方块注册

这里我们也是用到DeferredRegister类来获取forge的block注册表

public static final DeferredRegister<Block> BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID);

然后我们也要吧block注册表注册进入mod总线中

BLOCKS.register(FMLJavaModLoadingContext.get().getModEventBus());

物品材质

在textures目录的子文件夹Block中这里放置你的物品png
在models目录的子文件夹Block中防置你的物品模型json

模型示例:

{
  "credit": "Made with Blockbench",
  "parent": "minecraft:block/cube_all",
  "texture_size": [
    64,
    64
  ],
  "textures": {
    "0": "mymod:block/myblock",
    "particle": "mymod:block/myblock"
  },
  "elements": [
    {
      "from": [
        0,
        0,
        0
      ],
      "to": [
        16,
        16,
        16
      ],
      "faces": {
        "north": {
          "uv": [
            0,
            0,
            4,
            4
          ],
          "texture": "#0"
        },
        "east": {
          "uv": [
            0,
            4,
            4,
            8
          ],
          "texture": "#0"
        },
        "south": {
          "uv": [
            4,
            0,
            8,
            4
          ],
          "texture": "#0"
        },
        "west": {
          "uv": [
            4,
            4,
            8,
            8
          ],
          "texture": "#0"
        },
        "up": {
          "uv": [
            4,
            12,
            0,
            8
          ],
          "texture": "#0"
        },
        "down": {
          "uv": [
            12,
            0,
            8,
            4
          ],
          "texture": "#0"
        }
      }
    }
  ],
  "display": {}
}

对于方块我们比物品多一步
在blockstates文件中还要添加一个json模型文件

{
    "variants": {
        "": [
            {
                "model": "mymod:block/myblock"
            },
            {
                "model": "mymod:block/myblock",
                "y": 90
            },
            {
                "model": "mymod:block/myblock",
                "y": 180
            },
            {
                "model": "mymod:block/myblock",
                "y": 270
            }
        ]
    }
}

这样我们的第一个物品就创建成功了!

没错我们的方块类中也有很多属性等待你去源码中探索哦!

ItemState

介绍:

为什么我分开讲,因为我觉得ItemState跟BlockState差别不大,而且这里面别有洞天!
Item 和 Block 只有一个,但是ItemState 和 BlockState 有无数个!
……
未更新完敬请期待!
……

事件

介绍:Forge使用的是一种事件总线(Event Bus)的机制,使mod能够从原版或者mod行为中截取事件(Event)。对于大部分事件的主事件总线位于 MinecraftForge.EVENT_BUS。
但是还是有很多事件很***钻!
特点:forge有两套bus分别如下
forge -> event : 游戏内发生的事,游戏已经在运行了!
Mod事件 ->Fml -> event :游戏生命周期发生的事,和世界内无关,游戏启动,物品注册,配置文件加载等等游戏还没正式运行时候! -> 一般实现了IModBusEvent就是mod事件

事件的分类

能力(Capability)

Capability Provider 要实现ICapabilityProvider, INBTSerializable接口

自定义properties中要定义好存储和读取的方法,使用CompoundTag 来序列化和反序列化数据

每一个Capability都要一个对应的provider,这个provider要继承ICapabilityProvider,INBTSerializable这两个接口
并且重写getCapability方法和serializeNBT,deserializeNBT两个序列化和反序列化的方法

getCapability需要一个LazyOptional的返回值

所以在provider中我们要创建一个LazyOptional

private final LazyOptional<PlayerProperties> lazyOptional = LazyOptional.of(() -> this.playerProperties);

这是一般创建LazyOptional的方法

serializeNBT,deserializeNBT

就是将我们在properties中自定义的存储和读取CompoundTag的方法传入进去

 @Override
    public Tag serializeNBT() {
        CompoundTag tag = new CompoundTag();
        playerProperties.saveData(tag);
        return tag;
    }
    @Override
    public void deserializeNBT(Tag nbt) {
        playerProperties.loadData((CompoundTag) nbt);
    }