IntellIJ开发简单Minecraft插件(利用paper API)

有的时候想实现服务器里的一些简单的功能,但是网上又找不到,这个时候可以尝试写一个出来。

例如,在游戏里想要实现这样一个功能,玩家噶了之后在聊天栏处显示死亡坐标,这样可以方便玩家去那个坐标处把死亡时掉落的物品捡回来,差不多就是这样

试着搞一下吧:

首先在IntellIJ上安装Minecraft Development插件(File->setting->plugin)

新建项目:直接选择Minecraft,项目SDK保持最开始勾选的那个(跟游戏同一个SDK)就行了,选择paper plugin(这里打算搞一个paper核心上能用的插件),点击下一步

接下来:groupid输入com.xx.xx的样式,

这里希望插件能提醒玩家信息,干脆叫prompter好了,groupid取成com.mc.newprompter,artifactid取成prompter

其他的先别动(包括那个Maven,以后需要更多复杂操作的时候再来研究maven和gradle有啥区别吧),点下一步

Plugin name还是输入Prompter得了,Main Class Name不用动,右侧那个Minecraft Version按游戏版本选,例如1.19.3

(Minecraft Version加载有点慢,可能显示不出来,这个时候需要等一会,挂个梯子似乎加载更快点,同理后边要是出现连接不上网络之类的,都试试挂一下梯子吧,包括前边下载插件的时候)

Optional Settings下边的这堆玩意先不填了,点下一步

项目名称继续填prompter,项目位置自选,点创建

接下来就是整个工程界面了

OnEnable

@Override
    public void onEnable(){
        //你的代码
    }

表示当插件被启用时,执行“你的代码”中的内容

OnDisable

@Override
    public void onDisable(){
        //你的代码
    }

表示当插件被禁用时,执行“你的代码”中的内容。

接下来开始写代码:

新建一个java class,取名为DeathCoordinates,这个类就是用来显示死亡坐标的:

DeathCoordinates.java

package com.mc.newprompter.prompter;
import org.bukkit.Location;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.PlayerDeathEvent;

public class DeathCoordinates implements Listener {
    @EventHandler
    public void onPlayerDeath(PlayerDeathEvent event) {
        // 获取玩家死亡的位置
        Location location = event.getEntity().getLocation();
        // 在游戏聊天框内输出坐标
        event.getEntity().sendMessage("你死亡的坐标是: " + location.getX() + ", " + location.getY() + ", " + location.getZ());

    }
}

当然以上代码也可以加点别的东西,例如

getEntity().getPlayer()  //用getplayer可以获取被击杀的玩家

getEntity().getKiller()  //用getkiller可以获取击杀者

在主类中注册监听器,只需要在OnEnable里边加上一行就可以了:

Prompter.java

package com.mc.newprompter.prompter;

import org.bukkit.plugin.java.JavaPlugin;

public final class Prompter extends JavaPlugin {

    @Override
    public void onEnable() {
        // Plugin startup logic
        //注册监听器
        getServer().getPluginManager().registerEvents(new DeathCoordinates(), this);
    }

    @Override
    public void onDisable() {
        // Plugin shutdown logic
    }
}

因为我们要实现的功能很简单,所以代码也很简单,以上代码用到了两个相关内容PlayerDeathEvent 和Player.sendMessage

1.如果你想在玩家死亡后系统提示死亡地点的坐标,你可以使用 PlayerDeathEvent 事件来实现。PlayerDeathEvent 事件会在玩家死亡时触发,你可以在这个事件的处理函数中实现你的代码。

2.你已经通过PlayerDeathEvent事件获取到玩家在哪死亡的信息了,但是还得把这个信息输出到聊天栏,如果你想在玩家死亡时在游戏聊天框内输出死亡地点的坐标,可以使用 Bukkit API 中的 Player.sendMessage() 方法。

