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

botlin

Treue Seele

  • »botlin« ist der Autor dieses Themas

Beiträge: 139

Wohnort: Berlin

Beruf: Fachinformatiker für Anwendungsentwicklung, Student Internationale Medieninformatik

  • Private Nachricht senden

1

16.08.2012, 11:40

Objektverwaltung in Spielen

Hallöchen,
ich komm mal gleich zur Sache. Es geht mir um die Verwaltung von Objekten in Spielen, also Bäume,Terrain,Figuren,Menüstrukturen,Busttons,Labels,Sprites,3D Objekte, Lichquellen und so weiter.

Ich überlege nun schon seit einiger Zeit wie man sowas am sinnigsten anstellen könnte. Habe mir auch schon die eine oder andere Seite über Scenengraphen,Octrees,Quadtrees durchgelesen.

Beispiel: Ich möchte eine 3D Scene sowie ein Pausenmenü darstellen. Die Scene besteht aus ein paar Lichtquellen,ein paar statischen Modellen, ein paar Figuren. eventuell noch ein Haus. Das Menü besteht im wesentlichen aus Sprites und Labels.

Diese ganzen Sachen statisch zu definieren ist eine Möglichkeit.Ich suche aber eine Möglichkeit mit der ich die Scene später durch einen Editor erweitern und abändern lässt. Dafür fehlt mir der Ansatz wie man alle diese verschiedenen Objekte sinnig verwaltet.

Ich bin auf den Scenengraph als Baumstruktur gestossen. Welchen ich auch schon testweise umgesetzt habe.
Allerding stellt sich mir dann die Frage ob sich der eventuell nur zur verwaltung von Renderdaten eignet.
Ich stelle mir das schwierig vor auf Basis dieses SG komplexe Zusammenhänge zwischen Charakteren zu definieren.
Zum Beispiel Dialoge die je nach Situation varieren können.Abhängig ob andere Objekte im SG einen bestimmten status haben.
Woher weiss Objekt A ob Objekt B in einem ganz anderen Zweig überhaupt noch existiert.
Ist es überhaupt sinnig alles in einen Scenengraphen zu stecken? Oder Sollte man diesen wirklich nur für das Rendern verwenden?
Und wenn ja wie lassen sich dann die anderen Objekte am besten verwalten

Habt ihr Anregungen,Ideen, oder Erfahrungen die mir helfen können?

FSA

Community-Fossil

  • Private Nachricht senden

2

16.08.2012, 14:57

Ich schreibe immer alles in einer Datei wo die Objekt ID, Material, Transformation, und andere Daten stehen. Dann sage ich meinem ObjectHandler dass er das Objekt mit der ID in eine Array einzusetzen. In dem Array stehen alle Infos. Dann wird mit einer For Schleife einfach alles gerendert.

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

3

16.08.2012, 17:40

Ich verstehe nicht was du uns damit sagen willst. Du hälst irgendwelche Daten in einem Array, die sich vorher in Dateien auf der Festplatte befinden. Soweit habe ich es verstanden;) Wirklich hilfreich finde ich das nicht, da du nichts genauer beschreibst und die Zusammenhänge nicht klar werden.
Ich mache es mir meist einfach und halte einfach Listen von meinen Objekten im Spiel. Normal habe ich eine Instanz vom Spieler, dann habe ich eine Liste für Gegner, dazu kommt eine Liste für Items und noch eine Liste für Projektile. Ich erstelle hierfür normal pro Listentyp eine Basisklasse für ein Objekt dieser Liste. Wenn ich andere Arten benötige, leite ich einfach von dieser Klasse ab. Zum Teil reicht auch manchmal ein Objekttyp für alle Fälle. Zum Beispiel, wenn Projektile keine unterschiedliche Logik haben, oder diese Logik ausgelagert ist. Da hat aber jeder andere Vorlieben. Diese Listen kann ich nun durchlaufen und rendern oder Logik auf ihnen ausführen. Je nachdem was benötigt wird. Dies ist ein sehr einfaches System und reicht für meine Anwendungsfälle normal aus. Ich habe auch schon mit anderen Systemen rumgespielt. Die Strukturen sollen dich ja unterstützen. Wenn du zum Beispiel viele Objekte verwalten musst, könnte ein Quadtree sicher eine Sinnvolle Datenstruktur sein um deine Objekte zu verwalten. Durch Baumstrukturen wie zum Beispiel Szenegraphen hast du den Vorteil, dass du Vererbung von Eigenschaften implementieren kannst. Zum Beispiel kannst du einen Knoten unsichtbar machen und seine Kinder sind es direkt mit. Dafür ist die Verwaltung im Hintergrund natürlich manchmal etwas aufwendiger und du musst den ganzen Kram erst mal implementieren. Mein Tipp ist alles so einfach zu halten wie du musst. Klar kann man mal aus Interesse probieren wie bestimmte Sachen so funktionieren, aber an sich implementiert man Sachen oft viel komplizierter als man müsste, nur weil es irgendjemand oder irgendetwas vorschreibt, für einen selbst aber eigentlich unwichtig ist/wäre.
„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.“

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

