用BukkitRunnable做一个简单的定时距离检测插件

由于Spigot等MineCraft服务器是单线程的,因此,要实现定时执行操作的话,需要在插件中用到一个类似Runnable的类来执行相关操作。‘

定义一个实现BukkitRunnable接口的类:
将要延时执行,或者重复执行的内容放在这个类的run方法里。在它被实例化后,便可以用一系列属于BukkitRunnable的方法,灵活地调用run方法。

传入plugin是因为通过plugin可以得到对应的服务器,利用服务器可以做各种其他操作,比如最常见的广播。

import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;

public class ExampleTask extends BukkitRunnable {

    private final JavaPlugin plugin;

    public ExampleTask(JavaPlugin plugin) {
        this.plugin = plugin;
    }

    @Override
    public void run() {
        // 你需要在运行的时候执行的内容放这
        plugin.getServer().broadcastMessage("Welcome to Bukkit! Remember to read the documentation!");
    }

}

接下来在就是在某个地方实例化这个类,并用这个类的相关方法调用run。这里Bukkit主流的教程定义了一个监听器,我们直接一点,就在onEnable方法中实例化和调用

import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;

public final class ExamplePlugin extends JavaPlugin {

    @Override
    public void onEnable() {
        new ExampleListener(this);
    }
}

class ExampleListener implements Listener {

    private final ExamplePlugin plugin;

    public ExampleListener(ExamplePlugin plugin) {
        this.plugin = plugin;
        plugin.getServer().getPluginManager().registerEvents(this, plugin);
    }

    @EventHandler
    public void onJoin(PlayerJoinEvent event) {
        // 创建定时任务
        BukkitTask task = new ExampleSelfCancelingTask(this.plugin, 5).runTaskTimer(this.plugin, 10, 20);
    }

}

以下为插件源码:
这个文件很简单,直接new一个Runnable实例,接着调用就好了。
DisTest.java

package com.mcbbs.DisTest;
import java.util.HashMap;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitTask;

public class DisTest extends JavaPlugin  {
	static public HashMap<String,Player> playerList;
	
	@Override
	public void onEnable() {
		getLogger().info("DisTest enable!");
		//new出任务,延时0L,每20L执行一次
		BukkitTask task=new UpdateDis(this).runTaskTimer(this, 0, 20L);
		
	}
}

这个地方主要是两步。首先要一直查找主玩家。主玩家没到是不进行计算的。
接着对所有在线玩家计算他们与主玩家之间的欧拉距离,每次计算的时候更新一下最小值。

UpdateDis.java

package com.mcbbs.DisTest;

import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;

public class UpdateDis extends BukkitRunnable {
	private final JavaPlugin plugin;
	private Player mainPlayer;//主玩家
	private double minDis;//每次检测的最小距离
	//构造函数
	public UpdateDis(JavaPlugin plugin) {
		minDis=99999;
		this.plugin=plugin;
	}
	
	//run中写每次执行的逻辑
	@Override
	public void run() {
	//找主玩家
		if(Bukkit.getServer().getPlayer("jie")==null) {
			//主玩家没有到服务器
			Bukkit.getLogger().info("finding jie...");
			return;
		}
		else {
			Bukkit.getLogger().info("found jie!");
			mainPlayer=Bukkit.getServer().getPlayer("jie");
		}
	
	   //更新主玩家与所有玩家中的最小的距离
		updateDis();
		
		//广播最小距离
		plugin.getServer().broadcastMessage("the min dis from jie is"+minDis);
		
	}
	
	//更新最小距离
	public void updateDis() {
		minDis=99999;
		double mx=mainPlayer.getLocation().getX();
		double my=mainPlayer.getLocation().getY();
		double mz=mainPlayer.getLocation().getZ();
		//遍历当前所有玩家
		for(Player player:Bukkit.getServer().getOnlinePlayers()) {
			if(player.getUniqueId().equals(mainPlayer.getUniqueId())) {
				continue;
			}
			double px=player.getLocation().getX();
			double py=player.getLocation().getY();
			double pz=player.getLocation().getZ();
			
			double currentDis=Math.sqrt((px-mx)*(px-mx)+(py-my)*(py-my)+(pz-mz)*(pz-mz));
			if(currentDis<minDis) {
				minDis=currentDis;
			}
		}
	}
}

很简单的小插件,主要是遍历玩家+重复运行逻辑的实现

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 Bukkit 中实现延迟1秒的十次循环,你可以使用 `BukkitScheduler` 类的 `runTaskTimer()` 方法。这个方法可以用来调度一个重复执行的任务,并指定延迟和间隔时间。 以下是一个示例代码,展示了如何实现延迟1秒的十次循环: ```java import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitRunnable; public class MyPlugin extends JavaPlugin { @Override public void onEnable() { // 在件启用时调度一个重复执行的任务 int delayTicks = 20; // 20个游戏刻(1秒) int intervalTicks = 20; // 20个游戏刻(1秒) int totalIterations = 10; // 循环次数 Bukkit.getScheduler().runTaskTimer(this, new MyTask(), delayTicks, intervalTicks); } private class MyTask extends BukkitRunnable { private int iterations = 0; @Override public void run() { if (iterations < 10) { // 在这里编写你想要重复执行的任务的代码 // 例如,发送一条消息到控制台 getLogger().info("重复执行的任务:" + iterations); iterations++; } else { cancel(); // 达到循环次数后取消任务 } } } } ``` 在上述示例中,我们创建了一个继承自 `BukkitRunnable` 的内部类 `MyTask`,并重写了 `run` 方法。`iterations` 变量用于计算循环次数,初始值为 0。在 `run` 方法中,我们首先检查 `iterations` 是否小于 10,如果是,则执行任务代码并递增 `iterations`。如果 `iterations` 达到了 10,就调用 `cancel()` 方法来取消任务。 通过使用 `runTaskTimer()` 方法,并指定延迟和间隔时间,我们可以实现一个延迟1秒的十次循环的任务。你可以根据自己的需求来调整延迟、间隔和循环次数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值