You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bukkit插件问题:点击橡木按钮无法销毁按钮及下方煤炭块求助

问题与解决:点击橡木按钮销毁自身及下方煤炭块(无掉落物)

问题描述

我希望实现点击橡木按钮时,销毁该橡木按钮及其下方的煤炭块,且煤炭块无需产生掉落物。但实际运行时触发了空指针异常,且使用getDrops().clear()无法阻止煤炭块掉落物生成。

原代码

package me.doshicshow.mycustomitems;

import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Block;
import java.util.logging.Logger;

public class Customitems extends JavaPlugin implements Listener {
    private static Logger log = Logger.getLogger("Minecraft");
    @Override
    public void onEnable() {
        getServer().getPluginManager().registerEvents(this, this);
    }

    @EventHandler
    public void onPlayerInteract(PlayerInteractEvent event) {
        if (event.getClickedBlock() != null && event.getClickedBlock().getType() == Material.OAK_BUTTON && event.getClickedBlock().getRelative(BlockFace.DOWN).getType() == Material.COAL_BLOCK) {
            log.info(String.format("Found object %s", event.getClickedBlock()));
            event.getClickedBlock().breakNaturally();
            event.getClickedBlock().getDrops().clear();
            event.getClickedBlock().getRelative(BlockFace.DOWN).getDrops().clear();
            event.getClickedBlock().getRelative(BlockFace.DOWN).breakNaturally();
        }
    }
}

问题分析

  1. 空指针异常原因:调用breakNaturally()后,方块已被销毁,此时再通过event.getClickedBlock()获取方块并调用getDrops(),会因为方块不存在触发空指针。
  2. getDrops().clear()无效原因:getDrops()返回的是当前方块掉落物的副本集合,清空副本不会影响实际掉落;且breakNaturally()调用时就已经生成了掉落物,后续清空操作完全无效。

修改后的代码

package me.doshicshow.mycustomitems;

import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.logging.Logger;

public class Customitems extends JavaPlugin implements Listener {
    private static final Logger log = Logger.getLogger("Minecraft");

    @Override
    public void onEnable() {
        getServer().getPluginManager().registerEvents(this, this);
    }

    @EventHandler
    public void onPlayerInteract(PlayerInteractEvent event) {
        Block clickedBlock = event.getClickedBlock();
        // 先判空并检查是否为橡木按钮
        if (clickedBlock == null || clickedBlock.getType() != Material.OAK_BUTTON) {
            return;
        }
        
        Block coalBlock = clickedBlock.getRelative(BlockFace.DOWN);
        // 检查下方是否为煤炭块
        if (coalBlock.getType() != Material.COAL_BLOCK) {
            return;
        }

        log.info(String.format("Found object %s", clickedBlock));
        
        // 直接设为AIR移除方块,无掉落物
        clickedBlock.setType(Material.AIR);
        coalBlock.setType(Material.AIR);
    }
}

修改说明

  • 提前获取方块引用:先把橡木按钮和下方煤炭块的引用存起来,避免销毁后找不到对象导致空指针。
  • 用setType(Material.AIR)替代breakNaturally():这个方法直接移除方块,不会触发任何掉落物生成,完美满足煤炭块无掉落的需求;如果需要橡木按钮正常产生掉落,把clickedBlock.setType(Material.AIR)替换为clickedBlock.breakNaturally()即可。
  • 拆分判断条件:减少嵌套层级,代码更易读,也能提前过滤不符合条件的情况。

内容的提问来源于stack exchange,提问作者Doshic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 06:08:17