Minecraft Bukkit插件无法生成FallingBlock下落方块问题求助
问题根源梳理
- 致命问题1:主类
Main的getInstance()静态方法返回null,调用Bukkit.getScheduler().runTaskTimer时传入空的插件实例,直接触发空指针异常,调度任务根本无法启动 - 致命问题2:实例化
SandBotListener后没有注册到Bukkit事件系统,BlockPlaceEvent事件根本不会触发,放置海晶灯没有任何回调执行 - 逻辑问题:当前下落方块生成位置是海晶灯本身的坐标,没有调整到海晶灯下方,不符合需求
- 潜在问题:
keepToSpawn是类成员变量,同时放置多个海晶灯时会出现计数冲突,导致任务提前终止
修复后代码
主类 Main.java
package me.zavage.sandbot; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import me.zavage.sandbot.commands.SandBotCommand; import me.zavage.sandbot.listeners.SandBotListener; public class Main extends JavaPlugin { // 新增静态实例存储 private static Main instance; @Override public void onEnable() { instance = this; // 注册监听器到事件系统 getServer().getPluginManager().registerEvents(new SandBotListener(this), this); new SandBotCommand(this); } public static Plugin getInstance() { // 返回正确的插件实例 return instance; } }
监听器 SandBotListener.java
package me.zavage.sandbot.listeners; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.FallingBlock; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.scheduler.BukkitTask; import org.bukkit.util.Vector; import me.zavage.sandbot.Main; public class SandBotListener implements Listener { public SandBotListener(Main main) { } @EventHandler public void onPlaceSandbot(BlockPlaceEvent e) { Material spawnType = e.getBlockPlaced().getType(); if(!spawnType.equals(Material.SEA_LANTERN)) return; // 将计数变量改为局部变量,避免多实例冲突 int keepToSpawn = 5; // 调整生成位置到海晶灯正下方 Location loc = e.getBlock().getLocation().add(0, -1, 0); BukkitTask task = Bukkit.getScheduler().runTaskTimer(Main.getInstance(), () -> { run(loc); keepToSpawn--; if(keepToSpawn == 0) task.cancel(); }, 10, 10); } @SuppressWarnings("deprecation") private void run(Location loc) { FallingBlock falling = loc.getWorld().spawnFallingBlock(loc, Material.SAND, (byte) 0); falling.setDropItem(true); falling.setVelocity(new Vector(0, -0.5, 0)); } }
额外注意事项
- 如果你使用的是1.13+版本的BukkitAPI,
spawnFallingBlock的过时方法可以替换为spawnFallingBlock(loc, Material.SAND.createBlockData()),无需再传入byte类型的数据值 - 若不需要沙子下落破坏后掉落物品,可以将
falling.setDropItem(true)改为false避免生成多余物品
内容的提问来源于stack exchange,提问作者Zavage
相关产品推荐
相关产品推荐

