Вопрос Как получать игроков в радиусе 15 блоков?

Версия Minecraft
1.16.X

Mikita

Заблокирован
Сообщения
57
Решения
3
Всем привет, как получать игроков в 15 блоках? К примеру когда игрок кликает на что либо, мы получаем вокруг его игроков которые попали в радиус (15 радиус).
 
Решение
Код:
        Location location = ...;
        List<Player> players = new ArrayList<>();
        for (Player player : Bukkit.getOnlinePlayers()) {
            if (player.getWorld() == location.getWorld() && player.getLocation().distance(location) <= 15) {
                players.add(player);
            }
        }


Код:
        Location location = ...;
        List<Player> players = Bukkit.getOnlinePlayers().stream()
                .filter(player -> player.getWorld() == location.getWorld() && player.getLocation().distance(location) <= 15)
                .collect(Collectors.toList());

Код:
        Location location = ...;
        List<Player> players = location.getNearbyEntities(15, 15, 15).stream()
                .filter(entity ->...
Код:
        Location location = ...;
        List<Player> players = new ArrayList<>();
        for (Player player : Bukkit.getOnlinePlayers()) {
            if (player.getWorld() == location.getWorld() && player.getLocation().distance(location) <= 15) {
                players.add(player);
            }
        }


Код:
        Location location = ...;
        List<Player> players = Bukkit.getOnlinePlayers().stream()
                .filter(player -> player.getWorld() == location.getWorld() && player.getLocation().distance(location) <= 15)
                .collect(Collectors.toList());

Код:
        Location location = ...;
        List<Player> players = location.getNearbyEntities(15, 15, 15).stream()
                .filter(entity -> entity.getType() == EntityType.PLAYER).map(entity -> (Player) entity)
                .toList();

Любой из вариантов имеет шансы на жизнь, нужно тестить по нагрузке, третий способ нельзя использовать в асинхроне, что печалит, я чаще всего использую первый способ, можно не добавлять в лист игроков, а сразу выполнять над игроком какие-либо действия, например, отправлять ему сообщения и код будет выглядеть так

Код:
        Location location = ...;
        String message = "message";
        for (Player player : Bukkit.getOnlinePlayers()) {
            if (player.getWorld() == location.getWorld() && player.getLocation().distance(location) <= 15) {
                player.sendMessage(message);
            }
        }
 
Java:
final Location location = // твоя локация
   
final Collection<Entity> nearbyPlayers = location.getWorld().getNearbyEntities(
    location, 15, 15, 15, entity -> entity.getType() == EntityType.PLAYER
);

// тут уже можешь сделать что угодно, например совершить апкаст сущностей до игроков
nearbyPlayers.stream()
    .map(entity -> (Player) entity)
    .forEach(player -> player.sendMessage("Ты попался в мой радиус"))

Это решение наиболее правильное в большинстве случаев
 
Java:
final Location location = // твоя локация
  
final Collection<Entity> nearbyPlayers = location.getWorld().getNearbyEntities(
    location, 15, 15, 15, entity -> entity.getType() == EntityType.PLAYER
);

// тут уже можешь сделать что угодно, например совершить апкаст сущностей до игроков
nearbyPlayers.stream()
    .map(entity -> (Player) entity)
    .forEach(player -> player.sendMessage("Ты попался в мой радиус"))

Это решение наиболее правильное в большинстве случаев
Видел как-то в плагине реализацию синхронного таймера, в котором очень часто использовался метод World#getNearbyEntities(), ко мне обращались, чтобы оптимизировать плагин, а единственная проблема нагрузки была так это в синхронном таймере, который имел очень массивный код, а из-за большого количества синхронных методов, которые нельзя выполнять в асинхроне, пришлось это всё добро переписывать, чтобы запускать асинхронный таймер, дабы снизить нагрузку

Да и мне кажется, что на загруженном сервере лучше использовать Bukkit.getOnlinePlayers(), который выводит существующий лист игроков, этот лист не собирается при вызове, а вот метод World#getNearbyEntities() берет всех ентити в мире, а на загруженном сервере это тысячи, и сортирует по параметрам
 
Назад
Сверху Снизу