Cara menyusun status game dalam sistem berbasis entitas / komponen


11

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.

Jawaban:


4

Saya akui bahwa saya tidak membaca tautan yang Anda poskan. Setelah diedit, dan membaca tautan yang disediakan, posisi saya telah berubah. Di bawah ini mencerminkan hal ini.


Saya tidak tahu bahwa Anda perlu khawatir tentang status permainan dalam arti tradisional. Mempertimbangkan pendekatan Anda terhadap pengembangan, setiap sistem sangat spesifik sehingga mereka, pada dasarnya, adalah manajemen keadaan gim.

Dalam sistem entitas, komponennya hanya data, bukan? Begitu juga keadaan. Dalam bentuknya yang paling sederhana, itu hanya sebuah bendera. Jika Anda membuat status Anda menjadi komponen, dan memungkinkan sistem Anda untuk mengkonsumsi data komponen tersebut dan bereaksi terhadap status (tanda) di dalamnya, Anda akan membangun manajemen negara Anda ke dalam setiap sistem itu sendiri.

Tampaknya sistem manajemen seperti contoh AppHub tidak berlaku dengan baik untuk paradigma pengembangan Anda. Menciptakan sistem super yang merangkum sistem lain tampaknya mengalahkan tujuan memisahkan logika dari data.

Ini dapat membantu Anda memahami apa yang saya maksud dengan tidak harus secara eksplisit menangani status permainan:

http://paulgestwicki.blogspot.com/2012/03/components-and-systems-of-morgans-raid.html


Silakan lihat edit saya. Maaf kalau saya bingung.
Eva

Diperbarui untuk mencerminkan penemuan baru dan hasil edit Anda. Semoga seseorang dengan lebih banyak pengalaman dalam membangun sistem entitas akan berpadu, karena ini bukan bidang yang saya punya banyak pengalaman.
Cypher

Bagaimana dengan menghapus dan menambahkan sistem saat kondisi gim berubah? Misalnya, saat Anda menjeda game mungkin MovementSystem atau CollisionSystem Anda tidak diperlukan, tetapi Anda tetap ingin RenderSystem Anda untuk menggambar hal-hal di layar. Bisakah sistem yang aktif mewakili kondisi permainan?
argenkiwi

0

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 getRelevantObjectspanggilan Anda harus memungkinkan pemutakhiran untuk menemukan objek Game, atau sebaliknya.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.