Saya membuat game yang dirancang dengan paradigma entitas-komponen yang menggunakan sistem untuk berkomunikasi antar komponen seperti yang dijelaskan di sini . Saya telah mencapai titik dalam pengembangan saya bahwa saya perlu menambahkan status permainan (seperti dijeda, bermain, mulai level, mulai putaran, game over, dll.), Tapi saya tidak yakin bagaimana melakukannya dengan kerangka kerja saya. Saya telah melihat contoh kode ini pada status permainan yang tampaknya dirujuk oleh semua orang, tapi saya rasa itu tidak sesuai dengan kerangka kerja saya. Tampaknya masing-masing negara bagian menangani menggambar dan memperbarui sendiri. Kerangka kerja saya memiliki SystemManager yang menangani semua pembaruan menggunakan sistem. Sebagai contoh, inilah kelas RenderingSystem saya:
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());
}
}
Juga semua pembaruan dalam game saya adalah event-driven. Saya tidak memiliki loop seperti mereka yang hanya memperbarui semuanya pada saat yang sama.
Saya menyukai kerangka kerja saya karena memudahkan untuk menambahkan GameObjects baru, tetapi tidak memiliki masalah yang dihadapi beberapa desain berbasis komponen saat berkomunikasi antar komponen. Aku benci membuangnya hanya untuk berhenti bekerja. Apakah ada cara saya bisa menambahkan status game ke game saya tanpa menghapus desain entitas-komponen? Apakah contoh status permainan cocok dengan kerangka saya, dan saya hanya melewatkan sesuatu?
EDIT: Saya mungkin tidak menjelaskan kerangka kerja saya dengan cukup baik. Komponen saya hanya data. Jika saya coding dalam C ++, mereka mungkin akan menjadi struct. Berikut ini contohnya:
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;
}
}
Komponen saya tidak saling berkomunikasi. Sistem menangani komunikasi antar-komponen. Sistem saya juga tidak saling berkomunikasi. Mereka memiliki fungsi yang terpisah dan dapat dengan mudah dipisahkan. The MovementSystem tidak perlu tahu apa yang RenderingSystem render untuk memindahkan objek game dengan benar; itu hanya perlu menetapkan nilai yang tepat pada komponen, sehingga ketika RenderingSystem merender objek game, ia memiliki data yang akurat.
Status permainan tidak bisa menjadi sistem, karena itu perlu berinteraksi dengan sistem daripada komponen. Itu tidak mengatur data; itu menentukan fungsi mana yang perlu dipanggil.
GameStateComponent tidak masuk akal karena semua objek game memiliki satu status permainan. Komponen adalah apa yang membentuk objek dan masing-masing berbeda untuk setiap objek yang berbeda. Misalnya, objek permainan tidak dapat memiliki batas yang sama. Mereka dapat memiliki batas yang tumpang tindih, tetapi jika mereka memiliki komponen Bounds, mereka benar-benar objek yang sama. Semoga penjelasan ini membuat kerangka saya kurang membingungkan.
Negara adalah nilai yang berlaku untuk suatu objek. Status game, seperti namanya, akan menjadi status objek 'Game'. Objek Game itu - atau lebih mungkin, komponen tertentu di dalamnya - akan melacak kondisi saat ini dan membuat atau menghancurkan objek apa pun yang diperlukan untuk memfasilitasi keadaan saat ini. Karena komponen Anda hanya data, Anda akan memerlukan Sistem baru untuk menangani hal ini, meskipun mungkin hanya ada satu contoh komponen terkait.
Sulit mengomentari bagaimana Anda menerapkan jeda ketika tidak jelas bagaimana Anda menerapkan pembaruan. Proses yang memancarkan acara pembaruan dapat memilih untuk tidak melakukannya, jika objek game mengatakan game dijeda. Bagaimana objek game berkomunikasi dengan proses pembaruan tergantung pada Anda; mungkin
getRelevantObjects
panggilan Anda harus memungkinkan pemutakhiran untuk menemukan objek Game, atau sebaliknya.sumber