Поиск…


замечания

Ashley Entity System - это библиотека системы Entity System, которая управляется в рамках организации LibGDX и хорошо подходит для разработки игр. Это зависит от классов утилиты LibGDX, но может использоваться с другими фреймворками Java, не основанными на LibGDX, с некоторой работой.

Сущностные системы предоставляют другой способ управления данными и функциональностью по отношению к большим наборам объектов, не делая классы объектов богатыми с наследованием.

Использование Эшли может быть полезным подходом для тех, кто ищет подход к моделированию объектов, например Unity, но с рамкой рамки, а не с движком.

Создание компонента

Компоненты - это просто экземпляры, которые реализуют класс компонента Ashley.

import com.badlogic.ashley.core.Component;
import com.badlogic.ashley.core.ComponentMapper;

public class Position implements Component {
    public static final ComponentMapper<Position> Map = 
                                 ComponentMapper.getFor(Position.class);

    public float x = 0f, 
                 y = 0f;
}

Компонентные карты обеспечивают быстрый доступ к компонентам на объектах. Два общих способа управления картами компонентов - либо сохранять статический экземпляр в классе вашего компонента, либо иметь класс / перечисление, содержащее все картографы для всех ваших компонентов.

Нет необходимости объявлять в вашем приложении сопоставление типа компонента более одного раза.

Создание системы сущностей

Сущностные системы - это то, как вы выполняете функциональные операции над наборами объектов. Компоненты, как правило, не имеют связанной с ними логики, которая подразумевает осознание данных или состояния других экземпляров компонентов, поскольку это задача системы сущности. Система сущности не может быть зарегистрирована на несколько двигателей за раз.

Сущности системы не должны выполнять более одного типа функций. Система MovementSystem должна обрабатывать только позиционирование и т. П., В то время как нечто вроде RenderSystem должно обрабатывать чертежи сущностей.

import com.badlogic.ashley.core.Entity;
import com.badlogic.ashley.core.EntitySystem;
import com.badlogic.ashley.core.Family;

public class MovementSystem extends EntitySystem {
    //the type of components necessary for entities to have to be operated on
    private static final Family FAMILY = Family.all(Position.class).get();

    public MovementSystem () {
        super();
    }

    /**
     * The update method called every tick.
     * @param deltaTime The time passed since last frame in seconds.
     */
    public void update (float deltaTime) {
        for (Entity e : this.getEngine().getEntitiesFor(FAMILY)) {
            Position pos = Position.Map.get(e);
            
            // do entity movement logic on component
            ...
        }
    }

Иногда полезно расширять EntitySystems дополнительными функциональными возможностями, такими как EntityListeners, поэтому вы отслеживаете только типы объектов, над которыми хотите работать, вместо повторения всех объектов в каждом цикле. EntityListeners запускаются всякий раз, когда объект добавляется к тому же движку, на который зарегистрирована система.

import com.badlogic.ashley.core.EntityListener;
import com.badlogic.gdx.utils.Array;

public class MovementSystem extends EntitySystem implements EntityListener {
    Array<Entity> moveables = new Array<>();
    ...

    @Override
    public void entityAdded(Entity entity) {
        if (FAMILY.matches(entity)) {
            moveables.add(entity);
        }
    }

    @Override
    public void entityRemoved(Entity entity) {
        if (FAMILY.matches(entity)) {
            moveables.removeValue(entity, true);
        }
    }

    public void update (float deltaTime) {
        for (Entity e : this.moveables) {
            Position pos = Position.Map.get(e);
            
            // do entity movement logic on component
            ...
        }
    }
}

Отслеживание подмножества объектов, которые система обрабатывает в любое время, также может быть оптимальным, поскольку вы можете удалить конкретный объект из обработки этой системы, не удаляя связанный компонент или удаляя их из движка в целом, если это необходимо.

Создание сортированной системы сущностей

Простая EntitySystem которая обрабатывает каждый объект данного семейства в порядке, указанном comparator и вызывает processEntity() для каждого объекта каждый раз, когда EntitySystem обновляется. Это действительно просто класс удобства, поскольку системы рендеринга имеют тенденцию перебирать список объектов отсортированным образом. Добавление объектов приведет к тому, что список сущностей будет использоваться. Вызовите forceSort() если вы изменили критерии сортировки. Для получения дополнительной информации см. SortedIteratingSystem

В приведенном ниже примере кода лучше всего использовать для этого рендеринг ваших спрайтов в отсортированном порядке по zindex.

public class SpriteComponent implements Component {
     public TextureRegion region;
     public int z = 0;
}

public class Mapper {
     public static ComponentMapper<SpriteComponent> sprite = ComponentMapper.getFor(SpriteComponent.class);
}

public class RenderingSystem extends SortedIteratingSystem {

    public RenderingSystem () {
         super(Familly.all(SpriteComponent.class).get(), new ZComparator())
    }

    public void processEntity(Entity entity, float deltaTime) {
         if(checkZIndexHasChangeValue()) {
              forceSort();
         }
    }

    private static class ZComparator implements Comparator<Entity> {
        @Override
        public int compare(Entity entityA, Entity entityB) {
            return (int)Math.signum(Mapper.sprite.get(entityA).z - Mapper.sprite.get(entityB).z);
        }
    }

}

Создание системы интервальной итерации

Простая EntitySystem которая обрабатывает Семейство сущностей не один раз для фрейма, а через определенный интервал. Логика обработки сущности должна быть помещена в processEntity(Entity) . Для получения дополнительной информации см. IntervalIteratingSystem

В приведенном ниже примере кода лучшим использованием для этого является шаг мира физики.

public class Constants {
     public final static float TIME_STEP = 1 / 60.0f; // 60 fps
     public final static int VELOCITY_ITERATIONS = 6;
     public final static int POSITION_ITERATIONS = 2;
}

public class PhysicsSystem extends IntervalIteratingSystem {
    public PhysicsSystem () {
         super(Family.all(PhysicsComponent.class), Constants.TIME_STEP);
    }

    @Override
    protected void processEntity(Entity entity) {
         // process the physics component here with an interval of 60fps
    }

    @Override
    protected void updateInterval() {
        WorldManager.world.step(Constants.TIME_STEP, Constants.VELOCITY_ITERATIONS, Constants.POSITION_ITERATIONS);
        super.updateInterval();
    }

}


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow