六、定时器
如果你有一定的Java基础,应该知道Runnable和Thread。
BukkitRunnable
是实现了Runnable
的抽象,它还能自我安排和取消。
BukkitRunnable
的实现也不复杂。你在写插件的时候,多多推荐你用BukkitRunnable
。
BukkitRunnable
有着强大的功能,定时开始做任务,互不干扰。
创建
Bukkit有许多线程,使得程序从串行到并发,实现多线程的方法就是重写BukkitRunnable
。
基本套框
class Example extends BukkitRunnable {
@Override
public void run() {
//你需要在运行的时候执行的内容放这里
say("Hello! My dear!");
}
}
我们继承并重载BukkitRunnable
中的run方法,这样就是儿子继承父亲然后变异了。
这样,就是一个能执行任务最基本的套框了。
匿名创建
匿名,没有名字。创建一个没有名字的BukkitRunnable
,这也可以。
new BukkitRunnable() {
@Override
public void run() {
//TODO
}
}
但是,同上面继承创建相比而言,我更喜欢继承创建BukkitRunnable。
匿名创建虽然很便捷,但是用多了会发现代码很乱,有些需重复执行的任务只需创建一个类并调用它就可以了。
自我取消
前面提到过,BukkitRunnable
有一个功能是能够自我的取消。那么,该如何实现呢?
class Example extends BukkitRunnable {
@Override
public void run() {
this.canel();//自我取消
}
}
定时任务
我们想要去做一个任务,但是,我们希望它在某个时刻自动执行,该如何实现呢?
匿名创建实现:
new BukkitRunnable() {
@Override
public void run() {
//TODO
}
}.runTaskTimer(this,0,1*20L);
其中,runTaskTimer的参数分别是主类、延迟时间、多少tick运行一次。
继承创建实现:
class Example extends BukkitRunnable {
@Override
public void run() {
//TODO
}
//任务执行开始函数
public void start(long delay,long time) {
this.runTaskTimer(this.plugin,20L*delay,20L*time);
}
}
重填旧坑
之前讲过,我会讲完定时器,然后做出个非常棒的插件。
那么,首先,先把之前写的代码套上去。
class Example extends BukkitRunnable {
public Plugin plugin;
private World world;
private Block block;
private int x,y,z,i=0;
public Example(Plugin plugin) {
//初始化
world = Bukkit.getWorld("world");
Player player = Tutorial.player;
block = world.getBlockAt(player.getLocation());
x=player.getLocation().getBlockX();
y=player.getLocation().getBlockY();
z=player.getLocation().getBlockZ();
this.plugin=plugin;
}
@Override
public void run() {
i++;
//TODO
Block block2;
block.setType(Material.DIAMOND_BLOCK);
block2 = world.getBlockAt(x+i,y,z);
block2.setType(Material.DIAMOND_BLOCK);
//block,捡石子的人,TA需要跟在block2的后面捡石子,于是乎block本身需要改变TA的位置
block.setType(Material.GRASS_BLOCK);
block = world.getBlockAt(x+i,y,z);
}
//任务执行开始函数
public void start(long delay,long time) {
this.runTaskTimer(this.plugin,20L*delay,20L*time);
}
}
请注意我为什么要把for循环删掉。因为这个任务本身就是一个for,再来个for就显得很多余了。
看要求,需要1秒1秒的执行,那么就是定时任务。
//0->无延迟
//1L-->1秒钟执行一次
new Example(this).start(0,1L);
但是,这种情况并不能无止尽的下去,也就是说,你需要在某个时刻停止执行任务。(很熟悉?——自我取消)。
int s=50,i=0;
@Override
public void run() {
s--;
i++;
//当停止创建方块时
if(s<=0) this.canel();
//TODO
Block block2;
block.setType(Material.DIAMOND_BLOCK);
block2 = world.getBlockAt(x+i,y,z);
block2.setType(Material.DIAMOND_BLOCK);
//block,捡石子的人,TA需要跟在block2的后面捡石子,于是乎block本身需要改变TA的位置
block.setType(Material.GRASS_BLOCK);
block = world.getBlockAt(x+i,y,z);
}
可以看到,上面的代码把我们这次所学的基本套框、自我取消、定时任务完美地融合在了一起。
上一篇:我的世界Bukkit服务器插件开发教程(五)方块Blocks
下一篇:我的世界Bukkit服务器插件开发教程(七)计分板