1. Этот сайт использует файлы cookie. Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie. Узнать больше.
  2. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

Помогите Расстояние до мобов

Тема в разделе "Разработка плагинов для новичков", создана пользователем ilya50, 18 мар 2019.

  1. Автор темы
    ilya50

    ilya50 Активный участник Пользователь

    Баллы:
    76
    Допустим у меня есть красная точка(location), два крипера(LivingEntity). Мне нужно получить синие точки чтобы впоследствии получить расстояние до моба. Как это можно сделать ? Нужно именно по хитбоксам
    upload_2019-3-18_23-25-51.png
    [\SPOILER]
     
  2. Ission

    Ission Старожил Девелопер Пользователь

    Баллы:
    173
    Skype:
    lokivava
    Я бы решил как: выделить граничные условия и в зависимости от них вести расчёты. Беглый гуглёж даёт формулы рассчёта расстояний от точки до плоскости и от точки до прямой. Можно разделить при помощи BB (boundbox) всё пространство на 26 участков, группируемых в 3 группы.
    1. Группа из 8-ми секторов, которые касаются BB только углами, там расстояние между 2-мя точками.
    2. Группа из 12-ти секторов, имеет общее ребро с BB, там считаем расстояние до прямой.
    3. Группа из 6-ти секторов, имеет общую плоскость с BB, там считаем расстояние до плоскости.
    Безымянный.png
    Возможно есть более простое решение, но я или не помню его, или не знаю о нём.
     
  3. Energy warrior

    Energy warrior Активный участник Пользователь

    Баллы:
    76
    Итерация, и метод distance?
     
  4. MurlikMurlik

    MurlikMurlik Активный участник Пользователь

    Баллы:
    96
    По моему проще просто вычислить расстояние от первой точки до второй через баккит апи.
    Location loc = player.getLocation(); //Первая локация, например от игрока
    for (Entity en : Bukkit.getWorld("world").getEntities()) {
    if (en instanceof Creeper) {
    Location entityLoc = en.getLocation();
    double distance = loc.distance(entityLoc); //Получили расстояние от крипера до игрока
    //А тут уже можно работать с расстоянием
    }
    }
     
  5. Автор темы
    ilya50

    ilya50 Активный участник Пользователь

    Баллы:
    76
    Я знаю про этот способ, мне нужно по ХИТБОКСУ
     
  6. MurlikMurlik

    MurlikMurlik Активный участник Пользователь

    Баллы:
    96
    Но для какой цели это нужно сделать?
     
  7. NyanGuyMF

    NyanGuyMF Активный участник Пользователь

    Баллы:
    76
    От Entity можно получить BoundingBox (hitbox) и уже с этим работать
     
  8. Автор темы
    ilya50

    ilya50 Активный участник Пользователь

    Баллы:
    76
    Взрыв ракеты, мне не нужно через tnt, у меня своя обработка. Я хочу сделать как в quake
     
  9. Ission

    Ission Старожил Девелопер Пользователь

    Баллы:
    173
    Skype:
    lokivava
    Какая итерация? Нужно определить в какой из 26-ти областей находится красная точка, относительно BB.
    Сделать это можно при помощи условий. Например, чтобы отсечь вертикальные, нужно проверить 2 условия: если точка ниже нижней границы, значит она находится в нижних 9-ти секторах, если точка выше верхней границы -- в верхних 9-ти, иначе в центральных 8-ми.
     
  10. alexandrage

    alexandrage Старожил Пользователь

    Баллы:
    173
    AxisAlignedBB bb = craftentity.getHandle().getBoundingBox();
    double maxX = bb.maxX;
    double maxY = bb.maxY;
    double maxZ = bb.maxZ;
    double minX = bb.minX;
    double minY = bb.minY;
    double minZ = bb.minZ;
    Ну и дальше геометрия.
     
  11. Bars

    Bars Старожил Девелопер Пользователь

    Баллы:
    173
    Никаких getEntities() и getNearbyEntities()! Есть более оптимизированный метод - getEntitiesByClasses()

    Код:
        public static int zombiesAround(Player p, int r) {
            Iterator<Entity> i = p.getWorld().getEntitiesByClasses(new Class[]{ Zombie.class, ZombieVillager.class, Husk.class, PigZombie.class, Giant.class, Enderman.class }).iterator();
            int k = 0;
            while (i.hasNext()) {
                Entity e = i.next();
                if (e.getLocation().distance(p.getLocation()) <= r) k++;
            }
    
            return k;
        }
     
  12. MurlikMurlik

    MurlikMurlik Активный участник Пользователь

    Баллы:
    96
    Почти тоже самое и с обычным методом getEntities(), правда он не сравнивает по классам.
    Код:
        public Collection<Entity> getEntitiesByClasses(Class<?>... classes) {
            Collection<Entity> list = new ArrayList<Entity>();
    
            for (Object entity: world.entityList) {
                if (entity instanceof net.minecraft.server.Entity) {
                    Entity bukkitEntity = ((net.minecraft.server.Entity) entity).getBukkitEntity();
    
                    if (bukkitEntity == null) {
                        continue;
                    }
    
                    Class<?> bukkitClass = bukkitEntity.getClass();
    
                    for (Class<?> clazz : classes) {
                        if (clazz.isAssignableFrom(bukkitClass)) {
                            list.add(bukkitEntity);
                            break;
                        }
                    }
                }
            }
    
            return list;
        }
    Не знаю честно говоря в каком месте может быть быстрее.
     
  13. Bars

    Bars Старожил Девелопер Пользователь

    Баллы:
    173
    Надо делать бенчмаркинг с кучей энтити разных типов (куча лута и экспы на земле в разных местах, мобы всех видов, картины/рамки и т.д.), но это для тех кто готов заморачиваться
     

Поделиться этой страницей