Healing/Damage 块输出两次?
Healing/Damage Blocks are outputting twice?
@EventHandler
public void playerInteraction(PlayerInteractEvent event)
{
Action action = event.getAction();
Player player = event.getPlayer();
Block block = event.getClickedBlock();
if (action.equals(Action.RIGHT_CLICK_BLOCK))
{
if (block.getType().equals(Material.NETHER_WART_BLOCK))
{
player.setHealth(player.getHealth() -1);
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_HURT, 10, 1);
}
else if (block.getType().equals(Material.DIAMOND_BLOCK))
{
player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 1000, 2));
player.playSound(player.getLocation(), Sound.ENTITY_SPLASH_POTION_BREAK, 10, 1);
}
else if(block.getType().equals(Material.EMERALD_BLOCK))
{
if (player.getHealth() != 20)
{
player.setHealth(player.getHealth() + 1);
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 10, 1);;
}
if (player.getHealth() == 20)
{
player.sendMessage(ChatColor.DARK_RED + "You are already at full health!");
}
}
}
}
出于某种原因,每当我右键单击指定的块时,所有这些事情都会发生两次。有人知道为什么吗?我把整个方法贴出来了,是玩家互动事件
谢谢:)
首先,请确保您没有注册包含事件处理程序的侦听器 class 两次。
如果情况并非如此,根据 spigot 论坛上的这个帖子,由于 Mojang 将左手插槽添加到 Minecraft,一些事件(如 PlayerInteractEvent 或 InventoryClickEvent)将被调用两次(每只手一次)。
一个可能的解决方法是 "disable" 左手放在事件处理程序上:
@EventHandler
public void onPlayerInteraction(PlayerInteractEvent event) {
if(event.getAction() == Action.RIGHT_CLICK_BLOCK && event.getHand() == EquipmentSlot.HAND) {
//Do something once
}
}
如果您需要双手都可以触发事件,您可以执行以下操作:
- 第一次执行代码时,您将播放器添加到列表中。
- 在执行代码之前,您检查播放器是否在列表中。如果它在列表中,则表示代码已执行一次,因此您可以跳过它。
- 安排一个任务,稍后将玩家从列表中删除。
代码可以如下:
public class Foo implements Listener {
//An instance of the main plugin class
private MainClass plugin;
private List<UUID> playerBlacklist = new ArrayList<>();
@EventHandler
public void onPlayerInteractEvent(PlayerInteractEvent event) {
if(playerBlacklist.contains(event.getPlayer().getUniqueId)) {
return;
} else {
blacklistPlayer(event.getPlayer());
}
//Do something
}
private void blacklistPlayer(UUID uuid) {
playerBlacklist.add(uuid);
BukkitRunnable runnable = new BukkitRunnable(){
@Override
public void run() {
playerBlacklist.remove(uuid);
}
}
runnable.runTaskLaterAsynchronously(plugin, 5L);
}
}
如果这解决了您的问题,请告诉我。
@EventHandler
public void playerInteraction(PlayerInteractEvent event)
{
Action action = event.getAction();
Player player = event.getPlayer();
Block block = event.getClickedBlock();
if (action.equals(Action.RIGHT_CLICK_BLOCK))
{
if (block.getType().equals(Material.NETHER_WART_BLOCK))
{
player.setHealth(player.getHealth() -1);
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_HURT, 10, 1);
}
else if (block.getType().equals(Material.DIAMOND_BLOCK))
{
player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 1000, 2));
player.playSound(player.getLocation(), Sound.ENTITY_SPLASH_POTION_BREAK, 10, 1);
}
else if(block.getType().equals(Material.EMERALD_BLOCK))
{
if (player.getHealth() != 20)
{
player.setHealth(player.getHealth() + 1);
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 10, 1);;
}
if (player.getHealth() == 20)
{
player.sendMessage(ChatColor.DARK_RED + "You are already at full health!");
}
}
}
}
出于某种原因,每当我右键单击指定的块时,所有这些事情都会发生两次。有人知道为什么吗?我把整个方法贴出来了,是玩家互动事件
谢谢:)
首先,请确保您没有注册包含事件处理程序的侦听器 class 两次。
如果情况并非如此,根据 spigot 论坛上的这个帖子,由于 Mojang 将左手插槽添加到 Minecraft,一些事件(如 PlayerInteractEvent 或 InventoryClickEvent)将被调用两次(每只手一次)。
一个可能的解决方法是 "disable" 左手放在事件处理程序上:
@EventHandler
public void onPlayerInteraction(PlayerInteractEvent event) {
if(event.getAction() == Action.RIGHT_CLICK_BLOCK && event.getHand() == EquipmentSlot.HAND) {
//Do something once
}
}
如果您需要双手都可以触发事件,您可以执行以下操作:
- 第一次执行代码时,您将播放器添加到列表中。
- 在执行代码之前,您检查播放器是否在列表中。如果它在列表中,则表示代码已执行一次,因此您可以跳过它。
- 安排一个任务,稍后将玩家从列表中删除。
代码可以如下:
public class Foo implements Listener {
//An instance of the main plugin class
private MainClass plugin;
private List<UUID> playerBlacklist = new ArrayList<>();
@EventHandler
public void onPlayerInteractEvent(PlayerInteractEvent event) {
if(playerBlacklist.contains(event.getPlayer().getUniqueId)) {
return;
} else {
blacklistPlayer(event.getPlayer());
}
//Do something
}
private void blacklistPlayer(UUID uuid) {
playerBlacklist.add(uuid);
BukkitRunnable runnable = new BukkitRunnable(){
@Override
public void run() {
playerBlacklist.remove(uuid);
}
}
runnable.runTaskLaterAsynchronously(plugin, 5L);
}
}
如果这解决了您的问题,请告诉我。