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

kiba

Alter Hase

  • »kiba« ist der Autor dieses Themas

Beiträge: 327

Wohnort: NRW

Beruf: Azubi: Fach-Info. Anw.

  • Private Nachricht senden

1

19.12.2014, 01:26

DOD und GameObjects bzw. mit OOP-denkweise DOD verstehen

Hi Leute,
Seit langer Zeit hab ich mich schon mit C++11, C++14 und weiteren beschäftigt, unzählige Video angeschaut und bin dabei auf DOD (Data-Oriented Design) gestoßen.

Jetzt bin ich aber so ein eingefleischter OOP-Type und es fällt mir schwer mich in diese DOD-Welt reinzudenken da ich noch so Vorstellungen von Vererbung, dependencies und gekapselten Methoden hab.

Ich hab wegen DOD jetzt mehr die Vorstellung:

C-/C++-Quelltext

1
for(auto chara : charas)        update(chara);


ist "besser" als,

C-/C++-Quelltext

1
for(auto chara : charas)        chara.update();

was für mich irgendwie nach den selben aussieht.
In den meinsten GameObjects von mir benutzt ich höhstens vector (kein map, unordered, ...) und vl noch paar Enums.
Einige getter/setter und hilfsfunktionen um z.B. nach etwas Suchen.



(Link)

Das Problem ist aber die Vorstellung von Vererbung und Abhänigkeiten.
Wenn ich jetzt eine z.B. Liste von BattlerStatus(Tot, Vergiftet, Schlaf, ...) hab, dann klingt das für mich mehr nach "globalen daten" oder einer Singleton.
Und laut DOD sollte ja jedes Object alle Daten beinhalten die es benötigt.
Sollt jetzt jeder meiner Battler eine Liste von BattleStatuses beinhalten, damit diese genutzt werden kann?
Oder sollte ich die Methoden von den Battler auslagern, z.b. BattlerChara.useDebuff(BattlerChara attacker) // add BattlerStatus.
Muss ich dann nicht immer 2 Klassen erstellen einmal ein Manager und einmal die Data?
Kann ich dann immer noch Methoden auslagern oder muss ich "alles" in einer update Methode machen?


Wie sehr brauch ich so eine EntitySystem oder eine DOD, für meine GameObjects?
Meine Vorstellung ist, OOP in den GameLogicObjects also den ganzen Battler, Monstern, ..... Klassen zu benutzen (vll mit Factory-Pattern).
Und das DOD überlass ich der GamerEngine was nur Physik, Rendern, Input, ... verarbeitet.
Scene und GameObjects sind dann also OOP.




Die meisten Beispiele die ich im Internet finde sind mit Entitys mit position, velocity, lifetime, ...
Das klingt alles mehr nach Engines.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

19.12.2014, 06:44

Wieso genau willst Du überhaupt mit DOD arbeiten? Hast Du massive CPU-lastige Berechnungen mit Massendaten zu tun? Hat sich beim Profiling rausgestellt, dass Dein Spiel mehr Zeit mit dem Update der Spielelemente verbringt als mit rendern? Oder warum genau? Denn wenn nicht, dann klingt aus meiner Sicht Dein vorletzter Absatz sehr sinnvoll. Halte Deine Logik OOP und lass Physik und Rendern den DOD Ansatz verfolgen.
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]

kiba

Alter Hase

  • »kiba« ist der Autor dieses Themas

Beiträge: 327

Wohnort: NRW

Beruf: Azubi: Fach-Info. Anw.

  • Private Nachricht senden

3

19.12.2014, 22:32

Ok, danke Leute.


Ich dachte es könnte vll nur später Probleme geben, wenn ich z.b. mit Tilemaps arbeite und dann so 100 Events und NPCs hab die dann geuppt werden.
Hatte früher so meine Probleme damit.
Aber dazu gibt es glaube gute Frameworks und Libs wie Tiled.

Lares

1x Contest-Sieger

  • Private Nachricht senden

4

20.12.2014, 01:16


Aber dazu gibt es glaube gute Frameworks und Libs wie Tiled.

Moment. Tiled ist ein Editor zur Erstellen einer Mapdatei. Das hat nichts damit zu tun, wie deine Applikation die Datei liest und die Informationen verarbeitet.
Somit hat es keinen Einfluss auf die Performance.

PuppetMaster

Frischling

Beiträge: 20

Beruf: Embedded-System Entwickler (C++)

  • Private Nachricht senden

5

21.12.2014, 11:55


Aber dazu gibt es glaube gute Frameworks und Libs wie Tiled.

