【干货】《我的世界》Mod开发教程05:创造模式物品栏


3楼猫 发布时间:2024-12-20 13:24:15 作者:甄别 Language

【干货】《我的世界》Mod开发教程05:创造模式物品栏-第0张

在这一期教程中,我们将介绍Forge的事件系统以及之前提到的创造模式物品栏。首先,我们可以用一个微波炉的比喻来理解事件系统。就像使用微波炉加热食物一样,在关注加热完成的时间时,会留意微波炉是否发出“滴滴滴”的声音,这就是监听事件。一旦听到声音,你会对微波炉做出相应处理,比如检查食物是否热了,需要继续加热等。这一系列的操作就是事件处理,而事件发生则是指微波炉发出响声。这就是事件系统的基本原理。

【干货】《我的世界》Mod开发教程05:创造模式物品栏-第1张

在游戏中也存在许多事件,比如方块放置、摧毁、物品丢弃、动物成长等都是事件。为了对这些关键事件做出反应,我们需要监听这些事件并进行相应处理。事件大致可以分为两类:一种是在Forge内部的事件,管理游戏内发生的事件;另一种是在FML(Forge Mod Loader)下的事件,主要管理游戏生命周期中的事件,与游戏内内容无关,例如游戏启动时的方块和物品注册、配置文件加载等。

要了解Forge提供了哪些事件,可以在net.minecraft.forge包中查找。通过查看clientEV等类,可以找到各种事件。在代码中展开查找用法,了解事件的具体应用及范围,进而选择合适的事件来使用。

【干货】《我的世界》Mod开发教程05:创造模式物品栏-第2张

在本期教程中,我们将注册创造模式的物品栏,可以利用构建创造模式物品栏的事件来实现这一功能。

在使用事件时需要注意,事件分为两种:一种是Forge事件,另一种是FML事件。要判断一个事件属于哪种类型,可以观察其后缀。实现了mod bus EV接口的事件属于FML事件。比如我们上次注册物品时使用的是正一句,这个语句实际上获取了FML事件总线,也就是mod事件。通过编写事件处理函数并注册即可使用事件。

假设我们编写一个public void addCreativeTab函数,并将其注册进去。在该函数中,参数event包含各种有用信息。例如,如果想将物品添加到某个栏位(比如functional blocks),可以查看Minecraft类中的creative mode tips等变量。通过event.getTab()来获取creative mod tab对象,然后创建resource key对象或者使用getTypeKey方法来获取资源键。接着在event.accept(myBlock)后将事件注册即可。

【干货】《我的世界》Mod开发教程05:创造模式物品栏-第3张

通过bus.addListener(this::addCreativeTab)来注册事件,这样我们的函数就会被调用。启动游戏后,打开创造模式物品栏,应该能看到我们刚才注册的functional block,这样就实现了功能方块的展示。

除了以上的方式外,还有其他注册事件的方式。可以使用@SubscribeEvent注解和bus.register(this.getClass())的方式进行注册,也可以注册其他类如testMod.getClass()。这样FML就会识别所有带有@SubscribeEvent注解的方法并全部注册。这种方式适用于需要注册多个函数的情况,避免重复写长串的@Listener。

【干货】《我的世界》Mod开发教程05:创造模式物品栏-第3张

需要注意的是,如果注册的是一个类,而不是静态方法,那么注册的方法必须是静态的。非静态方法只能在创建实例时调用,而静态方法可以直接通过类来调用。因此,当注册一个类时,必须将注册方法改为静态方法。

另一种方式是使用纯注解的方式。可以将之前的方法注释掉,然后创建一个公共静态类,命名为EventListener,并将函数移到这个类中。在这个类的上方加上@EventSubscriber注解,指定bus等于mod id,即我们的mod id。同样,这里的方法也必须是静态的。

【干货】《我的世界》Mod开发教程05:创造模式物品栏-第3张