16.08.2012, 19:09

Habt ihr Anregungen,Ideen, oder Erfahrungen die mir helfen können?

Sagen wir's mal so: Bei mir sind weit über 100 Klassen an so einem flexiblen Zusammenspiel beteiligt, damit die durch einen Editor generierten Daten dynamisch in Szenen gestaltet werden. Vom Prinzip her wird wohl jede Engine auf etwas ähnlichem aufbauen und eine Engine ist auch das, was Du wohl suchst. Diese handhabt dann die Darstellung, Animation und das Rendering all der verschiedenen Objekte. Das ist sicher nichts, was man mal so nebenbei in wenigen Klassen abhandelt. Gut, ein Jump'n'Run von mir hatte nur eine Hand voll Klassen, das waren dann aber auch entsprechend üble Monster und alle Steuerungen, Grafik-Elemente und Gegner waren in Form und Verhalten somit hart kodiert.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

botlin

Treue Seele

  • »botlin« ist der Autor dieses Themas

Beiträge: 139

Wohnort: Berlin

Beruf: Fachinformatiker für Anwendungsentwicklung, Student Internationale Medieninformatik

  • Private Nachricht senden

5

17.08.2012, 09:53

Ja das mit den 100 Klassen glaub ich gut und gerne. Wenn ich sehe was ich nur für die Graphikkomponente schon an Klassen besitze. Allein mein jetziger Scenegraph besitzt bereits 16 Klassen wobei 10 davon für verschiedene Typen von Nodes sind. Also kurz gesagt bliebt mir wohl nur übrig das Ding wachsen zu lassen und mit der Zeit zu Optimieren.

FSA

Community-Fossil

  • Private Nachricht senden

6

17.08.2012, 17:04

@Schorsch: Ich habe eine Datei wo Daten über Modelle, Level und die Szene drinnen stehen. Diese Datei lese ich aus und sage dem ObjectHandler das er in dem Array an Position Model-ID ein Objekt vom Typ ObjectType einsetzten soll. Dabei kann ObjectType alles sein was man benutzen kann(Lichter, Areas, Modelle, Nodes)

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

7

17.08.2012, 18:42

Also hälst du alle Sachen in einem Array? Dann durchläufst du jedes mal alle Objekte wenn du nur bestimmte Objekte benötigst? Oder verstehe ich dein Konzept falsch.
„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.“

FSA

Community-Fossil

  • Private Nachricht senden

8

17.08.2012, 21:02

Zitat von »Schorsch«


Also hälst du alle Sachen in einem Array?

Ja.

Zitat von »Schorsch«


Dann durchläufst du jedes mal alle Objekte wenn du nur bestimmte Objekte benötigst?

Jaein.
Ich habe ein Array aus Strukturen. Eine Struktur enthält folgende Informationen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
struct EditObjects
{
    // General
    int             iIndex;
    Modeltyp        modeltyp;
    Vector3         vPos;
    Vector3         vRot;
    bool            bActive;

    // Objekt
    NewtonBody*     nBody;
    D3DMATERIAL9    Material;
    float           fMass;
    bool            bPhysic;

    // Licht
    bool bLightOn;
    Color Ambient,Diffuse,Specular,GAmbient;
    float InnerCone,OuterCone,Radius;
    int LightTyp; // 0=Spot; 1=Dir; 2=Point; 3=Kein Licht
    bool bSpecular;
};

Ich laufe beim Rendern jedes Element durch und gucke ob da was ist. Wenn ja, dann rendere ich es, oder erhöhe die Anzahl der Lichter(die sind nochmal im eigenen struct. EditObjects wir überall verändert und kopiert die nötigen Infos in das Licht-Struct das Modell-Struct,...)

