Optionen beim Spiel



  • Hey leute,
    ich programmiere zur Zeit ein kleines naja nennen wir es "RPG" in C++ (nur in Konsole). Dient auch lediglich der Freizeitgestaltung und den Übungszweck. Nun möchte ich gerne den Benutzer ein paar Optionen zur Verfügung stellen. Da ich versuche mein Stil zu perfektionieren stelle ich mir deshalb immer die Frage ob die Art und Weise wie ich das Problem löse "die Richtige" ist. Also ob sie effizient übersichtlich, sicher und so weiter ist.
    Ich habe für meinen Spieler und den Gegner jeweils eine klasse. Nun hab ich mir überlegt für Optionen auch eine Klasse zu erstellen und dann davon ein Objekt zu erzeugen.
    Ist diese Methode zu empfehlen?
    mir stellt sich nur dann die frage wie ich die Klasse des Spielers dann mit der der Optionen sozusagen zu "synchronisieren" also die Optionen sollen sich ja auch auf den Spieler und das Spiel Auswirkung. dafür müsste ich ja dann immer haufenweise Parameter in den Methoden der Spieler-klasse einfügen und immer übergeben.
    Wäre es dann sinnvoll das Objekt der Optionen-klasse als Attribut der Spieler-klasse einzubauen?

    Würdet ihr das auch so machen? Oder nur teilweise so?
    Oder vielleicht doch ganz anders ?
    Würde mich über hilfreiche Tipps und Tricks freuen da ich immer daran interessiert bin es "richtig" zu machen.^^

    Danke schonmal und ich freue mich auf eure Antworten 🙂



  • Eine Klasse für die Optionen ist schonmal ein guter Ansatz. Ggf werden später da auch noch mehrere Klassen draus, wenn die Optionen umfangreicher werden (Graphikoptionen, Gameplayoptionen, ..)

    Die Daten zwischen Spieler-Objekt und Optionen-Objekt zu synchronisieren würde ich eher nicht empfehlen. Es gibt da die schöne Regel "Don't repeat yourself (DRY)". Wenn du irgendetwas doppelt schreibst, machst du es mindestens einmal zu viel. Da du die Daten schon in der Optionen-Klasse hast, brauchst du sie nicht noch einmal extra in der Spieler-Klasse, zumal der Spieler wohl nur einen Teil der Optionen benötigt (z.B. sowas wie einen Schwierigkeitsgrad - Graphik-Einstellungen dagegen interessieren das Spieler-Objekt wohl eher nicht).
    Statt also jede Option einzeln zu übergeben oder sonstwie zu synchronisieren, kannst du einfach einen Zeiger auf das Optionen-Objekt übergeben.

    Die Fragen, die du dir nun stellen mußt sind "Wem gehört das Objekt?" und "Wer muss das Objekt benutzen?", bzw. welches andere Objekt sollte Schreib- und welches Lese-Zugriff auf die Optionen bekommen? Ansich ist es eine gute Idee, immer nur so wenig Zugriff wie möglich zu gewähren und Daten zu kapseln, anstatt jedes Objekt im Spiel pauschal überall hin schreiben zu lassen.

    Wenn du so etwas wie ein "Spiel"-Objekt hast, das die Spiel-Daten (Spieler, Level, Gegner, etc) verwaltet, dann wird das wahrscheinlich auch am ehesten der Besitzer des Optionen-Objekts sein. Falls dein Spieler-Objekt dann eh schon Zugriff auf das "Spiel"-Objekt hat, reicht es einfach, dem Spiel eine Funktion getOptions zu geben, mit der du den Zeiger auf das Optionen-Objekt zurückgibst.

    Idealerweise etwa in dieser Form:

    class Game {
        ...
    public:
        const Options* getOptions() const {
            return &options;
        }
    
    private:
        Options options;
    };
    

    Durch das Schlüsselwort const kann das Objekt, wenn du mittels "getOptions" darauf zugreifst, nur gelesen, aber nicht verändert werden.

    Alternativ kann man den Zeiger auch im Konstruktor des Spieler-Objekts übergeben, aber ich würde die Konstruktoren nicht mit unnötig vielen Parametern überladen, sowas wird schnell zu übübersichtlich.



  • Hey danke schonmal für deine Antwort.
    Auf die idee mit der Game-Klasse bin ich nicht gekommen.
    Aber find ich gut und werds gleich mal ausprobieren 😉 .

    Dafür stellt sich mir jetzt wiederum eine andere Frage...
    Wenn ich das so wie du sagst mache. Dann würde ich meine Player und mein Gegner als Attribute der Game-Klasse machen.So hier:

    class Game {
        ...
    public:
        const Options* getOptions() const {
            return &options;
        }
    
    private:
        Options options;
        Player p;
        Enemie e;
    };
    

    die Klasse Player und Enemie sind beide von der selben klasse abgeleitet.
    Ist es dann sinnvoll das gesamte Spiel in der Klasse verlaufen zu lassen ? oder doch lieber in der main?

    #include "Game.h"
    int main()
    {
        Game g;
        g.StartGame();
        return 0;
    }
    

    oder lieber viele funktionen schreiben mit denen ich in der main arbeite ?



  • So in etwa kannst du das machen. Die main-Funktion selbst hat dann keine weitere Aufgabe, als das Game-Objekt zu erstellen und dann die Kontrolle dorthin abzugeben. Damit vermeidest du irgendwelche globalen Variablen, die sonstwo herumfallen, und hast stattdessen alles schön geordnet in der Game-Klasse zusammengefasst.

    Die Game-Klasse selbst sollte aber auch nicht alle Verantwortung im Programm übernehmen. Das allgemeine OOP-Design ist, daß man für jedes Aufgabengebiet ein Objekt hat, und dieses Objekt dann auch nur dafür verantwortlich ist.
    Daß du also schon eine Klasse Player und Enemy (und eine gemeinsame Basisklasse) hast, ist also schonmal genau der richtige Weg. Konsequent weitergedacht heißt daß, daß Dinge, die Gegner betreffen, auch nur von der Enemy-Klasse behandelt werden, selbiges für Spieler, Map, etc. Die Game-Klasse delegiert also im wesentlichen auch nur noch an die entsprechenden Objekte.
    Dadurch reduzierst du die Abhängigkeiten von Objekten untereinander auf wenige Schnittstellen. Die Game-Klasse muss nicht wiessen, wie Player oder Enemy intern aufgebaut sind, sondern kennt nur die wichtigen Schnittstellen wie z.B. handleInput(int keycode), o.ä.



  • sehr schön.
    Dann hab ich ja alles richtig gemacht.
    und trotzdem immer dieses blöde Gefühl das ganz falsch zu machen. 😃

    Danke dir für deine Hilfe 😉


Anmelden zum Antworten