BlackBoard » Design, Programmierung & Entwicklung » Programmieren » [Architektur] Circular Dependency in einem klassischen 2D-Spiel » Hallo Gast [Anmelden|Registrieren]
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | An Freund senden | Thema zu Favoriten hinzufügen
Neues Thema erstellen Antwort erstellen
Zum Ende der Seite springen [Architektur] Circular Dependency in einem klassischen 2D-Spiel
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
Zirias Zirias ist männlich
BlackBoarder


images/avatars/avatar-450.jpg

Dabei seit: 11.09.2002
Beiträge: 1.217
Herkunft: /dev/urandom

[Architektur] Circular Dependency in einem klassischen 2D-Spiel       Zum Anfang der Seite springen

Vorgeschichte: Nach einem Hinweis von phlox81 auf ein Anti-Pattern, alles von einer einzigen Basisklasse abzuleiten, hab ich gesucht, ob das tatsächlich eines ist, und, mit welcher Begründung (schließlich machen das viele OOP-Umgebungen ganz implizit so) ... habe auch nichts gefunden. Allerdings fallen einem bei einer solchen Recherche durchaus Dinge auf, von denen man weiß, dass sie nicht toll sind, die man aber trotzdem bis dahin nicht "gewürdigt" hat:

Ich hab eine Circular Dependency. Und zwar gibt es ein Spielfeld (Board), das hat ein zweidimensionales Array (2D-Spiel *g*) von Entities, die sich auf diesem Feld befinden. Jedes Entity weiß aber auch, auf welchem Board (gibt natürlich nur eines) an welcher Stelle es steht. Das Board erzeugt die Entities anhand der Daten eines Levels.

Wenn jetzt ein Entity bewegt werden soll, überprüft es die Gültigkeit der Bewegung, indem es vom Board Nachbar-Entities abfragt. Wenn alles passt, wird ein "Move" erzeugt und an das Board zur Ausführung übergeben. Das Board führt die Bewegung animiert aus und aktualisiert am Ende die Positionsdaten und schickt ein Ereignis, dass die Bewegung abgeschlossen ist.

Also: Board greift auf Entity zu UND Entity greift auf Board zu.

Frage: Gewinne ich an der Stelle wirklich etwas, wenn ich versuche, das aufzulösen? z.B. könnte sich ein Entity selbst seine benötigten Nachbarn merken und vom Board aktualisieren lassen, dann wäre es nicht mehr nötig, dass das Entity auf das Board zugreift. Das erscheint mir aber irgendwie umständlich...

__________________
palmen-it.de
GCS/MU d+(++) s+: a C++ UL++++ P+++$ L+++ !E W+++ N+ o? K? w++$ !O M-- V?
PS+ PE++ Y+ PGP++ t !5 X- R- tv b+ DI++ D+ G e++ h r y+
25.05.2010 20:14 Zirias ist offline Homepage von Zirias Beiträge von Zirias suchen
Misel Misel ist männlich
Hüter des Kitkat


images/avatars/avatar-2084.png

Dabei seit: 02.11.2002
Beiträge: 1.203
Herkunft: live://home.berlin.d e

      Zum Anfang der Seite springen

Also so spontan aus dem Bauch heraus:

Das größte Problem werden rekursive Aufrufe sein. Besonders wenn ein Board eine Entity manipulieren kann und eine Entity auch ein Board manipulieren kann, läufst Du Gefahr, dass die sich gegenseitig ändern ohne, dass Du aus der Schleife rauskommst.

Ansonsten, wenn's funktioniert, lass es so smile

__________________
LAUFT! Ich spiele KILLERSPIELE!
25.05.2010 20:43 Misel ist offline E-Mail an Misel senden Homepage von Misel Beiträge von Misel suchen
phlox81 phlox81 ist männlich
Bote des Lichts und Moderator


images/avatars/avatar-2264.jpg

Dabei seit: 19.10.2002
Beiträge: 3.028
Herkunft: Irgendwo im Nirgendwo

      Zum Anfang der Seite springen

Also zumindest im C/C++ Bereich halte ich es für ein Antipattern, was leider in vielen der Frameworks begangen wurde (wxWidgets, Qt z.b.). Es führt zu unnötigen Abhängigkeiten, und bläht den Code unnötig auf.

Bei dir mag dies bedingt sinnvoll sein, da du ja in C gewisse Sachen über diese Struktur simulieren/realisieren musst, welche in eine OOP Sprache schon vorhanden sind.

Zu deinem Problem:

Sowas würde man in C++ mit einer Forward Deklaration lösen.
Ich weiss nicht ob das in C möglich ist.

Erstmal würde ich die Beziehung hinterfragen, zwischen Spielfigur und Board.
Eigentlich müsste es eine 3. Klasse Engine geben, welche die Spielzüge durchführt bzw. anstösst. Die Animation wäre dann in Board, oder in einer Klasse dafür. Engine sollte dann die Spielzüge ausführen, und die Spielfigur Klasse hätte nur den Logikcode den die Figur selber betrifft.

