Я створюю гру, розроблену за допомогою парадигми суті-компонента, яка використовує системи для зв'язку між компонентами, як пояснено тут . Я досяг моменту в своїй розробці, що мені потрібно додати ігрові стани (такі як пауза, гра, стартовий рівень, круглий старт, гра закінчена тощо), але я не впевнений, як це зробити з моєю основою. Я переглянув цей приклад коду на ігрових станах, на які всі, здається, посилаються, але не думаю, що він відповідає моїй рамці. Здається, кожен штат обробляє свій власний малюнок та оновлення. У моїй системі є 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());
}
}
Також усі оновлення в моїй грі залежать від подій. У мене немає такої петлі, яка просто оновлює все одночасно.
Мені подобається моя структура, тому що вона дозволяє легко додавати нові GameObjects, але не має проблем, з якими стикаються дизайни на основі компонентів під час спілкування між компонентами. Мені б не хотілося це робити, щоб призупинити роботу. Чи можна додати стани гри до своєї гри, не знімаючи дизайн-компонент сутності? Чи дійсно приклад стану гри відповідає моїм рамкам, і я просто щось пропускаю?
EDIT: Я, можливо, недостатньо добре пояснив свої рамки. Мої компоненти - це лише дані. Якби я кодував 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 надає ігрові об’єкти, вона має точні дані.
Ігровий стан не може бути системою, тому що йому потрібно взаємодіяти з системами, а не з компонентами. Це не встановлення даних; це визначає, які функції потрібно викликати.
GameStateComponent не має сенсу, оскільки всі ігрові об'єкти мають один ігровий стан. Компоненти - це те, що складається з об'єктів, і кожен для них різний. Наприклад, ігрові об’єкти не можуть мати однакові межі. Вони можуть мати межі, що перекриваються, але якщо вони поділяють BoundsComponent, вони дійсно той самий об’єкт. Сподіваємось, це пояснення робить мою основу менш заплутаною.