+倒霉の忍者+
本帖最后由 +倒霉の忍者+ 于 2013-2-24 16:23 编辑

以下内容需要积分高于 20 才可浏览

(注:本帖不回答插件制作相关问题,有问题请到你问我答区发帖)
* 未经许可不得转载本帖内容!



CraftBukkit插件制作 —— 第 叁 章:监听器


前言:
在1.1以前,监听器内的事件方法是以继承方式创建的,名称都是固定的(因为要覆盖),严格而繁琐;
1.1以后,CB作出较大改动,你仅需实现Listener接口,事件方法也变为依靠一个标记(EventHandler)来进行创建,自由且简便。

目前,你可以随意的创建一个监听器,方法也是任意的,只不过不要忘记标记“EventHandler”。

一、创建监听器
0.首先让我们来理解什么是监听器:
当一个玩家在游戏中做出各种行为时,你可能会需要对其控制,比如一名游客,你是不能让他去放置&破坏方块的。
这时你就需要用到监听器,对其进行判断,如果是游客就撤销该行为,如果不是则允许该行为。

1.新建一个类,名字任意(记住第壹章中只能使用英文的说明),但要求它实现“Listener”接口,它看起来应该象这样:
  1. package xxx.xxxxxxx.xxxxxx.xxxx;

  2. import org.bukkit.event.Listener;

  3. public class MyListener implements Listener {

  4. }
复制代码
2.创建一个方法,名字任意,变量为一个代表某一事件的类,我们以BlockBreakEvent事件为例,它看起来应该象这样:
  1.     public void aMethodName(BlockBreakEvent event) {
  2.         //代码
  3.     }
复制代码
3.添加EventHandler标记,你只要在方法上一行,输入“@EventHandler”即可,更改完后的方法代码应该象这样:
  1.     @EventHanlder
  2.     public void aMethodName(BlockBreakEvent event) {
  3.         //代码
  4.     }
复制代码
EventHandler 相关设置:

最后你的监听器看起来应该是这个样子
  1. package xxx.xxxxxxx.xxxxxx.xxxx;

  2. import org.bukkit.event.Listener;

  3. public class MyListener implements Listener {

  4.     @EventHanlder
  5.     public void aMethodName(BlockBreakEvent event) {
  6.         //代码
  7.     }
  8. }
复制代码
除了上面新建一个类作为事件监听器,你还可以在任何类中创建一个事件方法,只要记住2点:
(其实也就是把该类改造成一个监听器)

二、注册监听器
你已经创建了一个监听器,然而现在它只能作为一个摆设而已,你需要在服务器中注册它来使它起作用,调用这个方法:
  1. getServer().getPluginManager().registerEvents(Listener, Plugin);
复制代码
其中Listener处换为你实现该接口的类的对象(需要你自己去实例化),
Plugin则换成代表该插件的对象(在主类里的动态方法中用this关键字获得)。

之后你可以在任何地方来注册该监听器,只要你填入正确的对象(实际操作时是对象的引用)。
一般来说,是在插件加载时进行注册,下面是一个例子:
  1. package xxx.xxxxxxx.xxxxxx.xxxx;

  2. import java.util.logging.Logger;
  3. import org.bukkit.plugin.java.JavaPlugin;
  4. import xxx.xxxxx.xxxxx.xxxx.MyListener;

  5. public class MyPlugin extends JavaPlugin {

  6.     public void onEnable(){
  7.         getServer().getPluginManager().registerEvents(new MyListener(), this);
  8.         getLogger().info("你的插件已被加载!");
  9.     }

  10.     public void onDisable(){
  11.         getLogger().info("你的插件已被卸载。");
  12.     }
  13. }
复制代码
三、注销监听器

注销监听器有2种方式,一种是从单独事件中注销,另一种是从所有事件中注销。
无论是哪种方式,都可以指定某一监听器或插件来注销。

以BlockBreakEvent为例,单独事件注销方法如下:
  1. BlockBreakEvent.getHandlerList().unregister(Listener);
  2. BlockBreakEvent.getHandlerList().unregister(Plugin);
复制代码
从上到下分别是注销监听器中的该事件和插件中的该事件,
这样你就注销了对应对象中所有有关BlockBreakEvent的事件方法。

所有事件注销方法:
  1. HandlerList.unregisterAll();
  2. HandlerList.unregisterAll(Listener);
  3. HandlerList.unregisterAll(Plugin);
复制代码
从上至下分别是注销所有事件,注销监听器中的所有事件,和注销插件中的所有事件。
这样你就把对应对象的所有事件全部注销了。

四、自制事件
自制事件很简单,你只需要记住以下2点即可。

1.在每个事件中都加入Handler相关内容;
在每个自制事件中都要加入1个属性、1个动态方法和1个静态方法:
  1. private static final HandlerList handlers = new HandlerList();

  2. public HandlerList getHandlers() {
  3.     return handlers;
  4. }

  5. public static HandlerList getHandlerList() {
  6.     return handlers;
  7. }
复制代码
原因你可以在上一小节中找到。

我们假设这个事件是这样的:
  1. import org.bukkit.event.Event;
  2. import org.bukkit.event.HandlerList;

  3. public class CustomBlockEvent extends Event {
  4.     private static final HandlerList handlers = new HandlerList();
  5.     private Block block;

  6.     public CustomBlockEvent(Block block) {
  7.         this.block = block;
  8.     }

  9.     public String getBlock() {
  10.         return block;
  11.     }

  12.     public HandlerList getHandlers() {
  13.         return handlers;
  14.     }

  15.     public static HandlerList getHandlerList() {
  16.         return handlers;
  17.     }
  18. }
复制代码
2.触发该事件的方法
首先你要实例化一个事件对象来确定它的属性的内容;
  1. CustomBlockEvent event = new CustomBlockEvent(block);
复制代码
其中block代表某一方块的句柄。

之后触发该事件:
  1. Bukkit.getServer().getPluginManager().callEvent(event);
复制代码
之后监听器该事件的监听器就会按优先级先后调用事件方法。
(Bukkit代表插件系统,可以获得对应服务器,这和你直接在插件中获得的服务器是相同的,性能差别也很小)

监听自制事件和监听服务器自带事件是一样的。

上一章          回到索引          下一章




+倒霉の忍者+
本帖最后由 +倒霉の忍者+ 于 2012-9-4 21:07 编辑

沙发自占
留着备用的

卤蛋你丫的才灌水呢↓

dy2084
虽不明,但觉厉

袁嵩
唉...其实每次都是憧憬地走进这些教学贴,然后失望地走开...
没办法呢...谁叫我们知识有限...看也看不懂咩...也有细心看...可是就是
看不懂呢...也许是厌学心理吧..每次看到这些..就觉得头疼。

之前SimCity的插件我也是学了好久才会。
可是这个怎么就TA丫的看不懂TAT

我觉得我这种天生的傻蛋还是靠边走吧。

袁嵩
还是佩服楼主的耐力啊..
总觉得或许我说的话是错的。
天赋可能某些人要强一些。
可是怎么觉得自己没去努力呢...

虽说 世上无难事 只怕有心人

但是我或许就是个无心人...

某些时候咬咬牙也能学到……

第一页 上一页 下一页 最后一页