Du bist nicht angemeldet.

Werbeanzeige

1

17.04.2019, 13:38

[C++] Item Inventar realisieren

Hallo Leute,

ich brauche bitte eure Hilfe.

Folgendes Problem bzw. Überlegung:

Ich habe mehrere Klassen: Player, Inventory, Item, Game, Dungeon, Monster usw.

In Game läuft die Game Loop. Außerdem erzeugt Game ein Objekt vom Typ Player.
Player wiederum hat eine Membervariable Inventory(vector) welche beim erzeugen eines Player´s ebenfalls initialisiert wird.

Nun hat ein Game Objekt noch die Möglichkeit ein Objekt vom Typ Dungeon zu erzeugen, in welchem der Player Monster töten muss. Das führt dann wiederum dazu das man im Dungeon Objekte vom Typ Item droppen kann, welche dem Inventory im Player Objekt zugeordnet werden können. Wenn alle Monster im Dungeon tot sind, wird das Dungeon Objekt zerstört und man befindet sich wieder im Game Objekt.

Nun habe ich momentan eine Blockade im Hirn wie ich das mit dem Inventar und den Items realisieren soll. Folgende Probleme habe ich persönlich damit:

1) Wenn das Inventory im Player bspw. ein Vector vom Typ Item ist und ich die Größe von dem Vector nicht beim Initialisieren angebe, werden alle Objekte mit jedem push_back in einen "größeren" Bereich kopiert - der Destructor wird aufgerufen (also muss ich aufpassen was ich im Destructor mache). Sollte Item später als Basisklasse für andere Item Klassen dienen, wäre das aber auch nicht mehr möglich da ich ja dann Pointer benutzen muss um polymorphes Verhalten zu erzeugen oder?

2) Wenn das Inventory im Player bspw. ein Vector vom Typ Item* ist, zeigen alle Pointer auf einen ungültigen Speicherbereich.(Scope im Dungeon in welchem die Item Objekte erzeugt werden, wird verlassen bzw. das Dungeon Objekt wird komplett gekillt wenn alle Monster tot sind).

3) Wenn das Inventory im Player bspw. ein Vector vom Typ Item* ist und ich die Item Objekte im Dungeon mit new erzeuge, bleiben diese zwar auch nach verlassen des Scope´s bzw. des Dungeon Objekts valide (weil auf Heap erzeugt), jedoch muss ich mich dann selbst um das löschen kümmern (Außer ich benutze Smart Pointer??)

Unter der Voraussetzung das ich mein Problem richtig beschreiben konnte folgende Frage:
Was wäre eine valide Möglichkeit die Item Objekte im Player Inventar abzuspeichern, wenn das Inventar durch einen Vector repräsentiert wird?

Vielen Dank!

equinox

Frischling

Beiträge: 58

Beruf: Student

  • Private Nachricht senden

2

17.04.2019, 13:47

1) Es ist doch irrelevant ob dein Pointer "bewegt" wird oder nicht, der Speicherbereich in den er zeigt hängt ja nicht von seinem eigenen ab.

2) Du könntest auch Item& verwenden und deine Items mithilfe von std::move verschieben.

3) Ja, aber Smart-Pointer sind da meistens recht hilfreich und erleichtern das.

Angaben ohne Gewähr (weil könnte mich irren)

3

17.04.2019, 21:34

Nutze einfach std::shared_ptr<Item>.

2) Du könntest auch Item& verwenden und deine Items mithilfe von std::move verschieben.

Referenzen sind mehr oder weniger auch nichts anderes als Pointer. Und ein std::vector<T&> ist nicht im C++-Standard vorgesehen, das gibt nur Compilerfehler.
Cube Universe
Entdecke fremde Welten auf deiner epischen Reise durchs Universum.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Magogan« (17.04.2019, 21:48)


4

17.04.2019, 21:46

Vielen Dank für eure Antworten, dann probier ich das mal mit shared_ptr.

Grüße,

dot

Supermoderator

Beiträge: 9 850

Wohnort: Graz

  • Private Nachricht senden

5

18.04.2019, 02:22

Sofern du nicht tatsächlich eine Situation hast in der es mehrere Besitzer eines Objektes geben kann (was mir basierend auf obiger Beschreibung mal nicht der Fall zu sein scheint), nimm std::unique_ptr.

6

18.04.2019, 07:08