还有一种方法是将代码写到一个新的类里面。例如,新建一个包event,在其中新建一个Java类,命名为EventListener。将之前的代码复制到这个类中,无需添加static关键字。导入mod id和myBlock,并修改名称。这种方式也是可行的。

接着,我们可以在代码中继续编写,例如添加if event.getTab()等于creative mod tabs的条件,将物品放入tools栏位,并通过event.accept(myItem)来实现。进入游戏验证后,确保功能方块中有售货机,工具栏中有兑换券,验证注册成功。

【干货】《我的世界》Mod开发教程05:创造模式物品栏-第3张

退出游戏后回到代码中,如果将bus后面的参数改成forge,那么注册的就是Forge事件。可以尝试查找一个Forge事件,如实体或玩家内的某个boil event。将其改为ModEventListener,并再创建一个名为BusEventListener的类,使用@EventSubscriber注解,设置mod id为当前mod id,bus为forge,进行导入操作。

如果想要使骨粉对西瓜和南瓜等带有"gourd"标签的作物无效,可以编写一个preventSteam方法,并将其中的事件类型改为BlockEvent。接着查看该事件可以获取的参数,如level(方块生长阶段)、blockPos(方块位置)、blockState(方块状态)和world(世界对象)。首先需要获取方块信息,可以通过getBlock()方法获取到一个blockState对象,然后再根据需求获取具体方块信息。

【干货】《我的世界》Mod开发教程05:创造模式物品栏-第3张

在判断方块类型成功后,可以使用setCancelled(true)来取消事件。这样一来,当我们用骨粉对西瓜种子进行操作时,发现骨粉完全无效,甚至手势也没有变化,说明事件被成功取消了。不过,其他作物如土豆是可以正常生长的。

如果需要修改方块而不是取消事件,可以先存储方块信息到一个变量中,然后通过一系列操作来修改方块状态。比如可以设置方块年龄或者让其转变成其他方块,在原版代码基础上进行适当的更改即可。

【干货】《我的世界》Mod开发教程05:创造模式物品栏-第3张

最后别忘了将事件再次取消掉,通过event.setCancelled(true)实现。这样就可以用自定义的方法替代原本的行为,实现特定功能的定制化。

接着进行测试,每次操作只会让作物生长一格,注意到了吗?但是当作物生长到最大阶段后,游戏崩溃了。这是因为最大的生长阶段是七,我们设置了一个更高的值,导致游戏崩溃。这个问题留给大家自行解决。

另外要提及的是,如果每个Mod都将注册内容放在原版的注册表中,那么最终原版注册表中将会有很多内容,难以找到对应的注册项。解决方法是创建一个私有的静态不可变DeferredRegister对象,命名为creativeTab,并将其与DeferredRegister.create结合使用。如果使用Forge Registry时找不到CreativeTab,可以使用原版的Registry.CreativeModTab。

【干货】《我的世界》Mod开发教程05:创造模式物品栏-第3张

然后再声明一个公共的静态不可变RegistryObject类型的CreativeModTab对象,并通过creativeMotabs.register方法来注册自定义标签。在这之后,可以使用CreativeModTab.Builder来添加标题和图标等信息。创建一个兑换券的设计,设置DecayItems参数,并通过Output.accept方法添加自定义方块和兑换券。最后,通过CreativeModTips.registerBus注册事件总线,查看效果。

【干货】《我的世界》Mod开发教程05:创造模式物品栏-第3张

验证效果后,发现页面上有翻页并且出现了Test Mod,成功添加了我们的内容。自定义创造模式的物品栏也已经设置完成。本期就讲到这里关于事件系统的内容,无需太复杂,一旦需要使用,可以再次调用。虽然事件系统还有很多内容可以探索,但没必要全部讲解,因为有些用法我本身也无法想象怎么使用。只要在实际使用中遇到问题再去查看即可。所示例的用法例如难度更改等,你们应该能很容易地想到如何应用。查看参数并修改、获取它们等都是可以的。

好了,这期教程就到这里为止。


© 2022 3楼猫 下载APP 站点地图 广告合作:asmrly666@gmail.com