建立實體系統

實體系統是你對實體集執行功能操作的方式。元件通常不應具有與之關聯的邏輯,這些邏輯涉及資料的意識或其他元件例項的狀態,因為這是實體系統的工作。實體系統一次不能註冊到多個引擎。

實體系統不應執行多種型別的功能。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
            ...
        }
    }
}

跟蹤系統始終處理的實體子集也可以是最佳的,因為你可以從該系統的處理中移除特定實體,而無需移除關聯元件或者如果需要那樣從引擎中移除它們。