4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PlayerInteractEventを2回連続で反応しないようにする

Posted at

PlayerInteractEventについて

Spigotにて、プレイヤーがクリックしたときに呼ばれるイベントです。

例えば、棒を右クリックしたときに処理が実行される場合以下のように書けます

class ItemListener(private val plugin: SamplePlugin) : Listener {

    init {
        plugin.server.pluginManager.registerEvents(this, plugin)
    }

    @EventHandler
    fun ckickItem(event: PlayerInteractEvent) {
        val player = event.player
        if (event.action == Action.RIGHT_CLICK_AIR || event.action == Action.RIGHT_CLICK_BLOCK) {
            val itemStack = player.inventory.itemInMainHand
       
            if (itemStack.type == Material.STICK) {
                // 処理を書く
                event.isCancelled = true
            }
        }
    }
}

しかし、このように書くと、処理は実行されますが、1回のクリックに付きイベントが2回呼び出されて、処理が2回実行されてしまいます。

対処方針

  • プレイヤーがPlayerInteractEventを実行すると、プレイヤーにメタデータとしてフラグを持たせる
  • プレイヤーにフラグが存在する場合、PlayerInteractEventをスキップするようにする
  • 一定時間経過後にフラグを消す

実際のコード

以下のようなPlayerFlagというクラスを作りました
メタデータにtrueをセットし、一定時間経過後にfalseにセットします。

class PlayerFlag(val player: Player, val plugin: SamplePlugin) {

    fun set() {
        setMetadata(true)
        object : BukkitRunnable() {
            override fun run() {
                setMetadata(false)
            }
        }.runTaskLater(plugin, 10)
    }

    private fun setMetadata(flag: Boolean) {
        player.setMetadata("PlayerInteractEvent", FixedMetadataValue(plugin, flag))
    }

    fun get(): Boolean {
        try {
            return player.getMetadata("PlayerInteractEvent")[0].value() as Boolean
        } catch (e: Exception) {
            return false
        }
    }
}

ListenerにPlayerFlagのコードを追加します

class ItemListener(private val plugin: SamplePlugin) : Listener {

    init {
        plugin.server.pluginManager.registerEvents(this, plugin)
    }

    @EventHandler
    fun ckickItem(event: PlayerInteractEvent) {
        val player = event.player

        //追加したところ
        val playerFlag = PlayerFlag(player, plugin)
        if (playerFlag.get()) {
            return
        }

        if (event.action == Action.RIGHT_CLICK_AIR || event.action == Action.RIGHT_CLICK_BLOCK) {
            val itemStack = player.inventory.itemInMainHand
       
            if (itemStack.type == Material.STICK) {
                //追加したところ
                playerFlag.set()

                // 処理を書く
                event.isCancelled = true
            }
        }
    }
}

このようにして2回反応してしまう現象を防げます。

4
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?