Hier die Funktion zum Hinzufügen(Nur ein Objektyp, sonst wir das hier zu rieseig)

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
int ObjectHandler::AddObject(Modeltyp modeltyp, float fMass, Vector3 vPos, int iID)
{
    int iFreeIndex = 0;
    switch(modeltyp)
    {
        case MT_WALLTEST:
            iFreeIndex = FindFreeObject();
            if(iFreeIndex == -1)
            {
                return -1;
            }

            if(iID != -1)
                iFreeIndex = iID;

            m_EditObjects[iFreeIndex].iIndex = iFreeIndex;
            m_EditObjects[iFreeIndex].bActive = true;
            m_EditObjects[iFreeIndex].modeltyp = modeltyp;
            m_EditObjects[iFreeIndex].vRot = Vector3(0.0f);
            m_EditObjects[iFreeIndex].vPos = vPos;
            m_EditObjects[iFreeIndex].nBody = m_RigidbodyHandler->CreateRigidBody(nWorld,
                m_AllObjects.nWallTest,
                5.0f,
                MatrixRotation(m_EditObjects[iFreeIndex].vRot) *
                MatrixTranslation(m_EditObjects[iFreeIndex].vPos));

            NewtonBodySetUserData(m_EditObjects[iFreeIndex].nBody, (void*)iFreeIndex);
            if(m_bObjectSelected)
            {
                D3DMATERIAL9 mat;
                mat.Ambient = Color(0.5f,0.5f,0.5f);
                mat.Diffuse = Color(0.5f,0.5f,0.5f);
                //mat.Specular = Color(0.5f,0.5f,0.5f);
                mat.Emissive = Color(0.5f,0.5f,0.5f);
                m_EditObjects[iFreeIndex].Material = mat;
            }
            else
            {
                D3DMATERIAL9 mat;
                mat.Ambient = Color(1.0f,1.0f,1.0f);
                mat.Diffuse = Color(1.0f,1.0f,1.0f);
                //mat.Specular = Color(1.0f,1.0f,1.0f);
                mat.Emissive = Color(1.0f,1.0f,1.0f);
                m_EditObjects[iFreeIndex].Material = mat;
            }
            return iFreeIndex;
        break;
        }
}

Danach wird noch die UpdateLights Funktion aufgerufen, die die nötigen Infos von EditObjects in sich hinein Kopiert.
Klar sowiet? :P

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

9

18.08.2012, 13:16

Ich finde es gut, wie es in Unity gemacht wird.
Da ist ein GameObject von sich aus erst einmal leer und hat nur einen Namen und eine ID.
So ein Objekt kann dann beliebige Komponenten enthalten, z.B. eine Transformation, ein 3D-Mesh, eine Lichtquelle, Skripte, Sounds, ...
Ein Szenengraph entsteht durch die Transformations-Komponente, denn dort kann man ein anderes Objekt als Parent setzen.
Das Gute dabei ist, dass du jede Art von Objekten, ob sie nun sichtbar sind oder rein virtuell, abbilden kannst und jedes Objekt nur die Daten speichert, die es auch wirklich braucht.
Für's Rendering könnte man dann eine räumliche Datenstruktur aufbauen, die nur die grafischen Komponenten enthält.
Und die Objekte selbst kann man in einer Liste oder einer Hash-Map speichern, um sie schnell durch ihren Namen ansprechen zu können.

Thoran

Alter Hase

Beiträge: 520

Wohnort: Stuttgart

Beruf: Senior Software Engineer

  • Private Nachricht senden

10

20.08.2012, 11:23

So ähnlich wie David das erklärt hat, mach ich das auch bei meiner Engine. Ich habe nur Entities (dyn) oder Nodes(stat). Diese haben ein GameObject zum Speichern von assoziierten Daten. Wenn dann noch eine visuelle Repräsentation im Spiel nötig ist, wird dem Entity/Node eine Referenz auf einen Szenenknoten im Szenengraph übergeben. Damit kann man dann sowohl normalle Spielgrafik darstellen und mit spielrelevanten Daten verknüpfen als auch "unsichtbare" Trigger realisieren, die nur für die Spiellogik benötigt werden. Das GameObject kann dann noch in der Skriptsprache angesprochen werden um die Daten eines Objekts zu manipulieren (bsp. HP, Stamina etc.)

Thoran
Mein Entwicklertagebuch
Aktuelles Projekt: Universum Espionage
Eingestellt:Spieleengine SilverCore
Organisator "Spieleentwickler Stammtisch Stuttgart"

Werbeanzeige