+倒霉の忍者+
本帖最后由 +倒霉の忍者+ 于 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

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

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

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

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

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

stlfatboy
希望楼主早日更新,~辛苦了~

Minern
....不会5555楼主怎么获得服务器在线人数

a919298641
表示光是翻译bukkit的 类 都要把我的脑子弄爆了!

a919298641
主要是想翻译到MCBBS上...但是实在是太多了= =所以还是算了吧

leluluxiu
谢谢楼主分享!

a3948982938
本帖最后由 a3948982938 于 2016-2-1 23:44 编辑

ありがとうございます

小本
Lz 你的New Mylistener()
  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. }
复制代码
找了好久都不知道哪里出问题,结果是New要小写丫

+倒霉の忍者+
小本 发表于 2013-2-23 10:24
Lz 你的New Mylistener()找了好久都不知道哪里出问题,结果是New要小写丫

多谢你的提醒,如果你学过JAVA就会知道,这是用来创建实例的

a710128
0.0学习{:10_512:}

YZH20011356810
{:10_566:}大触简直无情,表示才java初学

lzp19990510
牛逼,赞一个先~

hehe123456
你打错了@EventHanlder
你少加了import org.bukkit.event.EventHandler;

mikuand
感谢分享

jerryh96
  1. package xxx.xxxxxxx.xxxxxx.xxxx;
  2. import org.bukkit.event.EventHandler;
  3. import org.bukkit.event.EventPriority;
  4. import org.bukkit.event.Listener;
  5. import org.bukkit.event.block.BlockBreakEvent;

  6. public class MyListener implements Listener {

  7.     @EventHandler(priority = EventPriority.LOW)
  8.     public void aMethodName(BlockBreakEvent event) {
  9.         //代码
  10.     }
  11. }
复制代码
这个是你的新代码





SpiritOfLight
Thx!我等苦于做插件的苦逼也算是有了那么一条出路。。。。。

小飞哥
该写写什么叫en什么什么t什么的,看不懂,很多没说到,比如每个词都是干什么用的

我不叫杨浩
0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0

Hong-Jian
袁嵩 发表于 2012-9-4 21:23
还是佩服楼主的耐力啊..
总觉得或许我说的话是错的。
天赋可能某些人要强一些。

你这种人啊,不出视频不会感兴趣的 = =

残缺的al灬
:看不懂捏= =
:看不懂就走吧

xifengdexi
大触简直无情,表示才java初学

木梁
积分不够看不到`````{:10_527:}

weip
后排支持,谢谢层主

1453844337
高于20分......

Activity
- - 弄那么搞积分干啥。

kjkj2173135
楼主
@EventHanlder是错的
应该是@EventHandler
害得我半天都弄不明白

kjkj2173135
你详解每个单词的意思,不然听不懂

kjkj2173135
aMethodName是一个函数(方法)
BlockBreakEvent是一个类
event 是一个变量

tdiant
kjkj2173135 发表于 2016-2-21 21:36
aMethodName是一个函数(方法)
BlockBreakEvent是一个类
event 是一个变量

Java里根本不存在函数,Java面向对象。
根本就没有解释每个词语的必要,会Java基础就应该能分辨出来。监听器就是一个打@EventHandler的方法。
比如你去买苹果拿回家吃,我还需要给你解释外面套着的是一个塑料袋,里面装的是苹果本体,苹果上面的枝子是与树对接的装置,苹果外面是苹果皮?这种问题只要你知道怎么吃苹果就能知道。

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

import org.bukkit.event.Listener;

public class MyListener implements Listener {

    @EventHanlder
    public void aMethodName(BlockBreakEvent event) {
        //代码
    }
}

叁只技术宅
看看支持一下。

shuai_youxin
看完后表示。。看不懂

hyq510
自定义事件是只能手动触发吗?
那我想要监听玩家死亡应该怎么做

wobo
看不了教程,需要20积分以上才能看

Mubai619
6666666666666

猿汐
感谢dalao的教程,仰慕

gyc-05
膜拜大神

wdadadada
给我看一眼嘛 QAQ

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