(注意:在这个例子中,我们使用了 Player.sendMessage() 方法来输出坐标。如果你想将坐标输出到服务器日志中,你可以使用 Java 的 System.out.println() 函数,例如:System.out.println("玩家死亡的坐标: " + location.getX() + ", " + location.getY() + ", " + location.getZ());

以上,我们已经把代码给整好了,接下来需要让它输出成一个可执行jar包,然后放进服务器里

点击左上角的文件(File),点击项目结构(Project Structure

点击 工件(Artifacts),点击右侧左上的+号,选择jar,选择空(empty)

名称取名为prompter1.0,勾选“包含在项目构建中”,右侧有可用元素的话点击,使左侧显示有'prompter'编译输出就行了,点击确定

此时回到编代码的窗口,点击左上的”构建“(build),选择构建工件(应该是Build Artifacts吧),

如上图,构建后去工程目录下找那个输出的jar包就行了

如我的就输出到了IdeaProjects\prompter\out\artifacts\prompter1_0目录下

这里有一个jar包,直接扔到服务器的plugins文件夹下就行了,服务器重启后生效。


 

接下来尝试加点更多功能吧,在右边显示一个侧边栏,能显示血量,在线人数,坐标啥的:

效果如图

新建一个java class,命名为CoordinatesDisplay,主要功能是展示坐标,以及显示血量啥的

CoordinatesDisplay.java

package com.mc.newprompter.prompter;
import com.destroystokyo.paper.event.player.PlayerJumpEvent;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.scoreboard.DisplaySlot;
import org.bukkit.scoreboard.Objective;
import org.bukkit.scoreboard.Score;
import org.bukkit.scoreboard.Scoreboard;
//可以参考一下https://www.jianshu.com/p/911edcaf5e79

public class CoordinatesDisplay implements Listener {
    // 创建计分板
    private Scoreboard scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
    // 创建计分目标
    private Objective objective = scoreboard.registerNewObjective("status", "dummy","§b状态信息");


    @EventHandler
    public void onPlayerJoin(PlayerJoinEvent event) {
        // 获取玩家
        Player player = event.getPlayer();
        // 设置计分目标的显示位置为左上角
        objective.setDisplaySlot(DisplaySlot.SIDEBAR);
        // 设置计分目标的名称
        //objective.setDisplayName("坐标信息");

        // 给玩家设置计分板
        player.setScoreboard(scoreboard);

        // 在记分板上设置玩家的血量
        Score healthScore = objective.getScore("§d血量:");
        healthScore.setScore((int) player.getHealth());
        // 在记分板上设置在线人数
        Score onlinePlayersScore = objective.getScore("§5在线人数: ");
        onlinePlayersScore.setScore(Bukkit.getOnlinePlayers().size());
    }//玩家在加入游戏时触发该事件

    @EventHandler
    public void onPlayerMove(PlayerMoveEvent event) {
        // 获取玩家
        Player player = event.getPlayer();
        // 获取玩家所在的世界
        World world = player.getWorld();

        // 更新玩家的血量
        Score healthScore = objective.getScore("§d血量:");
        healthScore.setScore((int) player.getHealth());

        // 获取玩家的位置
        Location location = player.getLocation();
        // 在记分板上设置坐标
        Score scoreX = objective.getScore("§1X轴:");
        scoreX.setScore((int) location.getX());
        Score scoreY = objective.getScore("§2Y轴:");
        scoreY.setScore((int) location.getY());
        Score scoreZ = objective.getScore("§3Z轴:");
        scoreZ.setScore((int) location.getZ());
    }//玩家在移动时触发这个
    
    
    /*@EventHandler
    public void onPlayerJump(PlayerJumpEvent event) {
        // 获取玩家
        Player player = event.getPlayer();
        // 获取玩家所在的世界
        World world = player.getWorld();
        // 获取玩家的位置
        Location location = player.getLocation();
        // 在记分板上设置坐标
        Score scoreX = objective.getScore("§1X:");
        scoreX.setScore((int) location.getX());
        Score scoreY = objective.getScore("§2Y:");
        scoreY.setScore((int) location.getY());
        Score scoreZ = objective.getScore("§3Z:");
        scoreZ.setScore((int) location.getZ());
    }玩家在跳跃时触发这个,不过先注释掉吧*/
}

然后在主类中注册这个的监听器,只需要在OnEnable里边再加上一行

getServer().getPluginManager().registerEvents(new CoordinatesDisplay(), this);

然后生成新的jar包塞进去就行了,现在不光有死亡坐标播报,还能显示实时坐标,血量啥的

但是比较尴尬的是,记分板好像是按从大到小排列的,所以哪个数大哪个变量就飞上边去了,以后再改吧。

ps:chatGPT真好用啊😭

posted @ 2022-12-28 15:42  拾一贰叁  阅读(1610)  评论(0编辑  收藏  举报