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

Bukkit中点击方块时PlayerInteractEvent触发两次问题问询

问题分析与解决方案

1. 主手判断逻辑错误

你的代码中用event.getHand().name() != "HAND"过滤副手事件的写法是错误的:

  • Java中字符串比较必须使用equals()方法,!=比较的是对象引用而非内容,即便字符串内容相同,也可能因引用不同导致判断失效,无法过滤副手事件。
  • 更规范的方式是直接比较EquipmentSlot枚举常量,无需转换为字符串。

修正后的判断代码:

// 先导入EquipmentSlot类
import org.bukkit.inventory.EquipmentSlot;

// 替换原判断行
if (event.getHand() != EquipmentSlot.HAND) return;

2. 事件处理器重复注册

如果你的插件主类中多次实例化WandHandler(比如调用了两次new WandHandler(this)),会导致同一个事件处理器被注册多次。每次触发PlayerInteractEvent时,所有注册的处理器都会执行一次,表现为代码逻辑运行两次。

检查主类的onEnable()方法,确保仅实例化一次WandHandler:

public class Jtest extends JavaPlugin {
    @Override
    public void onEnable() {
        new WandHandler(this); // 仅实例化一次
    }
}

3. 可选:过滤多余的交互动作类型

点击方块时,PlayerInteractEvent可能触发不同的Action类型(比如RIGHT_CLICK_BLOCK和PHYSICAL),如果不需要响应这些动作,可以添加过滤逻辑:

import org.bukkit.event.block.Action;

// 在主手判断后添加
if (!event.getAction().equals(Action.RIGHT_CLICK_BLOCK) && !event.getAction().equals(Action.RIGHT_CLICK_AIR)) {
    return;
}

修正后的完整处理器代码

package me.ronking159.jtest.handlers;

import me.ronking159.jtest.items.ItemManager;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.plugin.Plugin;

public class WandHandler implements Listener {
    public WandHandler(Plugin Jtest) {
        Bukkit.getPluginManager().registerEvents(this, Jtest);
    }

    @EventHandler
    public void WandHandler(PlayerInteractEvent event) {
        // 过滤副手事件
        if (event.getHand() != EquipmentSlot.HAND) return;
        // 过滤非右键动作(可选,根据需求调整)
        if (!event.getAction().equals(Action.RIGHT_CLICK_BLOCK) && !event.getAction().equals(Action.RIGHT_CLICK_AIR)) {
            return;
        }
        if (event.getItem() == null) return;
        // 用isSimilar()替代ItemMeta比较,更可靠地判断物品一致性
        if (!event.getItem().isSimilar(ItemManager.wand)) return;

        Player p = event.getPlayer();
        p.getWorld().createExplosion(p.getLocation(), 2.0f);
        p.sendMessage("You don't know how to use a wand yet!");
        p.sendMessage(event.getAction().name());
        p.sendMessage(event.getHand().name());
        p.sendMessage(event.getMaterial().name());
    }
}

注:代码中用isSimilar()替代了ItemMeta.equals(),因为isSimilar()会直接比较两个ItemStack的类型、数据、Meta等核心属性,比单独比较Meta更可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 10:35:41