Konfiguration: Global oder in den Objekten?



  • Mahlzeit!

    Ich habe eine Frage bzgl. Design: Ich habe ein Level, das aus mehreren Objekten besteht, z.B. Boxes and Balls. All Objekte eines Typs haben nun bestimmte immutable Eigenschaften, die von allen Instanzen geteilt werden: z.B. gibt es eine Ball-Geschwindigkeit, eine Ball-Größe, bestimmte Ball-Farben, Box-Farben usw.

    Nun stell ich mir die Frage: Definiere ich diese Eigenschaften in den jeweiligen Klassen oder "global" in der Level Klasse. Konkret:

    Möglichkeit 1 (In den Objekten selber):

    class Ball {
    public:
        Vec2                  position;
        float                 radius;
    
        ColorType             colorType;
        static const Color4F  ballColors[]; // Legt fest WIE Farbe rot, blau etc definiert ist
        static const float    speed; // Geschwindigkeit jedes Balls
    ...
    };
    
    class Box {
    public:
        enum class Type {
            Blocking,
            Hazard
        };
    
        Vec2                position;
        Type                type;
        // Es gibt 2 Box-Typen und hier werden deren Farben definiert:
        static const Color4F barrierBlockingColor;
        static const Color4F barrierHazardColor;
    

    Oder Variante 2: Die static const Konfig Member verschwinden aus den Klassen Box, Ball etc. und landen alle in Level:

    class Level {
    private:
        std::vector<Box*>   mBoxes;
        std::vector<Ball*>  mBalls;
    
        // Configuration
        static const Color4F boxBlockingColor;
        static const Color4F boxHazardColor;
    
        static const Color4F ballColors[];
        static float ballSpeed;
    

    Vorteil von Variante 2 ist, dass ich alle Level-Einstellungen zentral an einer Stelle ändern kann. Bei Variante 1 gefällt mir, dass die Eigenschaften in ihrer jeweiligen Klasse stehen.

    Was findet ihr besser?



  • Sicher nicht im Level, zumindest nicht in der Form. Das ist total unflexibel und du würfelst alle Zuständigkeiten durcheinander. Ein Level sollte sich nicht um Ballfarben kümmern.
    Vielleicht eher sowas wie eine abstrakte Eigenschaftsverwaltung, bei der man über eine ID an den Wert rankommt. Sowas könnte man schon eher zentral im Level hinterlegen.
    Und brauchst du überhaupt eine Klasse wie Ball? Sagt dir ECS was?



  • Mechanics schrieb:

    Sicher nicht im Level, zumindest nicht in der Form. Das ist total unflexibel und du würfelst alle Zuständigkeiten durcheinander. Ein Level sollte sich nicht um Ballfarben kümmern.
    Vielleicht eher sowas wie eine abstrakte Eigenschaftsverwaltung, bei der man über eine ID an den Wert rankommt. Sowas könnte man schon eher zentral im Level hinterlegen.
    Und brauchst du überhaupt eine Klasse wie Ball? Sagt dir ECS was?

    Was soll das für eine Frage sein? Wieso ich eine Klasse Ball brauche? Na weil ich eben Bälle herumfliegen lassen will 🙄
    Nein, ECS sagt mir nichts. Ist wohl zu viel verlangt, dass man so einen nicht alltäglichen Begriff einfach ausschreibt...



  • Entity Component System - ist mittlerweile ein alltäglicher Begriff in der Spieleentwicklung. Und wenn man danach vorgeht, könnte es durchaus sein, dass du keine Klasse Ball brauchst.
    Lies dich da ein bisschen ein, selbst wenn du das dann nicht verwendest, sollte es dir ein paar Denkanstöße geben.



  • Ich habe jetzt einige Zeit lang gesucht, finde aber nur sehr oberflächliche Artikel zu diesem ECS. Kennst du eine Seite mit konkreten C++ Beispielen?



  • Nicht direkt... Du kannst dir mal anschauen, wie Unity bzw. deren API funktioniert, die bauen auf ECS auf. Und man findet schon einige Implementierungen und Videos im Internet, aber das ist alles gewöhnungsbedürftig und man braucht erstmal eine Weile, um sich mit der Idee anzufreunden.

    Der erste Treffer bei mir ist das

    https://github.com/alecthomas/entityx

    Schaut auf den ersten Blick auch nicht so verkehrt aus.

    Aber wie gesagt, mir gings erstmal eher darum, dass du dir die Idee dahinter anschaust, ob man das unbedingt in der Form umsetzen muss, weiß ich auch nicht.
    Was aber sehr wahrscheinlich keine gute Idee ist, sind spezialisierte Klassen wie "Ball". Die Wahrscheinlichkeit ist hoch, dass du nicht wirklich eine Klasse Ball brauchst. Es bietet sich schon eher an, eine generische Klasse aus mehreren Komponenten zusammenzustecken - z.B. RenderComponent und CollisionDetectionComponent. Dann kannst du später auch ganz einfach über einen Level Editor einen Stein hinzufügen und musst keine Klasse dafür schreiben.



  • Ehrlich gesagt finde ich, dass das mit diesem ECS in Richtung Overdesign geht. Meine paar Klassen habe ich in 5 Minuten geschrieben und zu diesem mysterioesen ECS finde ich nicht mal ein einziges gutes TUtorial. Habe das Gefühl, dass das eher was für große Systeme wie Engines ist und bei mir total übertrieben wäre.

    Irgendwie wurde mir das jetzt auch zu Offtopic. Auf meine eigentliche Frage hat offenbar keine eine Antwort;( Ich habe die Konfigvariablen jetzt einfach in die konkreten Klassen geschoben.



  • Du hast das Wesentliche vergessen, nämlich die Methoden, die diese Konstanten benutzen. Wo die Methoden sind, gehören wahrscheinlich auch die benötigten Konstanten hin.


Anmelden zum Antworten