ここで説明するように、コンポーネント間の通信にシステムを使用するエンティティコンポーネントパラダイムで設計されたゲームを作成しています。開発の段階で、ゲームの状態(一時停止、再生、レベルスタート、ラウンドスタート、ゲームオーバーなど)を追加する必要がありますが、フレームワークでそれを行う方法がわかりません。私は誰もが参照していると思われるゲームの状態に関するこのコード例を見てきましたが、私のフレームワークに適合しないと思います。各州が独自の描画と更新を処理しているようです。私のフレームワークには、システムを使用してすべての更新を処理するSystemManagerがあります。たとえば、次は私のRenderingSystemクラスです。
public class RenderingSystem extends GameSystem {
private GameView gameView_;
/**
* Constructor
* Creates a new RenderingSystem.
* @param gameManager The game manager. Used to get the game components.
*/
public RenderingSystem(GameManager gameManager) {
super(gameManager);
}
/**
* Method: registerGameView
* Registers gameView into the RenderingSystem.
* @param gameView The game view registered.
*/
public void registerGameView(GameView gameView) {
gameView_ = gameView;
}
/**
* Method: triggerRender
* Adds a repaint call to the event queue for the dirty rectangle.
*/
public void triggerRender() {
Rectangle dirtyRect = new Rectangle();
for (GameObject object : getRenderableObjects()) {
GraphicsComponent graphicsComponent =
object.getComponent(GraphicsComponent.class);
dirtyRect.add(graphicsComponent.getDirtyRect());
}
gameView_.repaint(dirtyRect);
}
/**
* Method: renderGameView
* Renders the game objects onto the game view.
* @param g The graphics object that draws the game objects.
*/
public void renderGameView(Graphics g) {
for (GameObject object : getRenderableObjects()) {
GraphicsComponent graphicsComponent =
object.getComponent(GraphicsComponent.class);
if (!graphicsComponent.isVisible()) continue;
GraphicsComponent.Shape shape = graphicsComponent.getShape();
BoundsComponent boundsComponent =
object.getComponent(BoundsComponent.class);
Rectangle bounds = boundsComponent.getBounds();
g.setColor(graphicsComponent.getColor());
if (shape == GraphicsComponent.Shape.RECTANGULAR) {
g.fill3DRect(bounds.x, bounds.y, bounds.width, bounds.height,
true);
} else if (shape == GraphicsComponent.Shape.CIRCULAR) {
g.fillOval(bounds.x, bounds.y, bounds.width, bounds.height);
}
}
}
/**
* Method: getRenderableObjects
* @return The renderable game objects.
*/
private HashSet<GameObject> getRenderableObjects() {
return gameManager.getGameObjectManager().getRelevantObjects(
getClass());
}
}
また、私のゲームの更新はすべてイベント駆動型です。単純にすべてを同時に更新するようなループはありません。
フレームワークが気に入ったのは、新しいゲームオブジェクトを簡単に追加できるためですが、コンポーネントベースのデザインでコンポーネント間の通信時に発生する問題はありません。作業を一時停止するためだけに、それをチャックするのは嫌です。エンティティコンポーネントのデザインを削除せずにゲームにゲームステートを追加する方法はありますか?ゲームステートの例は実際に私のフレームワークに適合していますか?
編集: 私は私のフレームワークを十分に説明しなかったかもしれません。私のコンポーネントは単なるデータです。C ++でコーディングしている場合、おそらく構造体になります。以下はその例です。
public class BoundsComponent implements GameComponent {
/**
* The position of the game object.
*/
private Point pos_;
/**
* The size of the game object.
*/
private Dimension size_;
/**
* Constructor
* Creates a new BoundsComponent for a game object with initial position
* initialPos and initial size initialSize. The position and size combine
* to make up the bounds.
* @param initialPos The initial position of the game object.
* @param initialSize The initial size of the game object.
*/
public BoundsComponent(Point initialPos, Dimension initialSize) {
pos_ = initialPos;
size_ = initialSize;
}
/**
* Method: getBounds
* @return The bounds of the game object.
*/
public Rectangle getBounds() {
return new Rectangle(pos_, size_);
}
/**
* Method: setPos
* Sets the position of the game object to newPos.
* @param newPos The value to which the position of the game object is
* set.
*/
public void setPos(Point newPos) {
pos_ = newPos;
}
}
コンポーネントが相互に通信しません。システムはコンポーネント間の通信を処理します。また、私のシステムは互いに通信しません。それらは別々の機能を持ち、簡単に別々に保つことができます。MovementSystemは、ゲームオブジェクトを正しく移動するために、RenderingSystemが何をレンダリングしているかを知る必要はありません。コンポーネントに適切な値を設定するだけで、RenderingSystemがゲームオブジェクトをレンダリングするときに正確なデータが得られます。
コンポーネントではなくシステムとやり取りする必要があるため、ゲームの状態をシステムにすることはできません。データの設定ではありません。呼び出す必要がある関数を決定します。
すべてのゲームオブジェクトが1つのゲーム状態を共有するため、GameStateComponentは意味がありません。コンポーネントはオブジェクトを構成するものであり、コンポーネントはオブジェクトごとに異なります。たとえば、ゲームオブジェクトは同じ境界を持つことはできません。それらは重複する境界を持つことができますが、BoundsComponentを共有する場合、それらは実際には同じオブジェクトです。うまくいけば、この説明によって私のフレームワークの混乱が少なくなります。