我在做设计与实体分量范例,使用系统组件之间的通信,说明游戏在这里。在开发过程中,我已经达到需要添加游戏状态(例如暂停,播放,关卡开始,回合开始,游戏结束等)的地步,但是我不确定如何在我的框架中进行操作。我看这对游戏状态的代码示例,每个人都似乎是参考,但我不认为它与我的框架适合。似乎每个状态都处理自己的绘图和更新。我的框架有一个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());
}
}
另外,我游戏中的所有更新都是事件驱动的。我没有像他们这样的循环可以同时更新所有内容。
我喜欢我的框架,因为它可以轻松添加新的GameObject,但是在组件之间进行通信时,不会遇到某些基于组件的设计遇到的问题。我不想为了工作而停下来。有没有一种方法可以在不删除实体组件设计的情况下向游戏添加游戏状态?游戏状态示例是否真的适合我的框架,而我只是缺少一些东西?
编辑: 我可能还没有很好地解释我的框架。我的组件只是数据。如果我用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,则它们实际上是同一对象。希望这种解释可以使我的框架不那么混乱。