Bukkit 在 For 循环中延迟任务
Bukkit Delayed Task Inside a For Loop
我一直在尝试为 Bukkit 制作枪支插件,并且我正在尝试构建连发射击功能。我有一个包含延迟任务的 for 循环,在该延迟任务中是创建子弹的代码等等。从理论上讲,代码会添加一些项目符号,等待一次,然后添加更多项目符号,等待一次,等等,直到 for 循环完成。
public void fire(final Player p, final Gun g) {
for(int i=0; i<shotsPerBurst; i++) {
Bukkit.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, new Runnable() {
public void run() {
for(int i=0; i<bulletsPerShot; i++) {
Bullet b = new Bullet(p, g);
GunsV1.bullets.add(b);
}
}
}, 1L);
}
}
Eclipse 要求 Player p 和 Gun g 都是 final,我不知道为什么,当我尝试 运行 fire(p, g) 时,没有任何反应。我如何设置我的代码,以便 for 循环 运行 在循环之间延迟 1 个滴答?
解决一个问题:
Eclipse demands that Player p and Gun g both be final, I don't know why
您正在将 Player p
和 Gun g
传递给 new Thread
/new Runnable
,Eclipse 告诉您这 2 个 Object
应该不会被修改或更改,因为 Thread
/Runnable
也在 运行 方法中使用了这两个对象(如您所见)。
我建议您直接在这里写下您的问题:http://bukkit.org/forums/plugin-development.5/ 因为也有开发者对 Bukkit Server for Minecraft 了解得更多更详细。
我现在会尝试找到适合您需求的解决方案 - 但也许您已经尝试在论坛中找到解决方案。
为您找到了这个 link - 它可能会对您有所帮助:http://www.programcreek.com/java-api-examples/index.php?api=org.bukkit.scheduler.BukkitScheduler
在不冻结 Bukkit 的主线程的情况下,没有 简单 方法可以延迟 运行 for
循环。在这种情况下最好的办法是使用 plugin.getServer().getScheduler().runTaskLater()
:
plugin.getServer().getScheduler().runTaskLater(plugin, new Runnable(){
public void run(){
//shoot the gun
}
},1L);//run after 1 tick
但是,如果你使用这个,枪只会开一枪。要解决此问题,您应该 运行ning 调度程序:
public static void runTask(){
plugin.getServer().getScheduler().runTaskLater(plugin, new Runnable(){
public void run(){
//shoot the gun
runTask(); //run the task again
}
},1L);//run after 1 tick
}
但这样一来,枪就会一直开火,永远不会停止。因此,您应该计算它的次数 运行,并在达到该次数后停止 运行 任务:
public static void runTask(final int timesLeft){
plugin.getServer().getScheduler().runTaskLater(plugin, new Runnable(){
public void run(){
//shoot the gun
if(timesLeft > 0){
runTask(timesLeft - 1); //run the task again after removing from the times left
}
}
},1L);//run after 1 tick
}
因此,最后,您的循环方法可能如下所示:
public static void fire(final Player player, final Gun gun, final int timesLeft){
plugin.getServer().getScheduler().runTaskLater(plugin, new Runnable(){
public void run(){
Bullet bullet = new Bullet(player, gun);
GunsV1.bullets.add(bullet);
if(timesLeft > 0){
fire(player, gun, timesLeft - 1); //run the task again after removing from the times left
}
}
},1L);//run after 1 tick
}
您可以使用以下方式调用它:
fire(player, gun, shotsPerBurst);
在尝试了一些更长的延迟并查看了 spigot 参考之后,我意识到延迟的滴答声不是直到下一个任务才滴答,而是直到可运行对象运行。知道了这一点,我就能够使用 for 循环按比例增加延迟的滴答声:
public void fire(final Player p, final Gun g) {
for(int i=0; i<shotsPerBurst; i++) {
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
public void run() {
for(int i=0; i<bulletsPerShot; i++) {
Bullet b = new Bullet(p, g);
GunsV1.bullets.add(b);
}
}
}, i*3);
}
}
现在它在前一个任务之后运行每个任务三个滴答,并突发
我一直在尝试为 Bukkit 制作枪支插件,并且我正在尝试构建连发射击功能。我有一个包含延迟任务的 for 循环,在该延迟任务中是创建子弹的代码等等。从理论上讲,代码会添加一些项目符号,等待一次,然后添加更多项目符号,等待一次,等等,直到 for 循环完成。
public void fire(final Player p, final Gun g) {
for(int i=0; i<shotsPerBurst; i++) {
Bukkit.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, new Runnable() {
public void run() {
for(int i=0; i<bulletsPerShot; i++) {
Bullet b = new Bullet(p, g);
GunsV1.bullets.add(b);
}
}
}, 1L);
}
}
Eclipse 要求 Player p 和 Gun g 都是 final,我不知道为什么,当我尝试 运行 fire(p, g) 时,没有任何反应。我如何设置我的代码,以便 for 循环 运行 在循环之间延迟 1 个滴答?
解决一个问题:
Eclipse demands that Player p and Gun g both be final, I don't know why
您正在将 Player p
和 Gun g
传递给 new Thread
/new Runnable
,Eclipse 告诉您这 2 个 Object
应该不会被修改或更改,因为 Thread
/Runnable
也在 运行 方法中使用了这两个对象(如您所见)。
我建议您直接在这里写下您的问题:http://bukkit.org/forums/plugin-development.5/ 因为也有开发者对 Bukkit Server for Minecraft 了解得更多更详细。
我现在会尝试找到适合您需求的解决方案 - 但也许您已经尝试在论坛中找到解决方案。
为您找到了这个 link - 它可能会对您有所帮助:http://www.programcreek.com/java-api-examples/index.php?api=org.bukkit.scheduler.BukkitScheduler
在不冻结 Bukkit 的主线程的情况下,没有 简单 方法可以延迟 运行 for
循环。在这种情况下最好的办法是使用 plugin.getServer().getScheduler().runTaskLater()
:
plugin.getServer().getScheduler().runTaskLater(plugin, new Runnable(){
public void run(){
//shoot the gun
}
},1L);//run after 1 tick
但是,如果你使用这个,枪只会开一枪。要解决此问题,您应该 运行ning 调度程序:
public static void runTask(){
plugin.getServer().getScheduler().runTaskLater(plugin, new Runnable(){
public void run(){
//shoot the gun
runTask(); //run the task again
}
},1L);//run after 1 tick
}
但这样一来,枪就会一直开火,永远不会停止。因此,您应该计算它的次数 运行,并在达到该次数后停止 运行 任务:
public static void runTask(final int timesLeft){
plugin.getServer().getScheduler().runTaskLater(plugin, new Runnable(){
public void run(){
//shoot the gun
if(timesLeft > 0){
runTask(timesLeft - 1); //run the task again after removing from the times left
}
}
},1L);//run after 1 tick
}
因此,最后,您的循环方法可能如下所示:
public static void fire(final Player player, final Gun gun, final int timesLeft){
plugin.getServer().getScheduler().runTaskLater(plugin, new Runnable(){
public void run(){
Bullet bullet = new Bullet(player, gun);
GunsV1.bullets.add(bullet);
if(timesLeft > 0){
fire(player, gun, timesLeft - 1); //run the task again after removing from the times left
}
}
},1L);//run after 1 tick
}
您可以使用以下方式调用它:
fire(player, gun, shotsPerBurst);
在尝试了一些更长的延迟并查看了 spigot 参考之后,我意识到延迟的滴答声不是直到下一个任务才滴答,而是直到可运行对象运行。知道了这一点,我就能够使用 for 循环按比例增加延迟的滴答声:
public void fire(final Player p, final Gun g) {
for(int i=0; i<shotsPerBurst; i++) {
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
public void run() {
for(int i=0; i<bulletsPerShot; i++) {
Bullet b = new Bullet(p, g);
GunsV1.bullets.add(b);
}
}
}, i*3);
}
}
现在它在前一个任务之后运行每个任务三个滴答,并突发