Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

propper

Frischling

  • »propper« ist der Autor dieses Themas

Beiträge: 21

Wohnort: Internet

  • Private Nachricht senden

11

27.01.2014, 21:07

Also jedes extra zu handhabende Objekt nicht in eine Liste mit den ganzen anderen schmeißen, sondern an einen eigenen Speicherplatz bzw. Liste und jedes Objekt, das dadrauf Zugriff haben muss, sagen wo es sich befindet.

Danke :thumbsup:

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

12

27.01.2014, 21:31

Es gibt sicher Verwaltungsaufgaben, die für alle deine Objekte gelten. Dafür ist eine allgemeine Liste sehr gut zu gebrauchen und du sparst dir doppelten Code.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

propper

Frischling

  • »propper« ist der Autor dieses Themas

Beiträge: 21

Wohnort: Internet

  • Private Nachricht senden

13

27.01.2014, 21:42

Ich werde mal morgen ein schöneres (Verwaltungs-)System für mein Spiel entwerfen, was diese Funktion gut beinhaltet.

//Edit:

Ich würde es jetzt so machen, dass wenn ein Objekt ein Wert eines anderen Objektes haben möchte, es an eine Klasse (evtl. sowas wie "ValueManager" oder so) eine Meldung gibt, dass es von der ObjektID (einmalige ID der Objekte) eben diesen Wert haben will. Also wird der ValueManager bei jedem Update() die geforderten Werte der bestimmten Objekte Speichern und durch eine virtuelle Funktion in der Basisklasse der Objekte die Werte in das Objekt schreiben, so, dass das Objekt, was die Werte benötigt, sie in sich selbst gespeichert hat und damit dann auch Problemlos drauf zugreifen kann.
Jetzt ist nur das Problem, wie man die Werte dem Objekt am besten übergibt. Ich habe mir überlegt, dass man sich eine Klasse schreibt, die die Werte aufnimmt und dann immer nur so eine Klasse mit den Werten drin an die verschiedenen Objekte übergibt. Jetzt ist zwar das Problem mit der Übergabe gelöst, aber wie kann man denn jetzt die Werte verschiedener Typen in so einer Klasse Speichern?
Evtl. mit überladenen Funktionen, aber die Funktionen zum aufnehmen können diese Infos dann ja letztendlich auch nicht speichern, denn es gibt ja nicht sowas wie überladene Variablen. Selbst wenn, müsste man für jeden Typ eine überladene Funktion neu definieren.
Ich habe mal was von Binärdateien gehört, kann man in solchen Dateien zum Beispiel die Werte Speichern und dann gibt man lediglich die Adresse der Datei an das Objekt weiter. Also so, dass das Objekt dann von der Datei aus das benötigte Objekt sich selbst baut ?( ?
Oder man übergibt nicht nur die einzelnen Werte, sondern gleich die ganze Klasse, aber wenn man das jetzt allgemein über die BasisKlasse der Objekte abhandelt, hat man ja wieder nicht den vollen Funktionszugriff.


Ich habe hier mal ein Beispiel von den Klassen gemacht:

(Link)



Wenn ein MainObject bzw. ein Baum/Gärtner einen Wert braucht (am besten schon im Konstruktor angeben), dann führt es die Funktion RequestData() aus, was in die RequestIDList über den Pointer, der beim Konstruktor übergeben wurde (konnte ich hier nicht als einen Pointer kennzeichnen, da mir das Klassendiagramm-Programm sonst einen Fehler warf), einen Eintrag hinzufügt, mit der GlobalID von sich selbst und der GlobalID von dem Objekt, von den es die Informationen haben will.
-> Beim nächsten Update() wird in der RequestIDList nachgesehen, was drin steht und für jedes Objekt NeedData auf true gesetzt.
-> Ein neues Element in DataList wird erstellt (sofern es nicht schon eins gibt, wo der 1. int die ObjektID ist), mit den Werten pair<ObjektID, std::map(ID des Ziels, new DataSaver)> (grob dargestellt)
-> Die benötigte Klasse wird in DataSaver aus der std::map gespeichert (hier liegt das Problem mit den Datentypen), bis jetzt über SetData([Objekt])
-> Funktion SendData([ID des Zielobjekts], [DataSaver aus der Map]) des Objektes, was die werte braucht wird aufgerufen und der DataSaver
-> in der Funktion werden die Werte in der Klasse so gespeichert, dass es die Klasse bei dem nächsten Update() verwenden kann
-> Wird jedes Update() wiederholt
-> Wenn in der BasisKlasse CloseConection() aufgerufen wird, wird der Eintrag aus der NeedDataList für das Objekt gelöscht, so, dass keine Daten mehr gesendet werden.


Das ist evtl. jetzt sehr kompliziert und komisch erklärt und man könnte das alles sicherlich einfacher machen, aber ich stehe grade irgendwie auf dem Schlauch :S


Wenn ihr Kritik, Verbesserungsvorschläge, komplett andere Vorschläge oder eine eventuelle Lösung des Gezeigten Problems da lasst, wäre ich euch sehr dankbar :)


