第一章 第三节 如何编写监听器
参与编写者: MagicLu550,innc11,smartcmd
建议学习时间: 30分钟
学习要点: 学习如何构建一个简单的监听器,和自己构造事件
nukkit插件最主要的运行方式就是:
1 | 事件被触发 -> 执行动作 |
所以说监听器是插件中非常重要的部分
其实看一看这章,没有啥可讲的。监听器的内容很简单,很多人认识它的困难主要是概念上,
而不是使用上。
注册监听器有两个步骤: 1.定义监听器 2.注册监听器
nukkit监听器的构成: 事件监听和优先级
nukkit的监听器是通过 反射(reflect) 实现的,因此基于它,开发者容易上手,且上手
更简便。nukkit的监听器设计形同bukkit,也易于bukkit上手
nukkit声明一个事件的监听管理器是通过注解实现的,即@EventHandler
@EventHandler的源码如图
1 | package cn.nukkit.event; |
第一个是优先级,第二个是是否忽略事件被取消
默认的优先级是normal,从注释可以知道,这是他们的先后顺序,LOWEST会最先被调用,其次是LOW,最后是MONITOR,如果在LOWEST监听器中调用了Event.setCancelled(true),Nukkit则会忽略掉后面的 ignoreCancelled 被设置为true或者保持默认的优先级更高的监听器
-
EventPriority.LOWEST
-
EventPriority.LOW
-
EventPriority.NORMAL
-
EventPriority.HIGH
-
EventPriority.HIGHEST
-
EventPriority.MONITOR
而实现监听器的优先级标记是通过 枚举(Enum) 实现的
优先级的目的是为了保证监听器按照顺序执行,以使得一个监听器操作完会
进入下一个监听器继续执行,以确保执行的有序性。下一个监听器的相同操作
会覆盖之前监听器的相同操作。
同时,事件可以被我手动取消的,但是有时候事件虽然取消,但依然需要操作,
那么ignoreCancelled可以发挥作用了,当然默认是忽略掉取消的事件,也就是
说取消的事件默认不会被监听(这里可能有所错误,我这个不太常用)
一个EventHandler基本都是监听一个事件的(我只尝试过一个事件的),代码中
这样使用
1 | package net.noyark.www; |
这里的意思就是当玩家进入服务器时,就会触发PlayerJoinEvent事件,服务器会
形成一个PlayerJoinEvent对象,并且调用先前注册的有关PlayerJoinEvent的
EventHandler,将对象传入,这样就实现了一个 事件的调用
获取对象的内容,则通过e调用即可,我们不需要很明白它的具体细节,只需要知道,
使用EventHandler注解的方法(且有一个Event的子类类型参数,并且它所在的监听器被注册),
就会在事件发生时,相应的被调用,如上文所讲,这里的代码案例就是当发生玩家加入时,
这个onPlayerJoin方法会被服务端调用。
1 | package net.noyark.www; |
例如这个代码,在玩家加入时,将会向玩家发送一个"你好 玩家的名字",这就是
我们监听器的作用
1 | package net.noyark.www; |
如果要使用我们之前所说的参数,则这样使用。
事实上,监听器的基本使用方式也就这些,nukkit也提供了很多事件给予我们使用,也允许我们
自己制作事件自己使用,在第二部分中,我们将会讲解提供了哪些事件
如何自己定义一个事件
事实上,nukkit的事件是通过callEvent调用的,所以,我们同样可以通过callEvent实现我们自己
的事件。
1 | this.getServer().getPluginManager().callEvent(Event e); |
首先我们先定义一个事件类
1 | package net.noyark.www; |
之后,我们在监听器使用我们的事件
1 | package net.noyark.www; |
之后,我们就可以使用我们的事件了。
1 | this.getServer().getPluginManager().registerEvents(new OtherListener(),this); |
如何触发我们的事件?
事件的触发则通过callEvent触发,假如,我们写一个玩家假如时,如果他的
名字叫abc,就触发MyEvent事件
1 | package net.noyark.www; |
这里,我们完成了我们的自定义事件
假如我们要注册一个EventHandler,不去注册其他的该如何。
事实上,可以实现这个,nukkit提供了registerEvent方法,
可以注册单个EventHandler,但不太常用,我这里也不会再过多
阐述了,如果想了解,可以发issue,我将会添加这方面的内容