C++ für Spieleprogrammierer

C++ für Spieleprogrammierer

von: Heiko Kalista

Carl Hanser Fachbuchverlag, 2005

ISBN: 9783446400658

Sprache: Deutsch

482 Seiten, Download: 4133 KB

 
Format:  PDF, auch als Online-Lesen

geeignet für: Apple iPad, Android Tablet PC's Online-Lesen PC, MAC, Laptop


 

eBook anfordern

Mehr zum Inhalt

C++ für Spieleprogrammierer



7 Klassen (S. 182-183)

7.1 Was sind Klassen, und wozu dienen sie?
In den vergangenen Kapiteln haben wir die grundlegendsten Eigenschaften und Möglichkeiten von C++ kennen gelernt, die uns eine Art Basis bieten, um einfache Programme schreiben zu können. Tatsächlich kennen wir jetzt die meisten Dinge, die nötig sind, ein Programm zu schreiben. Was bisher allerdings noch fehlt, aber schon häufig angesprochen wurde, ist die so genannte Objektorientierung. Viele der bisherigen Beispiele würden in einem wirklichen Spiel höchstwahrscheinlich anders programmiert, als wir das bisher getan haben. Wir haben zwar darauf geachtet, dass unsere Programme übersichtlich und erweiterbar sind, haben dabei aber noch nicht die Vorzüge der Objektorientierung kennen gelernt, geschweige denn, sie uns zunutze gemacht.

Häufig sieht man zu Beginn nicht die Vorteile, die Klassen bieten, und verzichtet zugunsten der bisher angewandten Techniken darauf, da die Verwendung von Klassen im ersten Augenblick mit etwas mehr Schreibaufwand verbunden sind. Wie sich aber spätestens am Ende dieses Kapitels zeigen wird, ist es tatsächlich nur anfangs etwas mehr Aufwand, aber man spart sich auf längere Sicht eine Menge Arbeit, Zeit und Nerven. Klassen sind, wenn sie richtig verwendet werden, ein wahrer Segen bei der Programmierung. Sie helfen dabei, den Quellcode „logischer" zu gestalten, wenn man ihr Wesen verstanden hat.

Doch was sind denn nun die ominösen Klassen? Was bringen sie, und wie werden sie angewendet? Um das zu klären, geht es jetzt erst mal ein wenig theoretisch weiter. Damit das jedoch nicht in einem staubtrockenen Abschnitt endet, nehmen wir uns als Beispiel die Entwicklung eines Echtzeitstrategiespiels. Dabei handelt es sich um ein Spiel, bei dem man eine Basis aufbauen muss, Ressourcen wie etwa Gold, Holz, Nahrung, Steine oder Ähnliches sammelt, diese verwaltet und schließlich eine Armee aus verschiedenen Einheiten baut, um damit den Gegner anzugreifen. Dies ist ein weit verbreitetes und sehr beliebtes Spielegenre, das auch in der Zeit der 3D-Egoshooter immer noch angesagt ist. Bevor man jetzt mit der Programmierung loslegt, macht man sich ja erst einmal ein paar Gedanken darüber, wie die einzelnen Teile des Spiels aufgebaut und umgesetzt werden. Als Grundlage für eine solche Planung dienen natürlich das bisherige Wissen und die Kenntnisse, die man schon hat. Bei einem solchen Echtzeitstrategiespiel (im Folgenden RTS – Real Time Strategy – genannt) ist einer der wichtigsten Punkte natürlich das Verwalten der Einheiten, die ein Spieler bauen und steuern kann. Es wird schnell klar, dass es bei der Umsetzung mehrere Probleme gibt, die gelöst werden müssen. Beispielsweise ist etwa die Anzahl der Einheiten nicht immer die gleiche, es gibt viele verschiedene Arten von Einheiten (z.B. Infanterie, Kavallerie, Belagerungswaffen oder in futuristischen Spielen Raumschiffe, Raumstationen und so weiter). Es wird schnell deutlich, dass es eine Menge Verwaltungsaufwand zu erledigen gibt. Die unterschiedlichen Einheiten haben unterschiedli che Eigenschaften, agieren anders und ändern, jede für sich, ihre Werte, wenn sie in einen Kampf verwickelt sind. Wird eine Einheit zerstört oder eine neue Einheit in einer Fabrik gebaut, so muss es folglich irgendeine Art Liste geben, in der die aktuellen Einheiten verwaltet werden. Das riecht nicht nur nach einer ganzen Menge Arbeit, sondern es ist tatsächlich eine ganze Menge Aufwand, wenn man dies mit den uns bisher zur Verfügung stehenden Mitteln umzusetzen versucht.

