R: Clone Engine in C++?


2004-03-14 19:42 #1
Erinnert sich noch einer an ZZT oder Megazeux? Während einigen sehr informativen IVS Stunden (Thema: Zahlensystemetired.gif) habe ich mir mal den Megazeux Source gesaugt und ein bisschen drin rumgelesen. Und als ich beim eingebauten Editor angekommen war, schien mir dessen Realisierung sehr interessant. Es sind aber leider viele Dinge mittels Assembler realisiert wurden und da steig ich beim Lesen nicht wirklich durch 😉

Jetzt würden mich mal eure Ideen zu einer Engine, welche auf Klassen basiert, interessieren. Was für Klassen bräuchte man? Welche Art von Skriptsprache für die Objekte? (C like, Assembler like, Ereignis System, Message System, oder wir in Megazeux Sprünge zu Sprungmarken in anderen Objekten, ...)Speicherung eines Spiels für die Engine als Sammlung einzelner Dateien oder als eine einzige Datei (ZIP Archiv, damit andere Spieler/Entwickler auf Grafiken und so Zugriff haben) ...

Vor allem aber der Aufbau der einzelnen Klassen hat sich bei meinem Versuch als etwas schwierig (mangels Vorplanung 😬 😉 erwiesen.

Falls ich mal dazu komme, den Quellcode meines Versuches zu kommentieren, stelle ich ihn mal zur Schau 😉
2004-03-15 00:29 #2
Vielleicht erstmal ein paar puristische Merksätze:
- Ein gutes Klassenkonzept braucht immer Vorplanung und den Mut zur Neuimplementation, wenn man merkt, dass man etwas vergessen hat.
- Der Untergang eines guten Klassenkonzeptes ist Flickschusterei.
- Wenn man Probleme beim Erkennen der Klassenhierarchie hat, ist der Ansatz falsch.

Keine Ahnung, ob man diese Sätze so in Lehrbüchern findet, aber es sind die, welche ich mir immer aufbete, wenn es an die Kreation einer neuen Klassenhierarchie geht.

Allerdings bin ich auch so frei, Klassen nur dort einzusetzen, wo es locker von der Hand geht, sobald etwas mit Klassen mühsam wird, kommen bei mir wieder offene C-Strukturen zum Einsatz.

Aber bei einem Spiel fällt doch eine Klasse sofort in's Gesicht, das Spielobjekt. Es hat gewisse Eigenschaften und man kann etwas damit machen. Was man damit machen kann, sind bei C++ die Methoden, wie z.B. Aufnehmen, Ablegen, Benutzen oder Darstellen. Sicher ist es auch keine schlechte Idee, Methoden zur Serialisierung mit aufzunehmen, damit man das Objekt auch speichern kann. Angereichert mit ein paar globaleren Dingen wie Szene initialisieren und Szene verlassen ist diese Klasse schonmal fertig.

Aber so einfach sich das auch anhört, der Teufel steckt natürlich im Detail. Wie verwaltet man denn solche Objekte? Nur ein Array davon hilft nicht weiter, wenn man z.B. etwas auf einem Sand-Objekt ablegen möchte. Ausserdem sollte das Objekt unterscheiden können, ob der Held oder jemand anderes drüberläuft.

Apropos Laufen. Es ist sicher eine gute Idee, bewegende und nicht-bewegende Objekte unterschiedlich zu implementieren, da diese nur wenig gemeinsame Eigenschaften aufweisen werden, vielleicht mit Ausnahme der Anzeige und der Serialisierung. Vielleicht gibt's auch eine gemeinsame Basis-Klasse, welche diese beiden Dinge implementiert.

Du solltest Dir vor allem auch einmal Gedanken über die Speicherverwaltung machen. Tonnenweise new und delete Operatoren sorgen in den üblichen Applikationen für die meisten Probleme. Ich persönlich vermeide dynamische Speicherobjekte, wenn ich sie nicht unbedingt brauche.

Daher ist bei Robot die Interpretation der Klassen auch eine ganz andere, als man es erwarten würde. Sicher, es gibt eine Objekt-Klasse die der oben beschriebenen stark ähnelt. Jedes Objekt in Robot ist eine Spezialisierung dieser Basisklasse.
Allerdings werden von diesen Klassen keine dynamischen Instanzen erzeugt, vielmehr existiert von jeder Objektklasse genau eine Instanz, welche während der Programminitialisierung erzeugt wird.

Das eigentliche "Objekt" im Spiel, ist letztendlich nur noch ein 16-Bit-Wert, der in den unteren 8 Bit den Objekt-Typ definiert und die oberen 8 Bit für Attribute zur Verfügung stellt. Diese oberen 8 Bit definieren z.B. wie ein Tangram-Teil aussieht, ob ein Waldstück begehbar ist oder wieviele Streichhölzer noch in der Packung sind.

Die Objekte sind dann stur in einem 2D-Array abgelegt, welches so die eigentliche Szene definiert. Wenn irgendwo etwas hingelegt wird, setze ich im Array einfach nur den Wert hinein, nehme ich etwas weg, setze ich den Wert auf 0. Ohne jegliche Allokation.

Wenn ich mit einem Objekt etwas anfangen möchte, rufe ich die jeweilige Methode der Objekt-Instanz auf, die Zuordnung erfolgt dabei über ein (ebenfalls statisches) Array von Zeigern auf die Objekt-Instanzen mit den unteren 8Bit meines Objekt-Wertes als Index.

Probleme mit dem Speichern oder Duplizieren habe ich dadurch auch nicht, einfach das Array wegkopieren oder eben den Wert zusätzlich woanders hinspeichern.

Wie gesagt: Wenn bei der Realisierung etwas Kopfschmerzen bereitet, sollte man es anders lösen. Meist gibt es eine Variante, bei der sich alle Probleme in Luft auflösen.

Ich hoffe dass das etwas weiter hilft... 😉

waiting www.tom-productions.de - www.tofahrn-foto.de - www.tofahrn.de

2004-03-15 00:30 #3
R=Restore (Wiederherstellung)
Durch einen präzisen Angriff auf ezBoard sind sämtliche Beiträge der Foren verloren gegangen. Durch Restore-Prozesse seitens ezBoards konnte leider nur ein winziger Teil aller Beiträge gerettet werden. Das Robot-Forum hatte es auch schwer getroffen. Durch Google-Caches und Web.Archive.org konnten viele Beiträge wieder gefunden werden. Diese hier gehören dazu. Die Diskussion kann weitergeführt werden.