Auch würde ich das Spielfeld intern als 2D Int array abbilden. Notfalls könntest du hier auch eine Struktur aus Spielfigur ID und Pointer wählen.
So sparst du dir hunderte Stein Instanzen, die letztendlich alle das selbe nur tun. Oder instanzierst diese erst, wenn du sie benötigst.
Dem Spielfeld wiederum ist es egal, da es nur anhand der ID das korrekte Sprite darstellt.

phlox

__________________
Intelligenz ist eine Illusion des Menschen

phlox81.de | codenode.de
25.05.2010 21:09 phlox81 ist offline E-Mail an phlox81 senden Homepage von phlox81 Beiträge von phlox81 suchen
Zirias Zirias ist männlich
BlackBoarder


images/avatars/avatar-450.jpg

Dabei seit: 11.09.2002
Beiträge: 1.217
Herkunft: /dev/urandom

Themenstarter Thema begonnen von Zirias
      Zum Anfang der Seite springen

Zitat:
Original von phlox81
Also zumindest im C/C++ Bereich halte ich es für ein Antipattern, was leider in vielen der Frameworks begangen wurde (wxWidgets, Qt z.b.). Es führt zu unnötigen Abhängigkeiten, und bläht den Code unnötig auf.

Bei dir mag dies bedingt sinnvoll sein, da du ja in C gewisse Sachen über diese Struktur simulieren/realisieren musst, welche in eine OOP Sprache schon vorhanden sind.


Ich seh das so: ENTWEDER die Sprache kennt das Konzept "Object" und liefert alle nötigen Fähigkeiten, wie z.B. zur Laufzeit die Klasse zu bestimmen -- ODER ein Basisobjekt tut das. Beides gleichzeitig ist natürlich Unsinn. Aber die Lösung mit einem expliziten Basis-Objekt finde ich eigentlich ganz angenehm, so kann ich in C# zum Beispiel "foo.GetType()" schreiben smile

Zitat:
Sowas würde man in C++ mit einer Forward Deklaration lösen.
Ich weiss nicht ob das in C möglich ist.

Ähm? Klar kann ich in C forward declarations schreiben, MUSS ich sogar, sonst wäre die circular dependency gar nicht implementiertbar Augenzwinkern Aber auflösen kann ich sie damit nicht.

Zitat:
Erstmal würde ich die Beziehung hinterfragen, zwischen Spielfigur und Board.
Eigentlich müsste es eine 3. Klasse Engine geben, welche die Spielzüge durchführt bzw. anstösst. Die Animation wäre dann in Board, oder in einer Klasse dafür. Engine sollte dann die Spielzüge ausführen, und die Spielfigur Klasse hätte nur den Logikcode den die Figur selber betrifft.


Engine "rauszuziehen" klingt direkt mal sehr sinnvoll. Wird allerdings nicht so einfach sein. Und figurspezifisched Logik ist ja trotz allem von der Umgebung abhängig, die dann wiederum nur der Engine bekannt ist -- könnte man sich höchstens überlegen, GANZ auf die separaten Klassen für die Entities zu verzichten ... hmm ...

Zitat:
Auch würde ich das Spielfeld intern als 2D Int array abbilden.

Das tut zur Zeit das Level. Das Board liest das aus und instanziiert die tatsächlichen Objekte. Vielleicht wirklich unnötiger Overhead, muss ich nochmal drüber nachdenken. Praktisch ist es bisher für die fallenden Felsen, wenn die ihr Ereignis für eine abgeschlossene Bewegung bekommen prüfen sie direkt, ob sie weiterfallen bzw abrollen sollten, und fordern dann eine neue Bewegung an smile Alle anderen Entities (bis auf "Willy", die eigentliche Spielfigur) tragen aber in der Tat nichts zur Logik bei...

edit:

Danke auch Misel für die Warnung ... habe kurz drüber nachgedacht, und DAS kann zur Zeit zum Glück nicht passieren, da kein Entity jemals "mutators" des Board aufruft. Das Board kann Zustand des Entity ändern, aber nicht umgekehrt. Sollte ich vielleicht dokumentieren, falls ich bei dem aktuellen Modell bleibe, denn andernfalls könnte das tatsächlich zum Problem werden smile

__________________
palmen-it.de
GCS/MU d+(++) s+: a C++ UL++++ P+++$ L+++ !E W+++ N+ o? K? w++$ !O M-- V?
PS+ PE++ Y+ PGP++ t !5 X- R- tv b+ DI++ D+ G e++ h r y+

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Zirias: 25.05.2010 21:30.

25.05.2010 21:26 Zirias ist offline Homepage von Zirias Beiträge von Zirias suchen
Baumstruktur | Brettstruktur
Gehe zu:
Neues Thema erstellen Antwort erstellen
BlackBoard » Design, Programmierung & Entwicklung » Programmieren » [Architektur] Circular Dependency in einem klassischen 2D-Spiel

Forensoftware: Burning Board 2.3.6, entwickelt von WoltLab GmbH