Moment. Tiled ist ein Editor zur Erstellen einer Mapdatei. Das hat nichts damit zu tun, wie deine Applikation die Datei liest und die Informationen verarbeitet.
Somit hat es keinen Einfluss auf die Performance.


Es gibt die mit Tiled mitgelieferte libtiled zum lesen der tilemaps:
https://github.com/bjorn/tiled/tree/master/src/libtiled

Allerdings lohnt sich diese library nur wenn es ohnehin schon Qt dependencies im Projekt gibt.



Zu der eigentlichen Frage:

Wenn das Projekt erweiterbar sein soll ist es schwierig auf ein OOP Modell zu setzen, da im laufe der Zeit immer mehr Funktionalität in die Basisklassen wandert.
Spätestens wenn das "Diamond Problem" auftritt sollte man sich nicht wundern wenn ein System nicht mehr wartbar ist.

Tom Davies hat eine recht einfache Übersicht mit Vor- und Nachteilen verschiedener Systeme zusammengestellt (natürlich nicht vollständig):
http://www.tomseysdavies.com/2011/01/23/entity-systems/



MfG
PuppetMaster

Zitat von »"Billy Talent - Fallen Leaves"«

Run away before you drown, or the streets will beat you down.
Fallen leaves, fallen leaves, fallen leaves on the ground.

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »PuppetMaster« (21.12.2014, 12:10)


Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

6

22.12.2014, 17:41

Was ist denn mit einem Komponentengetriebenen Ansatz? Da hast du auch kein Diamond Problem.
„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.“

buggypixels

Treue Seele

Beiträge: 125

Wohnort: Meerbusch

Beruf: Programmierer

  • Private Nachricht senden

7

22.12.2014, 17:56

Die Umstellung auf DOD fällt vielen schwer, weil man immer noch objekt orientiert denkt. Du sprichst ja auch von Battler und Monstern etc.
Solche Objekte gibt es aber nicht in einem DOD Ansatz. Sondern es geht um Daten die transformiert werden. Das ist alles. Diese Daten sollten
dann zusammengefasst werden, damit sie direkt günstig aus dem Cache geladen werden. Wenn man die Artikel von Tom Davies und den anderen
liest, dann sieht man das sehr gut. Ist aber halt eine andere Denkweise.
Ich könnte jetzt hier wieder ein Beispiel mit Position und Velocity etc bringen, aber die scheinen bekannt zu sein.
Leider verstehe ich deine Klassen nicht und die Namen der Methoden sind auch für mich völlig unverständlich. Sonst hätte ich es mal anhand
deiner Klassen versucht.
Übrigens sehe ich keinen Unterschied zwischen Engine Klassen und Game Objekten. Ich verwende den Ansatz in allen Bereichen.

kiba

Alter Hase

  • »kiba« ist der Autor dieses Themas

Beiträge: 327

Wohnort: NRW

Beruf: Azubi: Fach-Info. Anw.

  • Private Nachricht senden

8

23.12.2014, 22:48

Hi danke erst mal für die antworten.

Also das Problem ist wie buggypixels schon gesagt hat das ich sehr OO denke.
Und für mich sind die Objekte die Data, mit weiteren Data (Data in Data) wären das doch auch nur dependencies oder nicht?
Mir ist die Trennung von Data und Algo noch schwer zu begreifen.
Denn wenn ich die Data vom Algo trenne sieht es für mich mehr nach C also nach C++ aus.
Ich weis auch das DOD einfach nur Data in Data transformieren ist, nur kann ich mir schwer vorstellen wie das alles zu trennen ist wenn es z.b. viele Daten sind, hab ich dann eine große Funktionen die alles macht oder auch mehreren subfunktionen?
Wie sieht es aus mit Gettern/Settern, Hilfsmethoden, Methoden die nur bestimmte Daten ändern, das klingt für mich dann so als müsste ich jeder Funktion immer die Data mit übergeben (was in OOP ja einfach nur das this ist).
Was ist mit statischen Daten die z.b. aus einer DB kommen und ein Item, Type von Monster oder anderes Representieren.
Würde ich dafür nicht einfach eine Factory machen wo ich diese statischen Grunddaten übergeben und dann GameObjekt bekomme, klingt für mich sehr nach OOP.
Lassen sich Klassen nicht einfacher erweitern oder ändern, wenn es in DOD keine Vererbung gibt was macht dann die tauschbarkeit und flexibilität aus?

Gibts vll im Internet bessere Beispiele von "OOP zu DOD" damit ich nicht immer in dieser OOP-Welt stecken und auch anderen Ansätze verstehe?

Werbeanzeige