Tworzę grę zaprojektowaną według paradygmatu encja-komponent, który wykorzystuje systemy do komunikacji między komponentami, jak wyjaśniono tutaj . Osiągnąłem punkt w moim rozwoju, że muszę dodawać stany gry (takie jak pauza, gra, rozpoczęcie poziomu, rozpoczęcie rundy, zakończenie gry itp.), Ale nie jestem pewien, jak to zrobić w moim środowisku. Przejrzałem ten przykład kodu dotyczący stanów gry, do którego wszyscy się odnoszą, ale nie sądzę, żeby pasował do mojego frameworka. Wygląda na to, że każdy stan obsługuje własny rysunek i aktualizację. Mój framework ma SystemManager, który obsługuje wszystkie aktualizacje za pomocą systemów. Na przykład oto moja klasa 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());
}
}
Również wszystkie aktualizacje w mojej grze są oparte na zdarzeniach. Nie mam takiej pętli, która po prostu aktualizuje wszystko w tym samym czasie.
Podoba mi się mój framework, ponieważ ułatwia dodawanie nowych GameObjects, ale nie ma problemów z niektórymi projektami opartymi na komponentach podczas komunikacji między komponentami. Nie chciałbym tego wyrzucać, żeby zrobić sobie przerwę w pracy. Czy istnieje sposób dodawania stanów gry do mojej gry bez usuwania projektu elementu-elementu? Czy przykład stanu gry faktycznie pasuje do mojego frameworka i po prostu czegoś brakuje?
EDYCJA: Być może nie dość dobrze wyjaśniłem swoje ramy. Moje komponenty to tylko dane. Gdybym pisał w C ++, prawdopodobnie byłyby to struktury. Oto przykład jednego z nich:
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;
}
}
Moje komponenty nie komunikują się ze sobą. Systemy obsługują komunikację między komponentami. Moje systemy również nie komunikują się ze sobą. Mają osobną funkcjonalność i można je łatwo przechowywać osobno. MovementSystem nie musi wiedzieć, co renderuje RenderingSystem, aby poprawnie przenieść obiekty gry; wystarczy ustawić właściwe wartości na komponentach, aby podczas renderowania obiektów gry RenderingSystem miał dokładne dane.
Stan gry nie może być systemem, ponieważ musi współdziałać z systemami, a nie z komponentami. Nie ustawia danych; określa, które funkcje należy wywołać.
GameStateComponent nie miałby sensu, ponieważ wszystkie obiekty gry mają ten sam stan gry. Elementy składają się na obiekty i każdy z nich jest inny dla każdego innego obiektu. Na przykład obiekty gry nie mogą mieć takich samych granic. Mogą mieć nakładające się granice, ale jeśli współużytkują BoundsComponent, to tak naprawdę są tym samym obiektem. Mam nadzieję, że to wyjaśnienie sprawia, że moje ramy są mniej mylące.