Man könnte sich natürlich nun eine ganze Reihe verschiedener Strukturen anlegen, die jeweils eine bestimmte Einheit beschreiben. Für jeden Einheitentyp legt man sich dann ein Array an, das groß genug ist, um einen ganzen Fuhrpark davon unterzubringen. Damit man jedem Einheitentyp bestimmte Aktionen erlauben kann (etwa schießen, reiten, Steine schleudern usw) schreibt man sich dann entsprechende Funktionen, die sich um das Verhalten der Einheiten kümmern. Wie man allerdings recht schnell erkennt, ist das eine sehr umständliche Lösung. Der Quellcode wird früher oder später extrem unübersichtlich, und jede Änderung am Verhalten von Einheiten und deren Zusammenspiel artet in fast unzumutbarer Arbeit aus. Möchte man dann auch noch einen neuen Einheitentyp hinzufügen, weil man vergessen hat, diesen bei der Planung zu berücksichtigen, so muss man sich um eine Vielzahl von Dingen kümmern: Eine neue Struktur anlegen, ein zusätzliches Array erzeugen und neue Funktionen für diese Einheit schreiben. Dabei macht man sich dann in der Regel die doppelte Arbeit, da man für den neu hinzugekommenen Einheitentyp Funktionen schreiben muss, die es in ähnlicher Art schon für andere Einheitentypen gibt. Beispielsweise können sich ja alle Einheitentypen bewegen. Wie diese das tun, unterscheidet sich nur wenig. Das wird etwa dann deutlich, wenn man zum Beispiel ein Katapult programmiert, das Steine schleudert, und dann eine Abwandlung dieses Einheitentyps hinzufügen möchte, etwa ein Katapult, das brennendes Pech schleudert. Die Funktionen, die nötig sind, um diese Einheitentypen über die Karte bewegen zu lassen, sind aller Wahrscheinlichkeit nach identisch. Der einzige Unterschied liegt in der Art des Angriffs. Man schreibt also eine Funktion doppelt, da man sich ja um zwei unterschiedliche Strukturen kümmern muss.

Man sieht schnell, dass hier eine bessere Lösung her muss. Strukturen zu erstellen und dann Funktionen zu schreiben, die auf diese Strukturen zugeschnitten sind, scheint wirklich nicht das Gelbe vom Ei zu sein. Wäre es nicht besser, wenn wir die Möglichkeit hätten, eine Struktur und die zugehörigen Funktionen irgendwie miteinander zu verbinden, so dass wir uns richtige Objekte erstellen könnten? Es wäre cool, wenn wir eine Art „Objektbeschreibung" deklarieren könnten, die nicht nur Daten (Variablen in einer Struktur), sondern auch gleich die nötigen Funktionen mit sich bringt.

Genau hier kommen die Klassen ins Spiel. Klassen erlauben es uns, zusammengehörige Dinge in Objekte zu fassen und damit logische Verhältnisse zu schaffen. Im richtigen Leben herrscht ja auch dieses Prinzip: ein Hund hat zum Beispiel einige Eigenschaften, wie etwa seinen Namen, sein Alter und sein Gewicht. Außerdem kann ein Hund laufen, bellen und fressen. Dieses Prinzip einer „Objektbeschreibung" wird in C++ durch Klassen realisiert. Eine Klasse kann Daten (also Variablen) und Funktionen zu deren Bearbeitung erhalten.

Kategorien

Service

Info/Kontakt