Wenn das Monster 2 Essenzen droppt und man nur eine tragen kann (Inventar voll), kann man shared_ptr und einen Variable für die Anzahl nutzen, um die teilweise zu plündern. Auch wenn man Items in verschiedenen Slots aufteilen will, ist das nützlich. Am besten ist es aber wohl, einfach eine ID für die Items zu verwenden, die braucht man eh zum Speichern.
Cube Universe
Entdecke fremde Welten auf deiner epischen Reise durchs Universum.

7

18.04.2019, 14:41

Im Prinzip gibt es in meiner Situation immer nur einen "Besitzer".
Vom Besitzer "Monster" zum Besitzer "Spieler Inventar". Aus dem Inventar sollte der Besitz dann eigentlich nur noch an ein Attribut "Spieler Waffe" bzw. "Spieler Rüstung" gehen (Da beim anlegen einer Waffe/Rüstung diese ja rein logisch betrachtet aus dem Inventar verschwindet").

Schorsch

Supermoderator

Beiträge: 5 187

Wohnort: Wickede

Beruf: Student

  • Private Nachricht senden

8

18.04.2019, 14:59

An sich kann man sich auch überlegen ob ein Item wirklich mehrfach vorkommen muss. In vielen Fällen reicht es ja vielleicht aus wenn das Inventar weiß welche Itemtypen der Spieler hat. Zusätzlich zum Typ des Items kann dort ja auch die Anzahl gespeichert werden, falls das nötig ist. Ansonsten kann weitere Logik der Items woanders untergebracht werden. Die Logik muss dann vermutlich auch nur einmalig da sein und nicht für jedes Item kopiert werden. Zum Beispiel kannst du irgendwo eine große Liste aller Items haben, wo deren Logik implementiert wird. An allen anderen Stellen wird dann nur auf den Itemtyp verwiesen und fertig.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

9

18.04.2019, 15:36

Würde bedeuten ich bräuchte eine Art "Item System" welches eine Tabelle mit ID->Item|Typ führt, sowie weitere Funktionalität für die ID->Item Auflösung bereit stellt.

Bspw. ich bin im Kampf und möchte ein Heiltrank nehmen. Nun müsste mein Inventar nach allen "consumables" durchsuchen und dann die entsprechende ID an das Item System übergeben. Das System selber gibt mir dann die Beschreibung/den Heilwert für das Item zurück. Oder beim angreifen. Ich hinterlege bei meinem Player eine ID für die Waffe und hole mir dann über das Item System die genauen Werte wie z.B den Schaden.

Hört sich das so sinnvoll an?

Schorsch

Supermoderator

Beiträge: 5 187

Wohnort: Wickede

Beruf: Student

  • Private Nachricht senden

10

18.04.2019, 15:47

Das wäre eine Möglichkeit. Das hängt alles stark davon ab was Items bei dir sind und wie diese funktionieren können. Unter der Annahme dass man Items bei dir alle benutzen oder einsetzen kann könntest du jeden Item eine Methode verpassen die prüft ob es aktuell einsetzbar ist. Bei einem Heiltrank könnte zum Beispiel geprüft werden ob der Spieler überhaupt Schaden erlitten hat. Weiterhin könnte das Item eine Methode bekommen um es auszuführen. Im Falle des Heiltranks würde diese dafür sorgen dass der Spieler Leben zurück bekommt. Vielleicht möchtest du in deinem Menü auch einen Namen und eine Beschreibung anzeigen. Das könnte auch hierhin verlegt werden.
Beim öffnen des Inventars geguckt welche Items der Spieler aktuell besitzt. Die IDs der Items werden dann an dein Item System übergeben und die zugehörigen Namen, Beschreibungen, etc davon geholt. Diese werden nun angezeigt. Items die der Spieler aktuell einsetzen kann könnten jetzt normal angezeigt werden, Items deren Bedingung nicht erfüllt ist nur ausgegraut und nicht anwählbar.
Solange sich Items des selben Typs die meisten Eigenschaften teilen ist das sinnvoll. Wenn das nicht der Fall ist wird es fuckelig da du dann einen Teil der Daten in deinem Itemsystem hast, und einen weiteren Teil in deinem Inventar. Wie gesagt, das hängt alles stark von der Art deiner Items ab.
Was du auf jeden Fall mitnehmen kannst ist dass nicht überall die Instanzen von Objekten rumgeschoben werden müssen.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Werbeanzeige