Spielarchitektur für Items



  • Hey Leute,
    wiedereinmal bin ich steckengeblieben...
    Diesmal geht es um Items im Spiel.
    Es ist eine art RPG wo der spieler verschiedene Eigenschaften wie Angriff,verteidung usw. hat.
    Die Items sollen unterschiedlich sein und sich auch unterschiedlich auf die Eigenschaften auswirken.

    1. Sollte die klasse des spielers entscheiden wie die items benutzt werden oder sollte ich in der Items-klasse eine methode implementieren die ein zeiger auf das Spielerobjekt bekommt und dann verändert?

    2. Wie stelle ich es am besten an das die Items unterschiedliche auswirkung haben ohne sowas zu machen wie der itemklasse attribute in dieser art hinzuzufügen:

    class Item
    {
    	string name;
            int addLife;
            int addDef;
            int addAtt;
            int addSpeed;
            int usw.....
    };
    

    und dann die verwendung so zu realisieren:

    playerlife+=addLife;
    playerdef+=addDef;
    playerspeed+=addSpeed;
    .....
    

    weil diese methode erscheint mir reichlich speicherverschwenderich wenn das item sich zum Beispiel nur auf 2 eigenschaften auswirken soll ?!

    hab aber keine idee...
    gibt es vlt sowas das man dem item einen zeiger auf die zu verändernde eigenschaft hinzufügen kann oder so was ähnliches ?

    lg sc0rpe
    und danke im vorraus 🙂



  • Du machst aus dem Item ein Funktor - also eine Klasse, die einen operator() hat, / eine Funktion, die/der ein Spieler/Objekt/wasauchimmer als Referenz erhält und entsprechend bearbeitet.
    Mit Klassen könntest du dann sogar noch einen Timer oder ähnliches einbauen.


  • Mod

    Sc0rpe schrieb:

    1. Sollte die klasse des spielers entscheiden wie die items benutzt werden oder sollte ich in der Items-klasse eine methode implementieren die ein zeiger auf das Spielerobjekt bekommt und dann verändert?

    die items sollten einfach angewandt werden, weder items noch spieler oder moebelstuecke oder ruestungen oder sonst was sollte wirklich 'entscheiden'.

    1. Wie stelle ich es am besten an das die Items unterschiedliche auswirkung haben ohne sowas zu machen wie der itemklasse attribute in dieser art hinzuzufügen:
    class Item
    {
    	string name;
            int addLife;
            int addDef;
            int addAtt;
            int addSpeed;
            int usw.....
    };
    

    und dann die verwendung so zu realisieren:

    playerlife+=addLife;
    playerdef+=addDef;
    playerspeed+=addSpeed;
    .....
    

    ja, suboptimal, flexibel und generisch ist es mit:

    class Item
    {
    	string name;
            std::vector<int> features;
    };
    

    und angewendet halt indem du drueberiterierst. dann kannst du alle eigenschaften, wie es sein sollte, mittels daten festlegen. also irgendwo ein script das festlegt welche + und - ein item hat.

    weil diese methode erscheint mir reichlich speicherverschwenderich wenn das item sich zum Beispiel nur auf 2 eigenschaften auswirken soll ?!

    ja und? eine textur hat vermutlich mehr speicherverbrauch als deine ganzen items 😛
    und falls es dir wirklich zuviel wird, braust du halt eine indirektion ein.

    struct Feature
    {
      int Index;
      int Value;
    };
    class Item
    {
    	string name;
            std::vector<Feature> features;
    };
    

    und anwenden kannst du es mit

    for(size_t a=0;a<myItem.features.size();a++)
      Entity.Feature[myItem.features[a].Index]+=myItem.features[a].Score;
    

    hab aber keine idee...
    gibt es vlt sowas das man dem item einen zeiger auf die zu verändernde eigenschaft hinzufügen kann oder so was ähnliches ?

    zeiger, index, ja, hat c++ alles.

    das nette daran es data driven zu machen statt special code zu implementieren ist dass du sehr flexibel bist. bei dingen die nicht wirklich schnell oder speicherguenstig sein muessen, bietet sich an es auf flexibilitaet auszulegen. das heisst, dass du benennungen (z.b. mal "mana" in "potion") aendern kannst, oder neue dinge einfuegen und entfernen koenntest, ohne dass du den code anfassen musst. denn mit der zeit waechst der code und es gibt mehr und mehr stellen an denen du die spezialfaelle bearbeiten musst um kleine aenderungen einzupflegen.

    dabei musst du deine configurationsdateien nicht cryptisch machen, also nicht sowas wie

    1: -5
    2: 0
    3: 0
    4: 7
    ...
    

    sondern mit klartext und ohne redundanz

    energy: -5
    geschwindigkeit: +7
    

    und im code kannst du dann nachschauen ob das soeben geparste feature schon existiert, dir den Index merken und notfalls es hinzufuegen und neuen index merken.

    natuerlich kein zwang, nur ein vorschlag 😉 (gibt sicherlich viele wege das zu loesen).



  • Hey Rapso,
    vielen Dank für deine Antwort!
    Dein Vorschlag gefällt mir. Hab nur ein Problem damit.
    Meine Playerklasse ist so aufgebaut:

    class player
    {
    private:
       int life;
       int def;
       int att;
       int speed;
       int block;
       int dodge;
       ....
    };
    

    das bedeutet ich müsste zur Umsetzung deines Vorschlages meine Attribute alle zusammen in ein Container stecken.
    Hab dabei dann allerdings bedenken wegen der Übersichtlichkeit.
    So habe ich alle meine Attribute schön einzeln und betitelt.
    Im Container kann ich dann nicht so schnell herausfinden welche Zahl welches Attribut darstellt.
    Außerdem denke ich das dann auch fast alles weiter ziemlich kompliziert dadurch wird.
    Gibt es vielleicht noch eine andere Möglichkeit bei der ich meine Variablen getrennt lassen kann?
    Oder sollte ich es dann doch wie oben beschrieben machen und den Items jedes einzelnen attribut geben und bei unverwendeten halt auf 0 setzen?
    Hatte halt lediglich bedenken darüber, dass sowas ein schlechter Programmierstil ist. Aber mir will einfach nichts besseres einfallen.
    😕

    edit:
    Gleich noch ein weiteres Problem. Wollte nun der Klasse Item eine Methode "Item-benutzen" hinzufügen, als paramter wollte ich eine Referenz auf das Player-Objekt entgegennehmen um es zu verändern, problem ist jetzt allerdings das ja die Attribute vom Player auf private sind und ich so nichts machen darf.
    Was nun ? einfach andersrum ? also der Player-Klasse die Methode geben und in dieser Das Item-Objekt mit "getItem()" geben lassen? Geht ja aber auch nicht weil die Item auch private sind. Und unzählige "getAttribut()" schreiben ist glaub auch nicht die richtige Lösung.


Anmelden zum Antworten