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

XelVair

Frischling

  • »XelVair« ist der Autor dieses Themas

Beiträge: 46

Beruf: Student

  • Private Nachricht senden

1

12.10.2011, 19:22

OOP und die Struktur eines Spiels

'Nabend SpPro.de :)

Eine Frage die sich bei mir vor kurzem aufgetan hat, die ich jedoch auch über das lesen diverser Quellcodes und Forenbeiträge nicht ganz beantworten konnte möchte ich gerne ein wenig ausdiskutieren.

Es geht um die Architektur/Struktur von Spielen, die sehr viel wert auf OOP legen. Mein Problem ist meistens, dass ich eine Game-Klasse habe, die Z.b. einen EnemyManager und einen PlayerManager beinhaltet.
Jetzt muss aber der PlayerManager doch z.B. die kollision mit dem EnemyManager abstimmen, jedoch weiß der PlayerManager nichts vom EnemyManager.

Bisher habe ich dieses Problem immer folgendermaßen gelöst:

Die Klasse PlayerManager besitzt einen Pointer vom Typ EnemyManager. Die Init-Funktion von PlayerManager hat als Argument mitunter eine &EnemyManager, auf die dann der Pointer gerichtet wird. Das klappt soweit recht gut, nur kommt mir das ganze recht wenig OOP-like vor, mal ganz zu schweigen von der modularität des ganzen.

Jetzt meine Frage an euch: Wenn Ihr ein Spiel programmiert, wie baut ihr ungefähr die Klassenhierarchie auf bzw. wie stellt ihr es an, dass bestimmte Klassen alle nötigen informationen bekommen, ohne Globale Variablen zu implementieren?

Ich hoffe,dass meine Frage verständlich ist ;)

~Xelvair
Ich bin eine Siegnatur, ihr kriegt mich nicht unter!

2

12.10.2011, 19:48

Zeiger, normale Klasseninstanzen oder eben Parameter.

MfG
Check

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

3

12.10.2011, 19:57

Naja globale Variablen zu verhindern ist eigentlich gar nicht so schwer. Die werden meistens ja nur aus Faulheit benutzt. Wenn man sein Konzept etwas mehr überarbeitet, dann kommt man schnell auf Ideen, seine Objekte an die Stellen weiter zu reichen, an denen sie gebraucht werden. Dann sagst du, dass Spiele sehr viel Wert auf OOP legen. Da kann ich nur bedingt zustimmen. Die Sache ist die, dass OOP sehr stark verbreitet ist. Es gibt aber genügend andere Ansätze, mit denen man Spiele entwickeln kann. Niemand schreibt mir vor ein Spiel OO zu programmieren. Ich möchte jetzt hier keine Diskussion zum dem Thema losbrechen. Nur darauf hinweisen, dass es auch andere Möglichkeiten gibt. Es spricht erstmal nichts dagegen ein Pong in Haskell zu schreiben oder? (außer einer völlig natürlichen und verständlichen Abneigung funktionaler Sprachen gegenüber;) ).

So und nun zum eigentlichen Thema;) Ich spiele immer sehr viel mit meinem Klassendesign herum. Bei dem einen Projekt lös ich noch alles auf die eine Weise und beim nächsten Projekt habe ich wieder andere Flausen im Kopf. Ich denke die wenigsten sind nach einem Projekt 100% mit ihrem Design zufrieden;)
Aber in etwa habe ich bei jedem Spiel eine Spielzustandsverwaltung in Form von GameStates. Diese implementieren das State-Pattern. Wenn es gewünscht ist, trenne ich die Darstellung auf dem Bildschirm manchmal von der Logik. So kann ich die aktuelle View austauschen, um zum Beispiel die Sicht eines anderen Spielers zu bekommen, oder etwas ganz anderes. Ein Pausescreen wäre dann zum Beispiel auch so eine View. Gleiches gilt zum Teil für die Steuerung/Eingabe. Diese ist teilweise mit in der View, teilweise aber auch in einer eigenständigen Klasse. Je nachdem ob ich die Steuerung unabhängig von der Sicht austauschen können möchte oder nicht. Das wird aber alles je nach Anforderung umgesetzt. Wenn ich keine austauschbare Sicht/Eingabe brauche, ist das alles überflüssig. Meine Welt wird normalerweise auch durch eine extra Klasse dargestellt. Normalerweise werden alle Spielobjekte hier gehalten. Die Welt dient mir quasi wie eine Art Container der Models mit zusätzlichen Funktionen. Spielobjekte werden meistens zusammengefasst. Meistens habe ich eine Parentklasse für alle Renderbaren Objekte und kann diese dann hinterher so zusammenfassen. Das kommt dann aber auch immer stark auf das Projekt an.
Naja so zieht sich das jetzt alles weiter. Ich glaube aber fast dass du darauf nicht hinaus wolltest. Gibt es bestimmte Punkte die dich interessieren?



