Design Patterns für die Spieleprogrammierung (eBook)
400 Seiten
MITP Verlags GmbH & Co. KG
978-3-95845-091-2 (ISBN)
Robert Nystrom arbeitet seit acht Jahren bei Electronic Arts, der weltweit führenden Firma auf dem Gebiet der digitalen interaktiven Unterhaltung. Das Unternehmen ist bekannt für Blockbuster-Marken wie Die Sims, Madden NFL, Battlefield und Dragon Age.
Robert Nystrom arbeitet seit acht Jahren bei Electronic Arts, der weltweit führenden Firma auf dem Gebiet der digitalen interaktiven Unterhaltung. Das Unternehmen ist bekannt für Blockbuster-Marken wie Die Sims, Madden NFL, Battlefield und Dragon Age.
Cover 1
Titel 3
Impressum 4
Inhaltsverzeichnis 7
Danksagungen 17
Teil I: Einführung 19
Kapitel 1: Architektur, Performance und Spiele 27
1.1 Was ist Softwarearchitektur? 27
1.1.1 Was zeichnet eine gute Softwarearchitektur aus? 28
1.1.2 Wie nimmt man Änderungen vor? 28
1.1.3 Inwiefern hilft eine Entkopplung? 30
1.2 Zu welchem Preis? 30
1.3 Performance und Geschwindigkeit 32
1.4 Das Gute an schlechtem Code 33
1.5 Ein ausgewogenes Verhältnis finden 34
1.6 Einfachheit 35
1.7 Fang endlich an! 37
Teil II: Design Patternsneu überdacht 39
Kapitel 2: Command (Befehl) 41
2.1 Eingabekonfiguration 42
2.2 Regieanweisungen 45
2.3 Rückgängig und Wiederholen 47
2.4 Klassen ohne Funktionen? 51
2.5 Siehe auch ... 53
Kapitel 3: Flyweight (Fliegengewicht) 55
3.1 Den Wald vor lauter Bäumen nicht sehen 55
3.2 Tausend Instanzen 58
3.3 Das Flyweight-Pattern 58
3.4 Ein Ort, um Wurzeln zu schlagen 59
3.5 Und die Performance? 64
3.6 Siehe auch ... 65
Kapitel 4: Observer (Beobachter) 67
4.1 Erzielte Leistungen 67
4.2 Funktionsweise 69
4.2.1 Der Observer 69
4.2.2 Das Subjekt 70
4.2.3 Beobachtung der Physik-Engine 72
4.3 »Das ist zu langsam!« 73
4.3.1 Oder ist es doch zu schnell? 74
4.4 »Zu viele dynamische Allokationen« 74
4.4.1 Verkettete Observer 75
4.4.2 Ein Pool von Listenknoten 79
4.5 Verbleibende Schwierigkeiten 79
4.5.1 Subjekte und Observer löschen 80
4.5.2 Keine Sorge, der Garbage Collector erledigt das schon 81
4.5.3 Was geht hier vor? 82
4.6 Heutige Observer 83
4.7 Zukünftige Observer 84
Kapitel 5: Prototype (Prototyp) 87
5.1 Das Design Pattern Prototype 87
5.1.1 Wie gut funktioniert es? 91
5.1.2 Spawn-Funktionen 91
5.1.3 Templates 92
5.1.4 First-Class-Typen 93
5.2 Eine auf Prototypen beruhende Sprache 93
5.2.1 Self 93
5.2.2 Wie ist es gelaufen? 96
5.2.3 Was ist mit JavaScript? 97
5.3 Prototypen zur Datenmodellierung 99
Kapitel 6: Singleton 103
6.1 Das Singleton-Pattern 103
6.1.1 Beschränkung einer Klasse auf eine Instanz 103
6.1.2 Bereitstellung eines globalen Zugriffspunkts 104
6.2 Gründe für die Verwendung 105
6.3 Gründe, die Verwendung zu bereuen 107
6.3.1 Singletons sind globale Variablen 108
6.3.2 Das Pattern löst zwei Probleme, selbst wenn es nur eins gibt 109
6.3.3 Die späte Initialisierung entzieht Ihnen die Kontrolle 110
6.4 Verzicht auf Singletons 112
6.4.1 Wird die Klasse überhaupt benötigt? 112
6.4.2 Nur eine Instanz einer Klasse 114
6.4.3 Bequemer Zugriff auf eine Instanz 115
6.5 Was bleibt dem Singleton? 118
Kapitel 7: State (Zustand) 119
7.1 Altbekanntes 119
7.2 Zustandsautomaten erledigen das 123
7.3 Enumerationen und Switch-Anweisungen 124
7.4 Das State-Pattern 127
7.4.1 Das Interface für den Zustand 128
7.4.2 Klassen für alle Zustände 128
7.4.3 An den Zustand delegieren 129
7.5 Wo sind die Zustandsobjekte? 130
7.5.1 Statische Zustände 130
7.5.2 Instanziierte Zustandsobjekte 131
7.6 Eintritts- und Austrittsaktionen 132
7.7 Wo ist der Haken? 134
7.8 Nebenläufige Zustandsautomaten 134
7.9 Hierarchische Zustandsautomaten 136
7.10 Kellerautomaten 138
7.11 Wie nützlich sind sie? 139
Teil III: Sequenzierungsmuster (Sequencing Patterns) 141
Kapitel 8: Double Buffer (Doppelter Buffer) 143
8.1 Motivation 143
8.1.1 Computergrafik kurz und bündig 143
8.1.2 Erster Akt, erste Szene 145
8.1.3 Zurück zur Grafik 146
8.2 Das Pattern 146
8.3 Anwendbarkeit 147
8.4 Konsequenzen 147
8.4.1 Der Austausch selbst kostet Zeit 147
8.4.2 Zwei Framebuffer belegen mehr Arbeitsspeicher 147
8.5 Beispielcode 148
8.5.1 Nicht nur Grafik 151
8.5.2 Künstliche Unintelligenz 151
8.5.3 Gebufferte Ohrfeigen 155
8.6 Designentscheidungen 156
8.6.1 Wie werden die Buffer ausgetauscht? 157
8.6.2 Wie fein ist der Buffer untergliedert? 158
8.7 Siehe auch ... 159
Kapitel 9: Game Loop (Hauptschleife) 161
9.1 Motivation 161
9.1.1 Interview mit einer CPU 161
9.1.2 Ereignisschleifen 162
9.1.3 Eine aus dem Takt geratene Welt 163
9.1.4 Sekunden pro Sekunde 164
9.2 Das Pattern 164
9.3 Anwendbarkeit 164
9.4 Konsequenzen 165
9.4.1 Abstimmung mit der Ereignisschleife des Betriebssystems 165
9.5 Beispielcode 166
9.5.1 Die Beine in die Hand nehmen 166
9.5.2 Ein kleines Nickerchen 166
9.5.3 Ein kleiner und ein großer Schritt 167
9.5.4 Aufholjagd 169
9.5.5 In der Mitte hängen geblieben 171
9.6 Designentscheidungen 173
9.6.1 Stammt die Game Loop aus Ihrer Feder oder benutzen Sie die der Plattform? 173
9.6.2 Wie handhaben Sie die Leistungsaufnahme? 174
9.6.3 Wie steuern Sie die Spielgeschwindigkeit? 175
9.7 Siehe auch ... 176
Kapitel 10: Update Method (Aktualisierungsmethode) 177
10.1 Motivation 177
10.2 Das Pattern 180
10.3 Anwendbarkeit 180
10.4 Konsequenzen 181
10.4.1 Verkomplizierung durch Aufteilen des Codes in einzelne Frames 181
10.4.2 Der Zustand muss gespeichert werden, um im nächsten Frame fortfahren zu können 181
10.4.3 Alle Objekte simulieren jeden Frame, aber nicht wirklich exakt gleichzeitig 182
10.4.4 Obacht bei der Modifizierung der Objektliste während der Aktualisierung 182
10.5 Beispielcode 184
10.5.1 Entity-Unterklassen? 186
10.5.2 Entities definieren 186
10.5.3 Zeitablauf 189
10.6 Designentscheidungen 190
10.6.1 Zu welcher Klasse gehört die update()-Methode? 190
10.6.2 Wie werden inaktive Objekte gehandhabt? 191
10.7 Siehe auch ... 192
Teil IV: Verhaltensmuster (Behavioral Patterns) 193
Kapitel 11: Bytecode 195
11.1 Motivation 195
11.1.1 Wettkampf der Zaubersprüche 196
11.1.2 Daten > Code
11.1.3 Das Interpreter-Pattern 196
11.1.4 Faktisch Maschinencode 200
11.2 Das Pattern 201
11.3 Anwendbarkeit 201
11.4 Konsequenzen 201
11.4.1 Befehlsformat 202
11.4.2 Fehlender Debugger 203
11.5 Beispielcode 203
11.5.1 Eine zauberhafte API 203
11.5.2 Ein bezaubernder Befehlssatz 204
11.5.3 Eine Stackmaschine 206
11.5.4 Verhalten = Komposition 209
11.5.5 Eine virtuelle Maschine 212
11.5.6 Hexerwerkzeuge 213
11.6 Designentscheidungen 215
11.6.1 Wie greifen Befehle auf den Stack zu? 215
11.6.2 Welche Befehle gibt es? 216
11.6.3 Wie werden Werte repräsentiert? 217
11.6.4 Wie wird der Bytecode erzeugt? 220
11.7 Siehe auch ... 222
Kapitel 12: Subclass Sandbox (Unterklassen-Sandbox) 223
12.1 Motivation 223
12.2 Das Pattern 225
12.3 Anwendbarkeit 226
12.4 Konsequenzen 226
12.5 Beispielcode 226
12.6 Designentscheidungen 229
12.6.1 Welche Operationen sollen bereitgestellt werden? 229
12.6.2 Sollen Methoden direkt oder durch Objekte, die sie enthalten, bereitgestellt werden? 231
12.6.3 Wie gelangt die Basisklasse an die benötigten Zustände? 232
12.7 Siehe auch ... 236
Kapitel 13: Type Object (Typ-Objekt) 237
13.1 Motivation 237
13.1.1 Die typische OOP-Lösung 237
13.1.2 Eine Klasse für eine Klasse 239
13.2 Das Pattern 241
13.3 Anwendbarkeit 241
13.4 Konsequenzen 242
13.4.1 Typ-Objekte müssen manuell gehandhabt werden 242
13.4.2 Die Definition des Verhaltens der verschiedenen Typen ist schwieriger 242
13.5 Beispielcode 243
13.5.1 Typartiges Verhalten von Typ-Objekten: Konstruktoren 245
13.5.2 Gemeinsame Nutzung von Daten durch Vererbung 246
13.6 Designentscheidungen 250
13.6.1 Ist das Typ-Objekt gekapselt oder zugänglich? 250
13.6.2 Wie werden Typ-Objekte erzeugt? 251
13.6.3 Kann sich der Typ ändern? 252
13.6.4 Welche Formen der Vererbung werden unterstützt? 253
13.7 Siehe auch ... 254
Teil V: Entkopplungsmuster (Decoupling Patterns) 255
Kapitel 14: Component (Komponente) 257
14.1 Motivation 257
14.1.1 Der Gordische Knoten 258
14.1.2 Den Knoten durchschlagen 258
14.1.3 Unerledigtes 259
14.1.4 Wiederverwendung 259
14.2 Das Pattern 261
14.3 Anwendbarkeit 261
14.4 Konsequenzen 262
14.5 Beispielcode 262
14.5.1 Eine monolithische Klasse 263
14.5.2 Abspalten eines Bereichs 264
14.5.3 Abspalten der übrigen Bereiche 266
14.5.4 Robo-Bjørn 268
14.5.5 Ganz ohne Bjørn? 270
14.6 Designentscheidungen 272
14.6.1 Wie gelangt ein Objekt an seine Komponenten? 273
14.6.2 Wie kommunizieren die Komponenten untereinander? 273
14.7 Siehe auch ... 277
Kapitel 15: Event Queue (Ereigniswarteschlange) 279
15.1 Motivation 279
15.1.1 Ereignisschleife der grafischen Benutzeroberfläche 279
15.1.2 Zentrale Ereignissammlung 280
15.1.3 Wie bitte? 281
15.2 Das Pattern 284
15.3 Anwendbarkeit 284
15.4 Konsequenzen 285
15.4.1 Eine zentrale Ereigniswarteschlange ist eine globale Variable 285
15.4.2 Den Boden unter den Füßen verlieren 285
15.4.3 Steckenbleiben in Rückkopplungsschleifen 286
15.5 Beispielcode 286
15.5.1 Ein Ring-Buffer 289
15.5.2 Anfragen zusammenfassen 293
15.5.3 Threads 294
15.6 Designentscheidungen 295
15.6.1 Was soll in die Warteschlange aufgenommen werden? 295
15.6.2 Wer darf lesend auf die Warteschlange zugreifen? 296
15.6.3 Wer darf schreibend auf die Warteschlange zugreifen? 298
15.6.4 Wie lang ist die Lebensdauer der Objekte in der Warteschlange? 299
15.7 Siehe auch ... 300
Kapitel 16: Service Locator (Dienstlokalisierung) 301
16.1 Motivation 301
16.2 Das Pattern 302
16.3 Anwendbarkeit 302
16.4 Konsequenzen 303
16.4.1 Der Dienst muss auch tatsächlich lokalisiert werden können 303
16.4.2 Dem Dienst ist nicht bekannt, wer ihn nutzt 303
16.5 Beispielcode 304
16.5.1 Der Dienst 304
16.5.2 Der Dienstanbieter 304
16.5.3 Ein einfacher Service Locator 305
16.5.4 Ein leerer Dienst 306
16.5.5 Protokollierender Dekorierer 308
16.6 Designentscheidungen 310
16.6.1 Wie wird der Dienst lokalisiert? 310
16.6.2 Was geschieht, wenn die Lokalisierung des Dienstes scheitert? 312
16.6.3 Wer darf auf den Dienst zugreifen? 315
16.7 Siehe auch ... 316
Teil VI: Optimierungsmuster (Optimization Patterns) 317
Kapitel 17: Data Locality (Datenlokalität) 319
17.1 Motivation 319
17.1.1 Ein Datenlager 320
17.1.2 Eine Palette für die CPU 322
17.1.3 Daten = Performance? 323
17.2 Das Pattern 324
17.3 Anwendbarkeit 325
17.4 Konsequenzen 325
17.5 Beispielcode 326
17.5.1 Aneinandergereihte Arrays 326
17.5.2 Gebündelte Daten 331
17.5.3 Hot/Cold Splitting 335
17.6 Designentscheidungen 337
17.6.1 Wie wird Polymorphismus gehandhabt? 338
17.6.2 Wie werden Spielobjekte definiert? 339
17.7 Siehe auch ... 342
Kapitel 18: Dirty Flag (Veraltet-Flag) 345
18.1 Motivation 345
18.1.1 Lokale Koordinaten und Weltkoordinaten 346
18.1.2 Gecachete Weltkoordinaten 347
18.1.3 Verzögerte Berechnung 348
18.2 Das Pattern 350
18.3 Anwendbarkeit 350
18.4 Konsequenzen 351
18.4.1 Nicht zu lange verzögern 351
18.4.2 Das Flag bei jedem Zustandswechsel ändern 352
18.4.3 Vorherige abgeleitete Daten verbleiben im Speicher 352
18.5 Beispielcode 353
18.5.1 Nicht-optimierte Traversierung 354
18.5.2 Let’s Get Dirty 355
18.6 Designentscheidungen 358
18.6.1 Wann wird das Dirty Flag gelöscht? 358
18.6.2 Wie feingranular ist Ihr »Dirty-Tracking«? 359
18.7 Siehe auch ... 360
Kapitel 19: Object Pool (Objektpool) 361
19.1 Motivation 361
19.1.1 Der Fluch der Fragmentierung 361
19.1.2 Das Beste beider Welten 362
19.2 Das Pattern 363
19.3 Anwendbarkeit 363
19.4 Konsequenzen 363
19.4.1 Der Pool verschwendet möglicherweise Speicherplatz für ungenutzte Objekte 363
19.4.2 Es steht nur eine feste Anzahl von Objekten zur Verfügung 364
19.4.3 Die Objekte sind von fester Größe 365
19.4.4 Wiederverwendete Objekte werden nicht automatisch zurückgesetzt 365
19.4.5 Unbenutzte Objekte verbleiben im Arbeitsspeicher 366
19.5 Beispielcode 366
19.5.1 Eine kostenlose Liste 369
19.6 Designentscheidungen 372
19.6.1 Sind Objekte an den Pool gekoppelt? 372
19.6.2 Wer ist für die Initialisierung der wiederverwendeten Objekte verantwortlich? 374
19.7 Siehe auch ... 376
Kapitel 20: Spatial Partition (Räumliche Aufteilung) 377
20.1 Motivation 377
20.1.1 Kampfeinheiten auf dem Schlachtfeld 377
20.1.2 Schlachtreihen zeichnen 378
20.2 Das Pattern 379
20.3 Anwendbarkeit 379
20.4 Konsequenzen 379
20.5 Beispielcode 380
20.5.1 Ein Bogen Millimeterpapier 380
20.5.2 Ein Gitternetz verketteter Einheiten 381
20.5.3 Betreten des Schlachtfeldes 383
20.5.4 Klirrende Schwerter 384
20.5.5 Vormarschieren 385
20.5.6 Um Armeslänge 386
20.6 Designentscheidungen 390
20.6.1 Ist die Aufteilung hierarchisch oder gleichmäßig? 390
20.6.2 Hängt die Zellengröße von der Verteilung der Objekte ab? 391
20.6.3 Werden die Objekte nur in den Zellen gespeichert? 393
20.7 Siehe auch ... 394
Stichwortverzeichnis 395
Teil I: Einführung
In diesem Teil:
-
Architektur, Performance und Spiele
Im fünften Schuljahr standen in unserem Klassenzimmer ein paar ziemlich ramponierte TRS-80-Computer herum, die meine Freunde und ich benutzen durften. Ein Lehrer, der unsere Begeisterung wecken wollte, gab uns einen Stapel Ausdrucke einiger einfacher BASIC-Programme, mit denen wir experimentieren konnten.
Die Kassettenlaufwerke der Rechner waren defekt, d.h., wenn wir Code ausführen wollten, mussten wir ihn immer sehr sorgfältig komplett neu eingeben. Das führte dazu, dass wir bevorzugt auf Programme zurückgriffen, die nur einige wenige Zeilen lang waren:
10 PRINT "BOBBY IST EIN RADIKALER!!!" 20 GOTO 10Vielleicht wird es ja auf wundersame Weise wahr, wenn der Computer es nur oft genug ausgibt ...
Trotzdem war das Ganze Glückssache. Wir hatten keine Ahnung von Programmierung, und schon der kleinste Syntaxfehler war für uns unergründlich. Wenn ein Programm nicht funktionierte, und das kam des Öfteren vor, fingen wir einfach von vorne an.
Am unteren Ende des Papierstapels mit Ausdrucken fanden wir schließlich ein richtiges Ungeheuer: ein Programm, das aus mehreren eng mit Code bedruckten Seiten bestand. Es dauerte ein Weilchen, bis wir überhaupt den Mut aufbrachten, es einzugeben, aber es war einfach unwiderstehlich, denn der Titel am Anfang des Listings lautete »Tunnels & Trolls«. Wir hatten keinen blassen Schimmer, worum es bei dem Programm ging, aber es klang nach einem Spiel, und was könnte cooler sein als ein selbstprogrammiertes Computerspiel?
Leider haben wir es nie zum Laufen bekommen und im darauffolgenden Schuljahr zogen wir in ein anderes Klassenzimmer um. (Jahre später, nachdem ich etwas BASIC gelernt hatte, wurde mir klar, dass es sich seinerzeit gar nicht um ein Spiel gehandelt hatte. Das Programm erzeugte bloß verschiedene Persönlichkeiten für das eigentliche Rollenspiel.) Dessen ungeachtet waren die Würfel gefallen: Ich hatte mir in den Kopf gesetzt, Spieleprogrammierer zu werden.
Als ich ein Teenager war, schaffte sich meine Familie einen Macintosh mit QuickBASIC an, später kam dann THINK C dazu. Ich habe fast meine gesamten Sommerferien damit verbracht, Spiele zusammenzuhacken. Es war mühsam, auf mich allein gestellt zu lernen und es ging nur langsam vorwärts. Anfangs war es gar nicht so schwer und ich bekam schnell etwas zum Laufen – vielleicht eine Landkartendarstellung oder ein kleines Puzzle. Aber sobald die Programme etwas umfangreicher waren, wurde es immer schwieriger.
Die übrige Zeit verbrachte ich damit, in den Sümpfen des südlichen Louisianas Schlangen und Schildkröten einzufangen. Wenn es draußen nicht so glühend heiß wäre, könnte sich dieses Buch sehr wohl auch um Amphibien- und Reptilienforschung drehen, statt um Programmierung.
Zunächst bestand die Herausforderung nur darin, überhaupt etwas zum Funktionieren zu bekommen. Dann musste ich mir überlegen, wie ich Programme schreiben konnte, die aus mehr Zeilen bestanden, als ich mir gleichzeitig merken konnte. Anstatt Bücher wie »Programmierung in C« von Kernighan und Ritchie zu lesen, versuchte ich Fachliteratur zu finden, die sich mit dem Organisieren von Programmen befasste.
Zeitsprung. Mehrere Jahre später drückte mir ein Bekannter das Buch Design Patterns: Entwurfsmuster als Elemente wiederverwendbarer objektorientierter Software in die Hand. Endlich! Das war genau das Nachschlagewerk, nach dem ich seit meiner Teenagerzeit gesucht hatte. Ich las es in einem Rutsch von vorne bis hinten durch. Zwar hatte ich noch immer mit meinen eigenen Programmen zu kämpfen, aber mir fiel ein Stein vom Herzen, als ich begriff, dass andere Leute ähnliche Schwierigkeiten hatten und Lösungen dafür erarbeiteten. Ich hatte das Gefühl, dass ich statt »nur« meiner bloßen Hände nun endlich richtige Werkzeuge einsetzen konnte.
Den Bekannten, der mir das Buch gab, lernte ich bei dieser Gelegenheit übrigens gerade erst kennen. Fünf Minuten nachdem wir einander vorgestellt wurden, saß ich auf seinem Sofa und verbrachte die nächsten Stunden mit Lesen, wobei ich ihn vollkommen ignorierte. Ich hoffe allerdings, dass sich meine Sozialkompetenz seitdem doch ein wenig verbessert hat.
2001 trat ich meinen Traumjob an: Programmierer bei Electronic Arts. Ich konnte es kaum erwarten, mir die richtigen Spiele anzusehen und herauszufinden, wie die Profis sie entwickeln. Wie sieht wohl die Architektur eines so gigantischen Spiels wie Madden Football aus? Wie arbeiten die verschiedenen Systemkomponenten zusammen? Wie schaffen sie es, eine einzige Codebasis auf mehreren Plattformen zum Laufen zu bringen?
Als ich den Quellcode sah, war das eine demutsvolle und überraschende Erfahrung. Der Code zur Grafikerzeugung, die künstliche Intelligenz (KI), die Animationen und visuellen Effekte – all das war einfach brillant. Hier gab es Leute, die das letzte bisschen Leistung aus der CPU herauskitzeln und nutzen konnten. Sie erledigten Dinge, von denen ich gar nicht wusste, dass sie überhaupt möglich sind, schon vor der Mittagspause.
Aber der Architektur, in der sich dieser brillante Code befand, wurde kaum Beachtung geschenkt. Die Programmierer waren so sehr auf Features konzentriert, dass sie dabei die Organisation übersahen. Es wimmelte nur so von eng gekoppelten Modulen. Neue Features wurden der Codebasis da aufgepfropft, wo es gerade passte. Ernüchtert musste ich feststellen, dass es viele der Programmierer offenbar nicht weiter als bis zum Singleton-Pattern geschafft hatten – wenn sie das Buch Design Patterns denn überhaupt mal aufgeschlagen haben sollten.
Na ja, ganz so schlimm war es natürlich auch wieder nicht. Ich hatte mir allerdings ausgemalt, dass Spieleprogrammierer mithilfe von Wandtafelen wochenlang in aller Seelenruhe in einem Elfenbeinturm die architektonischen Einzelheiten ausdiskutierten – tatsächlich war der Code, den ich mir ansah, jedoch von Leuten geschrieben worden, die sich mit engen Abgabefristen konfrontiert sahen. Sie gaben wirklich ihr Bestes und das war, so dämmerte mir allmählich, oft sehr gut. Je länger ich mich mit der Arbeit am Gamecode beschäftigte, desto mehr brillante Codeschnipsel entdeckte ich, die sich unter der Oberfläche versteckten.
Leider war »versteckt« häufig eine allzu treffende Beschreibung. Es waren echte Juwelen im Code verborgen, die viele völlig übersahen. Ich habe mehr als nur einmal erlebt, dass andere Programmierer sich damit abmühten, Dinge neu zu erfinden, obwohl in der Codebasis, mit der sie arbeiteten, bereits gute Lösungen für genau die betreffende Fragestellung vorhanden waren.
Dieses Problem möchte das vorliegende Buch lösen. Ich habe die besten in der Spieleprogrammierung vorkommenden Patterns ausgewählt, geordnet und zusammengestellt, damit wir unsere Zeit damit verbringen können, Dinge tatsächlich neu zu erfinden, anstatt sie wieder zu erfinden.
Darum geht es
Es gibt bereits Dutzende Bücher über Spieleprogrammierung – warum also ein weiteres schreiben? Die meisten mir bekannten Bücher zum Thema Spieleprogrammierung gehören einer der beiden folgenden Kategorien an:
Themenspezifische Bücher Diese Bücher sind weitestgehend auf einen bestimmten Aspekt der Spieleprogrammierung fokussiert, wie etwa 3D-Grafik, Rendern in Echtzeit, Physiksimulation, künstliche Intelligenz oder Audio. Das sind die Gebiete, auf die sich viele Spieleprogrammierer im Lauf ihrer Karriere spezialisieren.
Bücher über komplette Spiel-Engines Im Gegensatz zu der vorgenannten Kategorie versuchen diese Bücher, alle Bestandteile einer Engine abzuhandeln. Sie sind auf die Entwicklung einer kompletten Engine für ein bestimmtes Spielgenre ausgerichtet, meist 3D-Ego-Shooter.
Mir sagen die beiden Kategorien durchaus zu, aber ich denke, dass sie einige Lücken lassen. Themenspezifische Bücher erklären selten, wie der Code mit dem Rest des Spiels zusammenwirkt. Sie mögen vielleicht beim Rendern und der Physiksimulation ein alter Hase sein, aber wissen Sie auch, wie man beides vernünftig miteinander verbindet?
Dieser Bereich wird von der zweiten Kategorie zwar abgedeckt, ich finde die Bücher über komplette Spiel-Engines allerdings oft zu einseitig und genrebezogen. Mit dem Aufkommen von Smartphones und der damit einhergehenden Verbreitung mobiler Spiele und sogenannter Casual Games (einfache Spiele, die man bei Gelegenheit spielt) sind wir in einem Zeitalter angelangt, in dem viele verschiedene Spielegenres bedient werden. Wir klonen nicht mehr nur Quake. Bücher über Spiel-Engines helfen Ihnen nicht weiter, wenn Ihr Spiel nicht zur Engine passt.
Ich bemühe mich hier darum, die Themen eher wie auf einer Speisekarte zu präsentieren. Die einzelnen Kapitel im Buch beruhen auf jeweils unabhängigen Konzepten, die auf Ihren Code anwendbar sind. Auf diese Weise können Sie sie so zusammenstellen, wie es am besten zu dem Spiel passt, das Sie entwickeln möchten.
Ein weiteres Beispiel für diesen »Speisekarten-Ansatz« ist die hochgelobte Buchreihe Game...
Erscheint lt. Verlag | 26.8.2015 |
---|---|
Reihe/Serie | mitp Professional |
Verlagsort | Frechen |
Sprache | deutsch |
Themenwelt | Mathematik / Informatik ► Informatik ► Programmiersprachen / -werkzeuge |
Schlagworte | Entwickler • Games • Programmierung • Spiele • Spieleentwicklung |
ISBN-10 | 3-95845-091-1 / 3958450911 |
ISBN-13 | 978-3-95845-091-2 / 9783958450912 |
Haben Sie eine Frage zum Produkt? |
![PDF](/img/icon_pdf_big.jpg)
Größe: 32,1 MB
Digital Rights Management: ohne DRM
Dieses eBook enthält kein DRM oder Kopierschutz. Eine Weitergabe an Dritte ist jedoch rechtlich nicht zulässig, weil Sie beim Kauf nur die Rechte an der persönlichen Nutzung erwerben.
Dateiformat: PDF (Portable Document Format)
Mit einem festen Seitenlayout eignet sich die PDF besonders für Fachbücher mit Spalten, Tabellen und Abbildungen. Eine PDF kann auf fast allen Geräten angezeigt werden, ist aber für kleine Displays (Smartphone, eReader) nur eingeschränkt geeignet.
Systemvoraussetzungen:
PC/Mac: Mit einem PC oder Mac können Sie dieses eBook lesen. Sie benötigen dafür einen PDF-Viewer - z.B. den Adobe Reader oder Adobe Digital Editions.
eReader: Dieses eBook kann mit (fast) allen eBook-Readern gelesen werden. Mit dem amazon-Kindle ist es aber nicht kompatibel.
Smartphone/Tablet: Egal ob Apple oder Android, dieses eBook können Sie lesen. Sie benötigen dafür einen PDF-Viewer - z.B. die kostenlose Adobe Digital Editions-App.
Zusätzliches Feature: Online Lesen
Dieses eBook können Sie zusätzlich zum Download auch online im Webbrowser lesen.
Buying eBooks from abroad
For tax law reasons we can sell eBooks just within Germany and Switzerland. Regrettably we cannot fulfill eBook-orders from other countries.
![EPUB](/img/icon_epub_big.jpg)
Größe: 3,7 MB
Digital Rights Management: ohne DRM
Dieses eBook enthält kein DRM oder Kopierschutz. Eine Weitergabe an Dritte ist jedoch rechtlich nicht zulässig, weil Sie beim Kauf nur die Rechte an der persönlichen Nutzung erwerben.
Dateiformat: EPUB (Electronic Publication)
EPUB ist ein offener Standard für eBooks und eignet sich besonders zur Darstellung von Belletristik und Sachbüchern. Der Fließtext wird dynamisch an die Display- und Schriftgröße angepasst. Auch für mobile Lesegeräte ist EPUB daher gut geeignet.
Systemvoraussetzungen:
PC/Mac: Mit einem PC oder Mac können Sie dieses eBook lesen. Sie benötigen dafür die kostenlose Software Adobe Digital Editions.
eReader: Dieses eBook kann mit (fast) allen eBook-Readern gelesen werden. Mit dem amazon-Kindle ist es aber nicht kompatibel.
Smartphone/Tablet: Egal ob Apple oder Android, dieses eBook können Sie lesen. Sie benötigen dafür eine kostenlose App.
Geräteliste und zusätzliche Hinweise
Zusätzliches Feature: Online Lesen
Dieses eBook können Sie zusätzlich zum Download auch online im Webbrowser lesen.
Buying eBooks from abroad
For tax law reasons we can sell eBooks just within Germany and Switzerland. Regrettably we cannot fulfill eBook-orders from other countries.
aus dem Bereich