Bir varlık / bileşen tabanlı sistemde oyun durumları nasıl yapılandırılır


11

Burada açıklandığı gibi bileşenler arasında iletişim kurmak için sistemleri kullanan varlık-bileşen paradigmasıyla tasarlanmış bir oyun yapıyorum . Gelişimimde oyun durumları (duraklatılmış, oynama, seviye başlangıcı, yuvarlak başlangıç, oyun bitti vb.) Eklemem gereken noktaya ulaştım, ancak bunu çerçevemle nasıl yapacağımdan emin değilim. Ben herkesin başvuru gibi görünüyor oyun devletleri bu kod örneğine baktım , ama benim çerçeveye uygun olduğunu sanmıyorum. Her devletin kendi çizimini ve güncellemesini ele aldığı görülüyor. Benim çerçevemde, sistemleri kullanarak tüm güncelleştirmeleri işleyen bir SystemManager vardır. Örneğin, işte RenderingSystem sınıfım:

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());
    }

}

Ayrıca oyunumdaki tüm güncellemeler olaya dayalıdır. Onlarınki gibi her şeyi aynı anda güncelleyen bir döngüm yok.

Çerçevemi seviyorum çünkü yeni GameObjects eklemeyi kolaylaştırıyor, ancak bileşenler arasında iletişim kurarken bazı bileşen tabanlı tasarımların karşılaştığı problemler yok. Sadece işe ara vermek için mandren yapmaktan nefret ederdim. Varlık bileşeni tasarımını kaldırmadan oyunuma oyun durumları eklememin bir yolu var mı? Oyun durumu örneği aslında çerçeveme uyuyor mu ve sadece bir şey eksik mi?

EDIT: Çerçevemi yeterince iyi açıklamamış olabilirim. Bileşenlerim sadece veri. C ++ 'da kodlama olsaydım, muhtemelen yapı olurdu. İşte bir örnek:

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;
    }

}

Bileşenlerim birbirleriyle iletişim kurmuyor. Sistemler bileşenler arası iletişimi idare eder. Sistemlerim de birbirleriyle iletişim kurmuyor. Ayrı işlevleri vardır ve kolayca ayrı tutulabilirler. MovementSystem'ın oyun nesnelerini doğru bir şekilde taşımak için RenderingSystem'ın neler yarattığını bilmesine gerek yoktur; sadece bileşenler üzerinde doğru değerleri ayarlamanız gerekir, böylece RenderingSystem oyun nesnelerini oluşturduğunda doğru verilere sahiptir.

Oyun durumu bir sistem olamazdı, çünkü bileşenler yerine sistemlerle etkileşime girmesi gerekiyor. Veri ayarlamıyor; hangi işlevlerin çağrılması gerektiğini belirler.

GameStateComponent mantıklı olmaz çünkü tüm oyun nesneleri bir oyun durumunu paylaşır. Bileşenler nesneleri oluşturan şeydir ve her biri her farklı nesne için farklıdır. Örneğin, oyun nesneleri aynı sınırlara sahip olamaz. Çakışan sınırlara sahip olabilirler, ancak bir BoundsComponent paylaşırlarsa, gerçekten aynı nesnedirler. Umarım, bu açıklama çerçevemi daha az kafa karıştırıcı yapar.

Yanıtlar:


4

Gönderdiğiniz bağlantıyı okumadığımı itiraf edeceğim. Düzenlemenizden ve sağlanan bağlantıyı okuduktan sonra konumum değişti. Aşağıdakiler bunu yansıtır.


Geleneksel anlamda oyun durumları hakkında endişelenmeniz gerektiğini bilmiyorum. Geliştirmeye yaklaşımınızı göz önüne alındığında, her bir sistem onlar, aslında, o özgü böyledir olan oyunun devlet yönetimi.

Bir varlık sisteminde, bileşenler sadece veridir, değil mi? Bir devlet de öyle. En basit haliyle, sadece bir bayrak. Durumlarınızı bileşenlere dönüştürürseniz ve sistemlerinizin bu bileşenlerin verilerini tüketmesine ve içindeki durumlara (bayraklara) tepki vermesine izin verirseniz, eyalet yönetiminizi her sistemin kendisine inşa edersiniz.

Görünüşe göre AppHub örneği gibi yönetim sistemleri geliştirme paradigmanıza çok iyi uymuyor. Diğer sistemleri kapsayan bir süper sistem oluşturmak, mantığı verilerden ayırma amacını ortadan kaldırıyor gibi görünüyor.

Bu, oyun durumlarını açıkça işlememek zorunda kalmadan ne demek istediğimi anlamanıza yardımcı olabilir:

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


Lütfen düzenlememe bakın. Kafa karıştırıcı olsaydım özür dilerim.
Eva

Yeni keşifleri ve düzenlemelerinizi yansıtacak şekilde güncellendi. Umarım varlık sistemleri oluşturma konusunda daha fazla deneyime sahip biri, burası çok fazla deneyime sahip olduğum bir alan olmadığından
devreye girer

Oyun durumu değiştiğinde sistemleri kaldırmaya ve eklemeye ne dersiniz? Örneğin, oyunu duraklattığınızda belki MovementSystem veya CollisionSystem gerekmez, ancak yine de RenderSystem'ınızın ekrana bir şeyler çizmesini istersiniz. Aktif sistemler bir oyun durumunu temsil edebilir mi?
argenkiwi

0

Durum, bir nesneye uygulanan bir değerdir. Oyun durumu, adından da anlaşılacağı gibi, bir 'Oyun' nesnesinin durumu olacaktır. Bu Oyun nesnesi - veya büyük olasılıkla üzerindeki belirli bir bileşen - geçerli durumu izler ve mevcut durumu kolaylaştırmak için gerekli olan nesneleri yaratır veya yok eder. Bileşenleriniz yalnızca veri olduğundan, ilişkili bileşenin yalnızca bir örneği olsa da, bunun üstesinden gelmek için yeni bir Sisteme ihtiyacınız olacaktır.

Güncellemeyi nasıl uyguladığınız net olmadığında duraklamayı nasıl uygulayacağınız hakkında yorum yapmak zordur. Oyun nesnesi oyunun duraklatıldığını söylüyorsa, güncelleme olaylarını yayan işlem bunu yapmamayı seçebilir. Oyun nesnesinin güncelleme işlemiyle nasıl iletişim kurduğu size kalmış; belki de getRelevantObjectsçağrınız güncelleyicinin Oyun nesnesini bulmasına izin vermelidir, ya da tam tersi.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.