mfg Propper

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »propper« (28.01.2014, 21:19)


propper

Frischling

  • »propper« ist der Autor dieses Themas

Beiträge: 21

Wohnort: Internet

  • Private Nachricht senden

14

03.02.2014, 18:25

gelöst!

Erstmal sry für den Doppelpost,
Da mein vorheriger Post völliger blödsin war, habe ich das jetzt mal anders gelöst:

In der Basisklasse ist nun folgende Funktion enthalten:

C-/C++-Quelltext

1
2
3
4
MainObject*  MainObject::GetMainObject(int ID)
{
    if(this->ID == ID) return this; else return NULL;
}


In dem ObjectManager, der die ObjectList und andere Funktionen für Objekte enthält, hat nun diese Funktion (zufällig gleicher Name):

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
MainObject* ObjectManager::GetMainObject(int ID)
{
    MainObject *pMainObject;
    for(ObjectIt = ObjectList.begin(); ObjectIt != ObjectList.end(); ObjectIt++)
    {
        pMainObject = *ObjectIt;
        if(pMainObject->GetMainObject(ID) != NULL) return pMainObject->GetMainObject(ID); //Objekt zurückgeben
    }
    return NULL; //ID nicht gefunden
}


Und da jedes Basisklasse einen Pointer zu der ObjectList hat, kann jede Basisklasse auch so eine ähnliche Funktion beinhalten:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//Für alle benötigten Objekte vorher einen Pointer definieren:
#include "Baum.hpp"
Baum *pBaum;

void MainObject::SetPointer()
{
    MainObject *pMainObject;
    for(ObjectIt = ObjectList->begin(); ObjectIt != ObjectList->end(); ObjectIt++)
    {
        pMainObject = *ObjectIt;
        /*
        Beispiel, welche Werte wo eingesetzt werden müssen:
        if(pMainObject->GetMainObject([SearchedID]) != NULL) p[PointerName] = dynamic_cast<[PointerClass]*>(pMainObject->GetMainObject([SearchedID]));

        Wieder mal das Beispiel "Baum". Wir müssen wissen, dass der gesuchte Baum die ID 1 hat, wenn das Objekt in der
        Liste gefunden wurde, wird es in dem Entsprechenden Pointer gespeichert. Vorher wird es noch gecastet, damit es
        Keine Basisklasse mehr ist:
        */
        if(pMainObject->GetMainObject(1) != NULL) pBaum = dynamic_cast<Baum*> (pMainObject->GetMainObject(1));
    }
}


Diese Funktion wird jetzt bei jedem Update()-Aufruf aufgerufen, damit die Pointer aktualisiert werden. Ich glaube sie werden sonst nicht aktualisiert, da sie nur auf eine Kopie des Objektes zeigen, oder liege ich da falsch?

C-/C++-Quelltext

1
2
3
4
void MainObject::Update(/* Args */)
{
    SetPointer();
}



So, danke für eure hilfe :thumbup:

mfg propper

//Edit:

Wo ist in diesem Forum der "Erledigt"-Button? :D

Werbeanzeige