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真好用啊😭