2016-11-14 4 views
1

Недавно я начал разрабатывать плагин Bukkit, и мне нужна помощь в спящем/ожидании в моем коде. Я новичок в java, поэтому, если бы вы могли это объяснить, я был бы признателен. Вот мой код:bukkit - Ожидание?

@EventHandler 
public void onTnt(PlayerInteractEntityEvent e) { 
    Player clicker = e.getPlayer(); 
    Player rightclick = (Player) e.getRightClicked(); 
    rightclick.sendMessage(ChatColor.GRAY + "~" + ChatColor.DARK_PURPLE + "AN INSTAKILLER HAS YOU AS A TARGET! SNEAK NOW!"); 
    rightclick.sendMessage(ChatColor.GRAY + "~" + ChatColor.DARK_RED + "AN INSTAKILLER HAS YOU AS A TARGET! SNEAK NOW!"); 
    rightclick.sendMessage(ChatColor.GRAY + "~" + ChatColor.GOLD + "AN INSTAKILLER HAS YOU AS A TARGET! SNEAK NOW!"); 
    /* Then wait 3 sec. I've tried Thread.Sleep, wait() and sleep(), no sucess*/ 

    if (!(rightclick.isSneaking())) { 
     rightclick.sendMessage(ChatColor.GRAY + "~" + ChatColor.GOLD + "Bye bye."); 
     rightclick.setHealth(0); 

    } 

} 
+0

Я не думаю, что ожидание или сон правильная идея здесь, сделать новый bukkitrunnable и график его работы в 3 секунды, чтобы не сгладить поток вашего плагина – zack6849

ответ

2

Хотя обычно вы будете использовать Thread.sleep что-то вроде этого, что бы заморозить весь сервер, а события не будут обработаны в то время (так что даже если игрок остановил пробирается на их сторона, они все еще будут красться от того, что видит сервер).

Что вам нужно сделать, это использовать BukkitRunnable (или в качестве альтернативы регулярным Runnable и getServer().getScheduler().scheduleSyncDelayedTask):

@EventHandler 
public void onTnt(PlayerInteractEntityEvent e) { 
    Player clicker = e.getPlayer(); 
    // Needs to be final to reference it later 
    final Player rightclick = (Player) e.getRightClicked(); 
    rightclick.sendMessage(ChatColor.GRAY + "~" + ChatColor.DARK_PURPLE + "AN INSTAKILLER HAS YOU AS A TARGET! SNEAK NOW!"); 
    rightclick.sendMessage(ChatColor.GRAY + "~" + ChatColor.DARK_RED + "AN INSTAKILLER HAS YOU AS A TARGET! SNEAK NOW!"); 
    rightclick.sendMessage(ChatColor.GRAY + "~" + ChatColor.GOLD + "AN INSTAKILLER HAS YOU AS A TARGET! SNEAK NOW!"); 


    BukkitRunnable task = new BukkitRunnable() { 
     @Override 
     public void run() { 
      if (!(rightclick.isSneaking())) { 
       rightclick.sendMessage(ChatColor.GRAY + "~" + ChatColor.GOLD + "Bye bye."); 
       rightclick.setHealth(0); 
      } 
     } 
    }; 
    // Run the task on this plugin in 3 seconds (60 ticks) 
    task.runTaskLater(this, 20 * 3); 
} 
0

Я отдаю себе отчет в том, что это старый вопрос, но я хотел бы добавить то, что пользователи, которые будут искать способ сделать, могут найти это.

Простейшим сказать, чтобы сделать это создает запланированное задание:

Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() { 
// The stuff which should be accomplished after the timer runs out goes here. 
// Example: 
player.sendMessage("The time has ran out!"); 
}, time); 

Теперь давайте пройти через процесс понимания того, что происходит здесь. В принципе, они создали задержанную задачу (есть два типа запланированных задач: отложенные и повторяющиеся задачи). Первый аргумент метода выше - this. Предполагается, что это экземпляр вашего основного класса (подкласс org.bukkit.plugin.java.JavaPlugin). Это означает, что если запланированное задание не входит в ваш основной класс, вам нужно будет заменить его экземпляром. Второй аргумент new Runnable() { ... } здесь мы фактически создаем runnable. Независимо от того, что должно быть выполнено, когда таймер заканчивается, следует зайти в фигурные скобки. Наконец, последний параметр: это фактическая задержка, измеренная в TICKS. Это означает, что если вы хотите подождать x секунд, вам придется умножить x * 20, так как отметка равна 1/20 секунды, поэтому 5 секунд будут равны 100 тикам.

Если вы знаете, как использовать лямбды, вы можете заменить анонимный класс:

Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(this,() -> player.sendMessage("The time has ran out!"), time);