Minecraft Forge 模组开发实战 — 游戏规则可控的二段跳(一)二段跳部分

第一天 准备开发环境

首先你需要一个MDK,这里使用forge-1.19.4-45.1.0,把它解压到一个文件夹

然后你需要一个IntelliJ(Community免费版即可),

 

打开build.gradle所在的文件夹,然后等待构建。

构建就不用多说了,遇到的问题也五花八门

至少我现在还不懂所有错误的解决方法,我自己构建是一帆风顺的,但帮别人构建总会出各种各样的错误

构建一般需要一个小时,也有可能十几分钟

listLibraries可能会运行好久...我这一步运行了半小时

展开这个 

 

,然后找到src/main/java/com.example.example/ExampleMod打开看看

如果没有红字报错就说明构建好了

建议大家给IntelliJ装中文插件和Minecraft Development插件,装的方法网上都有教程,这里就不细说了

 

 

第二天 配置开发环境

首先创建一个主类

把com.example.examplemod给删了

然后创建一个自己的包,一般用域名倒写+模组id

软件包的名字一般是全小写+下划线

 

 

如果没有域名的话可以直接com.什么什么.模组id

以下目录仅作参考

 

然后给Main类加两个注解

@Mod("你的modid")
@Mod.EventBusSubscriber

 

鼠标悬停到Mod上点击导入类

import net.minecraftforge.fml.common.Mod;

 

然后是mods.toml文件

 

 

 

注意:只能用纯英文

mods.toml文件包含的是模组的一些相关信息

比如名称、作者、描述之类的

显示到模组列表中

 

启动游戏

写好之后,可以启动游戏试试了

第一次启动可能需要安装minecraft

会下载一些资源

从屏幕右上角也可以运行/调试

 

但是第一次是要从右边gradle里运行/调试的,然后会自动生成配置文件,之后就可以从右上角了

注意:Forge并不支持在游戏运行的时候修改代码,修改代码后必须重启游戏才能应用,但是有种很神奇的方式可以大大提高调试效率:断点调试

 

这样就启动好了

调一下语言,然后打开模组列表看看吧

 

可以关掉游戏了,我们来写个事件处理器吧

在Main类里创建一个

@SubscribeEvent
public static void onKey(InputEvent.Key event) { }

注意SubscribeEvent注解需要导入

import net.minecraftforge.eventbus.api.SubscribeEvent;

InputEvent类需要导入 

import net.minecraftforge.client.event.InputEvent;
Minecraft mc = Minecraft.getInstance();

可以获取客户端实例

要知道按键事件是只有客户端会触发的

mc.player就是获取客户端玩家

如果玩家是null说明没有进入世界,为了防止NullPointerException(空指针错误)必须做个判断

 

玩家没有进入世界怎么按按键

在主页面按啊

Minecraft mc = Minecraft.getInstance();可以写在任何地方,只要是能调用到的地方就行

 

这样也行

event.getAction()获取你的操作:按下/弹起

event.getKey()获取按下的键

event.getAction()的返回值有三种:按下、弹起、重复(都是int类型的常量,所以如果不顾代码可读性的话可以直接换成数字)

  • InputConstants.PRESS

  • InputConstants.RELEASE

  • InputConstants.REPEAT

重复?

比如你按住a,然后会发现,你会一直输入a,第一次是按下,后面的都是重复了

重复的触发延时和触发间隔都是可以在系统设置里调的

if (event.getAction() == InputConstants.PRESS) {

这个样子就可以判断是不是按下

检查按键有两种方式

第一种方式是检测按下的是不是空格键

if (event.getKey() == GLFW.GLFW_KEY_SPACE)

GLFW.GLFW_KEY_SPACE也是int常量

第二种方法是检测按下的是不是跳跃键

mc.options获取客户端设置,类型是net.minecraft.client.Options

mc.options.keyJump.getKey().getValue()返回跳跃键的按键码

if (event.getKey() == mc.options.keyJump.getKey().getValue())

这种方式可以应对修改按键设置的情况

mc.options.keyJump是net.minecraft.client.KeyMapping类型(按键映射)

 

 

然后写让玩家跳起来

跳跃是客户端的操作

mc.player其实是一个net.minecraft.client.player.LocalPlayer对象

我们通过调用这个对象的方法来让玩家起跳

mc.player.jumpFromGround();

就是这么简单,无论是不是踩在地上都可以起跳

jumpFromGround是默认你在地上了

是不是还要加限定条件才能成为二段跳,而不是无限跳

确实,这样就是无限段跳(外挂模组),你进别人世界玩的时候可以装个无限跳,但进服务器就得小心了

 

这是我无限跳的代码,大家可以运行游戏尝试一下

接下来我们要写个跳跃计数器

这个计数器不能写成方法变量,要写成类变量

 

注意必须是静态的(static)

方法变量是什么

 

然后每跳一次就把它+1

 

然后要做的是在玩家落地的时候把计数器清零,我们再写一个处理器用来检测落地

LivingFallEvent在任何生物落地的时候都会触发

需要检测触发事件的是不是客户端玩家

@SubscribeEvent
public static void onFall(LivingFallEvent event) {
    if (event.getEntity() instanceof LocalPlayer player) {
        if (player == mc.player) {
            jumpCount = 0;
        }
    }
}

 

event.getEntity()获取触发事件的实体

instanceof关键字判断对象是否属于某个类

if (event.getEntity() instanceof LocalPlayer player) {

if (event.getEntity() instanceof LocalPlayer) {
    LocalPlayer player = (LocalPlayer) event.getEntity();

的简写

event.getEntity();

得到的是一个Entity(实体)对象

玩家也是实体

LocalPlayer(本地玩家)类是从Entity类继承下来的

因此LocalPlayer类是Entity类的子类

和C++一样,在确保event.getEntity()获取到的一定是一个LocalPlayer对象或者是LocalPlayer的子类的对象的时候,可以通过(LocalPlayer) event.getEntity()来把它转换成LocalPlayer对象(如果不是LocalPlayer对象的话会抛异常)

而event.getEntity() instanceof LocalPlayer就能确保event.getEntity()获取到的一定是一个LocalPlayer对象或者是LocalPlayer的子类的对象

 

但是这种写法难免有些复杂,因此就产生了模式变量这种东西

 

 

现在二段跳的功能已经实现了,大家可以运行游戏尝试一下

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值