edit:
Habe noch mal gecheckt. Dir ging es in dem anderen Beitrag ja zum Beispiel um die Getter.
Du solltest normalerweise deine Klasse so aufbauen, dass nichts nach außen geht, was keinen Sinn macht. Vor allem Implementierungsdetails sollten am besten gekapselt werden. Dass heisst, dass der Benutzer nicht sieht was intern abläuft und die Klasse einfach nur benutzen muss. Dadurch schiebst du das Problem auf eine neue Ebene. Die Klasse soll dir ja helfen dass Problem zu lösen. Dann sollte der Benutzer nicht über die gleichen Dinge nachdenken müssen, als wenn er ohne die Klasse arbeiten würde. Wenn du zum Beispiel einen EnemyManager implementiert. Dann sollte den Benutzer nicht interessieren ob dieser intern nun eine Liste, ein Array oder ein Dictionary für die einzelnen Instanzen hält. Der Manager ist ja dafür da, diese Logik zu kapseln und auf ein neues Niveau zu bringen. Deswegen wird dein Manager vermutlich auch keine Methode GetEnemyList() oä bereitstellen. Wenn dein Player jetzt deinen EnemyManager kennen muss, ist das ja erst mal kein Problem. Es spricht ja nichts dagegen. Jetzt müsste man das natürlich etwas genauer betrachten und vielleicht auch Code sehen um zu entscheiden wie sehr dass nun OOP-Richtlinien entspricht. Aber wenn du gut damit fährst, dann behalte es vielleicht erst mal so bei.
„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.“

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Schorsch« (12.10.2011, 20:03)


Rushh0ur

Frischling

Beiträge: 67

Beruf: Student Elektrotechnik

  • Private Nachricht senden

4

12.10.2011, 19:57

Des weiteren evtl. durch Deklaration von friend classen und oder singleton-Klassen, durch letzteres kann man indirekt eine globale Variable definieren und durch Kombination von beiden kann man den zugriff Steuern. (C++)

Mfg Rushh0ur

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

5

12.10.2011, 20:04

Singleton ist nicht als Ersatz für globals gedacht;) Deswegen haben Singletons auch so einen schlechten Ruf.
„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.“

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

6

12.10.2011, 20:37

Das einzige was Singleton und globale Variablen gemeinsam gemeinsam haben ist, dass beide in einem guten Design pratkisch nie vorkommen ;)

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

7

12.10.2011, 21:21

Naja es gibt seien Daseinsberechtigung aber das wurde ja hier im Forum schon oft genug diskutiert;)
„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.“

8

12.10.2011, 21:24

Jedem seines, solange man eben klarkommt.

MfG
Check

XelVair

Frischling

  • »XelVair« ist der Autor dieses Themas

Beiträge: 46

Beruf: Student

  • Private Nachricht senden

9

12.10.2011, 22:06

Vielen Dank an alle Posts und Vorschläge (vorallem an Schorsch ;)), mir ist klar geworden, dass es kein "Perfektes" Design gibt, und jeder seinen eigenen Weg finden sollte.

Trotzdem würde ich es mich interessieren, wie manche von euch an bestimmte dinge heran gehen.
Angenommen ihr habt einen PlayerManager und einen EnemyManager, dann vllt noch einen ProjectileManager. Wie lässt sich das mit der kollision am besten lösen? Mit einer neuen Klasse die Referenuzen auf PlayerManager, EnemyManager und ProjectileManager bekommt, und dann denen jeweils events zuschiebt? Vllt. kann ja jemand von einer Struktur erzählen, die er bei einem Spiel angewand hat, und glücklich damit ist ;)

Danke im Voraus,

Xelvair
Ich bin eine Siegnatur, ihr kriegt mich nicht unter!

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

10

12.10.2011, 22:14

Ich würde mir mal überlegen, wofür ich diese ganzen Manager brauche. Wenn ich Kollisionen zwischen all diesen Objekten testen will, dann muss ich sie dazu erstmal überhaupt alle kennen. Wirf vielleicht auch einen Blick auf den Double Dispatch Pattern.

Werbeanzeige