2016-07-05 68 views
1

SystemSystemlibgdx(Ashley Framework ECS) - 與其他系統交談系統的正確方式是什麼?

目前我使用阿什利框架開發CharacterSystemGunSystemBulletSystem。我的問題是我不知道這是否是system與其他system的正確方式。

CharacterSystem方法onProcessEntitycharacterattack被觸發我用getEngine().getSystem(GunSystem.class).trigger(true)GunSystem裏面我有一個方法Bullet的生成實體。當在攝像機外部時,BulletSystem處理身體的釋放。

sub-question用ECS框架創建Bulletclass的正確方法是什麼?

回答

2

我從未使用過Ashley作爲ECS,但通常Systems不應該彼此溝通。

原因:當Systems會溝通時,它們不會彼此獨立。獨立Systems允許您自由添加和刪除它們,而不必擔心代碼中斷。當重要的Systems丟失時,遊戲邏輯可能會中斷。

有一個Factory(類),它創建子彈實體。然後在每個System中使用Factory,它可以構建新的子彈實體。

+0

我使用libgdx,你推薦ECS框架與libgdx一起使用? – ronscript

+0

Ashley或artemis-odb。不知道任何其他ECS。 –

2

我在遊戲和最近的項目中使用Ashley ECS相當多(https://github.com/basimkhajwal/LSD)我遇到過類似的情況。我的方法可能不是標準的,它可能會在不同的項目設置中發生,但使用事件隊列對我來說是一個很好的解決方案。

從本質上說,你有一個enum(在我的情況GameEvent)負責處理所有不同的事件需要傳遞周圍像PLAYER_DIEDLAUNCH_PLAYER等。我使用Ashley的signals接口來創建一個簡單的隊列存儲事件,系統可以對每個時間點進行輪詢。具體如下:

public class EventQueue implements Listener<GameEvent> { 

    private PriorityQueue<GameEvent> eventQueue; 

    public EventQueue() { 
     eventQueue = new PriorityQueue<GameEvent>(); 
    } 

    public GameEvent[] getEvents() { 
     GameEvent[] events = eventQueue.toArray(new GameEvent[0]); 
     eventQueue.clear(); 
     return events; 
    } 

    public GameEvent poll() { 
     return eventQueue.poll(); 
    } 

    @Override 
    public void receive(Signal<GameEvent> signal, GameEvent event) { 
     eventQueue.add(event); 
    } 

} 

接下來,我GameWorld類,它加載阿什利Engine,並與系統填充它的人,我有一個這是我的事件隊列中的主要骨幹。在這裏,如Listener<T>,Signal<T>已經是阿什利的一部分。

有些系統需要能夠觸發這個信號/從它接收事件,所以他們把這個Signal類放在構造函數中。然後,EntitySystem可以綁定偵聽器或觸發事件,然後將事件傳遞給其他偵聽器。例如。我LaserSystem類(簡體):

public class LaserSystem extends IteratingSystem implements Disposable, ContactListener { 

    ...  

    private Signal<GameEvent> gameEventSignal; 
    private EventQueue eventQueue; 

    public LaserSystem(Signal<GameEvent> gameEventSignal) { 
     super(Family.all(LaserComponent.class).get(), Constants.SYSTEM_PRIORITIES.LASER); 

     this.gameEventSignal = gameEventSignal; 

     eventQueue = new EventQueue(); 
     gameEventSignal.add(eventQueue); 
    } 

    ... 

    @Override 
    public void beginContact(Contact contact) { 

     .... 

     LaserComponent laserComponent = laserMapper.get(laser); 
     laserComponent.updateLaser = true; 

     if (other.getComponent(PlayerComponent.class) != null) { 
      gameEventSignal.dispatch(GameEvent.LASER_COLLISION); 
     } 
    } 
} 

希望這是有道理的,也覺得免費閱讀我的項目的代碼更用法示例。

相關問題