2017-01-13 13 views
2

私はエンティティコンポーネントシステム(ECS)フレームワークを使用して2D空間シューターを作成しています。私のコンポーネントはデータのみで、私のシステムはすべてのロジックを扱い、エンティティは基本的にIDです。私はthorと呼ばれるSFMLの開発者の一人、によって建てられたかなりクールな入力システムを使用していますコンポーネントエンティティシステム - 入力処理

struct LaserCannon { 
    bool shooting; 
}; 

struct Thrusters { 
    bool up, left, right, down; 
    float acceleration; 
}; 

struct Movement { 
    sf::Vector2f velocity, acceleration; 
    float maxSpeed; 
}; 

:ここ

は私のコンポーネントの一部です。 sf::Keyboard::Wのような入力は、Control::UPのような自分のより高いレベルのイベントにマップします。イベントがinputMap->isActive(Control::UP)で発生したかどうかを確認し、適切に応答することができます。

これは生の入力を「上回る」抽象化レベルにしていますが、もう少し先に進む必要があります。私はControl::UPのようなものに応答できるようにエンティティを必要とし、プレイヤー船のスラスタを作動させるような実体レベルの結果物を活性化する必要があります。 コンポーネントやシステムを使ってアプローチする方法がわからないので、私はこれをまだやっていません!

私は1つの可能な解決策を作ってみた:私は私がコントロールしたいすべてのものを表すブール値を持っているPlayerShipControllerと呼ばれる新しいコンポーネントを作成することができます。他がある場合は、これを達成するために、おそらくより良い方法を

struct PlayerShipController { 
    bool up, left, right, down, shoot; 
}; 

// Input handling system 
struct InputSystem : public entityx::System<InputSystem> { 
    InputSystem(std::shared_ptr<thor::ActionMap<Event>> inputMap) : inputMap(inputMap) {} 

    void update(entityx::EntityManager &es, entityx::EventManager &events, entityx::TimeDelta dt) override { 

     // Iterate across all entities with a PlayerShipController 
     es.each<cm::PlayerShipController>([dt, this](entityx::Entity entity, cm::PlayerShipController &controller) { 
      if (inputMap->isActive(Event::LEFT_BUTTON)) { 
       controller.left = true; 
      } 
      if (inputMap->isActive(Event::UP_BUTTON)) { 
       controller.up = true; 
      } 
      if (inputMap->isActive(Event::RIGHT_BUTTON)) { 
       controller.right = true; 
      } 
      if (inputMap->isActive(Event::DOWN_BUTTON)) { 
       controller.down = true; 
      } 
     }); 
    }; 
    std::shared_ptr<thor::ActionMap<Event>> inputMap; 
}; 

をしかし、私は疑問に思って:私は、入力に反応し、そのようにそれに応じて、これらのブール値を設定し、システムを持つことができます。私のソリューションについて本当に気に入らないのは、ゲームに特有のシステムを書くことです(それはPlayerShipControllerが必要です)。私はそれが中間層の一種を持っていることははるかにneaterだろうと思う..私には、以下のソリューションははるかにクーラーです!

  1. ユーザプレス「W」
  2. のみ発送は、ユーザによって制御されるために何とか、Ship::THRUST_UPようなエンティティ・レベルのイベントにマッピングされる
  3. Control::UP InputMapをトールによってControl::UPに変換される「W」
  4. Ship::THRUST_UPのような
  5. エンティティレベルのイベントは、especiは何Thrusters::upブール

を活性化などのアクションに翻訳されています小惑星の爆発やスラスタを使った敵の船のような他の多くのものを制御するために、同じエンティティレベルのイベントを使うことが理想的です。私は今、それを実装する方法、またはECSに統合する方法はありません。どうすればいい?

答えて

2

上記のようにキーイベントがポーリングされると、特定のイベントを購読しているすべてのゲームエンティティに送信できるように、イベントディスパッチャを設定することをお勧めします。 EntityXにはイベントオブジェクトが組み込まれており、これを行うことができます。見てくださいhere