Sto realizzando un gioco progettato con il paradigma entità-componente che utilizza i sistemi per comunicare tra i componenti, come spiegato qui . Ho raggiunto il punto nel mio sviluppo che ho bisogno di aggiungere stati di gioco (come pausa, gioco, inizio livello, inizio round, fine gioco, ecc.), Ma non sono sicuro di come farlo con il mio framework. Ho visto questo esempio di codice sugli stati di gioco a cui tutti sembrano fare riferimento, ma non penso che si adatti al mio framework. Sembra che ogni stato gestisca il proprio disegno e il proprio aggiornamento. Il mio framework ha un SystemManager che gestisce tutti gli aggiornamenti tramite i sistemi. Ad esempio, ecco la mia classe 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());
}
}
Anche tutto l'aggiornamento nel mio gioco è guidato dagli eventi. Non ho un loop come il loro che aggiorna semplicemente tutto allo stesso tempo.
Mi piace il mio framework perché semplifica l'aggiunta di nuovi GameObjects, ma non presenta i problemi che alcuni progetti basati sui componenti incontrano quando comunicano tra i componenti. Odierei buttarlo solo per fare una pausa al lavoro. C'è un modo in cui posso aggiungere stati di gioco al mio gioco senza rimuovere il design del componente entità? L'esempio di stato del gioco si adatta davvero al mio framework e mi manca qualcosa?
EDIT: potrei non aver spiegato abbastanza bene il mio quadro. I miei componenti sono solo dati. Se stavo codificando in C ++, probabilmente sarebbero delle strutture. Ecco un esempio:
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;
}
}
I miei componenti non comunicano tra loro. I sistemi gestiscono la comunicazione tra componenti. Anche i miei sistemi non comunicano tra loro. Hanno funzionalità separate e possono essere facilmente separate. Il MovementSystem non ha bisogno di sapere che cosa rende RenderingSystem per spostare correttamente gli oggetti di gioco; deve solo impostare i giusti valori sui componenti, in modo che quando RenderingSystem esegue il rendering degli oggetti di gioco, disponga di dati precisi.
Lo stato del gioco non potrebbe essere un sistema, poiché deve interagire con i sistemi anziché con i componenti. Non sta impostando i dati; sta determinando quali funzioni devono essere chiamate.
Un GameStateComponent non avrebbe senso perché tutti gli oggetti di gioco condividono uno stato di gioco. I componenti sono ciò che compone gli oggetti e ognuno è diverso per ciascun oggetto diverso. Ad esempio, gli oggetti di gioco non possono avere gli stessi limiti. Possono avere limiti sovrapposti, ma se condividono un BoundsComponent, sono davvero lo stesso oggetto. Spero che questa spiegazione renda il mio quadro meno confuso.