创建实体系统

实体系统是你对实体集执行功能操作的方式。组件通常不应具有与之关联的逻辑,这些逻辑涉及数据的意识或其他组件实例的状态,因为这是实体系统的工作。实体系统一次不能注册到多个引擎。

实体系统不应执行多种类型的功能。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
            ...
        }
    }

有时,使用 EntityListeners 中的附加功能扩展 EntitySystems 是有帮助的,因此你只跟踪你希望操作的实体类型,而不是每个周期迭代引擎中的所有实体。只要将实体添加到系统注册到的同一引擎,就会触发 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
            ...
        }
    }
}

跟踪系统始终处理的实体子集也可以是最佳的,因为你可以从该系统的处理中移除特定实体,而无需移除关联组件或者如果需要那样从引擎中移除它们。