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

  • Автор темы Автор темы ilya50
  • Дата начала Дата начала

ilya50

Активный участник
Пользователь
Баллы
76
Допустим у меня есть красная точка(location), два крипера(LivingEntity). Мне нужно получить синие точки чтобы впоследствии получить расстояние до моба. Как это можно сделать ? Нужно именно по хитбоксам
upload_2019-3-18_23-25-51.png
[\SPOILER]
 
Я бы решил как: выделить граничные условия и в зависимости от них вести расчёты. Беглый гуглёж даёт формулы рассчёта расстояний от точки до плоскости и от точки до прямой. Можно разделить при помощи BB (boundbox) всё пространство на 26 участков, группируемых в 3 группы.
1. Группа из 8-ми секторов, которые касаются BB только углами, там расстояние между 2-мя точками.
2. Группа из 12-ти секторов, имеет общее ребро с BB, там считаем расстояние до прямой.
3. Группа из 6-ти секторов, имеет общую плоскость с BB, там считаем расстояние до плоскости.
Безымянный.png
Возможно есть более простое решение, но я или не помню его, или не знаю о нём.
 
Я бы решил как: выделить граничные условия и в зависимости от них вести расчёты. Беглый гуглёж даёт формулы рассчёта расстояний от точки до плоскости и от точки до прямой. Можно разделить при помощи BB (boundbox) всё пространство на 26 участков, группируемых в 3 группы.
1. Группа из 8-ми секторов, которые касаются BB только углами, там расстояние между 2-мя точками.
2. Группа из 12-ти секторов, имеет общее ребро с BB, там считаем расстояние до прямой.
3. Группа из 6-ти секторов, имеет общую плоскость с BB, там считаем расстояние до плоскости.
Возможно есть более простое решение, но я или не помню его, или не знаю о нём.
Итерация, и метод distance?
 
Допустим у меня есть красная точка(location), два крипера(LivingEntity). Мне нужно получить синие точки чтобы впоследствии получить расстояние до моба. Как это можно сделать ? Нужно именно по хитбоксам
По моему проще просто вычислить расстояние от первой точки до второй через баккит апи.
Location loc = player.getLocation(); //Первая локация, например от игрока
for (Entity en : Bukkit.getWorld("world").getEntities()) {
if (en instanceof Creeper) {
Location entityLoc = en.getLocation();
double distance = loc.distance(entityLoc); //Получили расстояние от крипера до игрока
//А тут уже можно работать с расстоянием
}
}
 
По моему проще просто вычислить расстояние от первой точки до второй через баккит апи.
Location loc = player.getLocation(); //Первая локация, например от игрока
for (Entity en : Bukkit.getWorld("world").getEntities()) {
if (en instanceof Creeper) {
Location entityLoc = en.getLocation();
double distance = loc.distance(entityLoc); //Получили расстояние от крипера до игрока
//А тут уже можно работать с расстоянием
}
}
Я знаю про этот способ, мне нужно по ХИТБОКСУ
 
Итерация, и метод distance?
Какая итерация? Нужно определить в какой из 26-ти областей находится красная точка, относительно BB.
Сделать это можно при помощи условий. Например, чтобы отсечь вертикальные, нужно проверить 2 условия: если точка ниже нижней границы, значит она находится в нижних 9-ти секторах, если точка выше верхней границы -- в верхних 9-ти, иначе в центральных 8-ми.
 
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;
Ну и дальше геометрия.
 
По моему проще просто вычислить расстояние от первой точки до второй через баккит апи.
Location loc = player.getLocation(); //Первая локация, например от игрока
for (Entity en : Bukkit.getWorld("world").getEntities()) {
if (en instanceof Creeper) {
Location entityLoc = en.getLocation();
double distance = loc.distance(entityLoc); //Получили расстояние от крипера до игрока
//А тут уже можно работать с расстоянием
}
}
Никаких getEntities() и getNearbyEntities()! Есть более оптимизированный метод - getEntitiesByClasses()

Java:
    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;
    }
 
Никаких getEntities() и getNearbyEntities()! Есть более оптимизированный метод - getEntitiesByClasses()

Java:
    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;
    }
Почти тоже самое и с обычным методом 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;
    }
Не знаю честно говоря в каком месте может быть быстрее.
 
Не знаю честно говоря в каком месте может быть быстрее.
Надо делать бенчмаркинг с кучей энтити разных типов (куча лута и экспы на земле в разных местах, мобы всех видов, картины/рамки и т.д.), но это для тех кто готов заморачиваться
 
Назад
Верх