Ich bin gerade dabei, ein 2D-Sprite-basiertes Spiel für Windows 7 Phone mit XNA zu entwickeln. Die dafür verfügbaren Schulungen und Tutorials sind ziemlich hilfreich, aber das Problem, dem ich gegenüberstehe, ist, dass jeder von ihnen anders an sein Klassendesign herangeht und der Code nicht besonders gut faktorisiert ist. Infolgedessen war es für mich schwierig, genau zu verstehen, welche Aufgaben ich einer bestimmten Klasse übertragen sollte.
Zum Beispiel könnte ich eine Basis-Sprite-Klasse haben BaseSprite
, die weiß, wie sie sich selbst zeichnet, auf Kollisionen prüft usw. Dann könnte ich eine AnimatedSprite
Klasse haben, die weiß, wie sie in ihrem Sprite-Sheet, einer ExplodingSprite
Klasse usw. navigiert . Diese Technik wird im Space Invaders-Beispiel in den Materialien zu Windows 7 Phone Jumpstart Session 2 demonstriert .
Alternativ könnte ich stattdessen den Großteil des Renderns und Ausführens der Spielverantwortung in eine GameScreen
Klasse einordnen. Diese Klasse und ihre abgeleiteten Klassen verhalten sich in Bezug auf ihre Zuständigkeiten eher wie Formulare oder Webseiten. Sprite-Klassen sind einfachere Container mit viel weniger Logik.
Dies ist die Technik, die im Alien Sprite-Spiel des Windows 7 Phone Training Kits und in anderen Beispielen für den Spielstatus-Manager verwendet wird.
Was ist der richtige objektorientierte Ansatz für das Klassendesign in der Spieleentwicklung?
In Spielen ist das Komponentenmuster eine gängige Lösung.
quelle
Die SOLID-Prinzipien gelten für das Design von Spielecodes genauso wie für jeden anderen Beruf - zumindest bis zur Optimierung. Daher würde ich Ihr erstes Beispiel als Ausgangspunkt nehmen.
Ich würde jedoch noch weiter gehen, da BaseSprite so klingt, als würde es zu einer Megaklasse werden. Das Prinzip der Einzelverantwortung schreibt vor, dass Kollision, Rendering und Navigation von Komponenten und nicht von einzelnen Einträgen in einer Klassenhierarchie behandelt werden sollen. Die Halteklasse all dieser Komponenten sollte nur mit dem Verschieben von Weltpositionen zwischen ihnen umgehen.
quelle
Bei den letzten Projekten habe ich mich mehr auf einen MVC-Ansatz konzentriert.
Zuerst waren wir uns nicht sicher, ob das funktionieren würde, aber es hat perfekt funktioniert.
Modell
Die Datenobjekte. Nur die reinen Daten. Kein Verhalten, kein Rendern.
Datenmanager. Nur mit "Listen" von Datenobjekten umgehen. (Kann auch erweitert werden, um das Pooling zu unterstützen.)
Aussicht
Wir nennen sie Renderer. Für jeden Datenobjekttyp gibt es einen Renderer. Wenn es mit einem Manager aufgerufen wird, werden alle Objekte in dieser Liste gerendert.
Regler
Entspricht den Renderern, steuert jedoch das Verhalten.
Beispiel
Der ShipManager verfügt über eine Liste von Schiffen. Der ShipController verschiebt die Schiffe entsprechend ihrem Status. Der ShipRenderer rendert die Schiffe entsprechend ihrem Status.
Warum
Auf diese Weise sind Sicht und Logik streng voneinander getrennt. Es macht das Portieren auf eine neue Plattform ziemlich einfach. Die Optimierung des Datenlayouts im XxxManager ist ebenfalls sehr einfach.
quelle