Entwurf und Implementierung eines Rapid-Prototyping
Transcription
Entwurf und Implementierung eines Rapid-Prototyping
Entwurf und Implementierung eines Rapid-Prototyping-Tools für 2D-Spiele Christian Herzog DIPLOMARBEIT eingereicht am Fachhochschul-Masterstudiengang Digitale Medien in Hagenberg im September 2010 © Copyright 2010 Christian Herzog Alle Rechte vorbehalten ii Erklärung Hiermit erkläre ich an Eides statt, dass ich die vorliegende Arbeit selbstständig und ohne fremde Hilfe verfasst, andere als die angegebenen Quellen und Hilfsmittel nicht benutzt und die aus anderen Quellen entnommenen Stellen als solche gekennzeichnet habe. Hagenberg, am 21. September 2010 Christian Herzog iii Inhaltsverzeichnis Erklärung iii Vorwort vii Kurzfassung viii Abstract ix 1 Einleitung 1.1 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 Fragestellung . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3 Übersicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Theoretischer Hintergrund 2.1 Kernelemente eines Spiels . . . . . . . . . . 2.1.1 Eingabe . . . . . . . . . . . . . . . . 2.1.2 Grafikausgabe . . . . . . . . . . . . . 2.1.3 Gameplay . . . . . . . . . . . . . . . 2.1.4 Kollisionserkennung und Physik . . . 2.1.5 Sound . . . . . . . . . . . . . . . . . 2.1.6 Multiplayer . . . . . . . . . . . . . . 2.2 Produktionsphasen eines Computerspiels . . 2.2.1 Pre-Production . . . . . . . . . . . . 2.2.2 Production . . . . . . . . . . . . . . 2.2.3 Alpha . . . . . . . . . . . . . . . . . 2.2.4 Beta . . . . . . . . . . . . . . . . . . 2.2.5 Gold-Master . . . . . . . . . . . . . . 2.3 Ansätze für Game-Engines . . . . . . . . . . 2.3.1 Definition des Begriffs Game-Engine 2.3.2 Definition des Begriffs Game-Object 2.3.3 Objektorientierter Ansatz . . . . . . 2.3.4 Komponentenbasierter Ansatz . . . . 2.4 Rapid-Prototyping . . . . . . . . . . . . . . iv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1 2 2 4 4 4 5 6 7 8 8 9 9 9 10 10 10 10 10 11 11 12 13 Inhaltsverzeichnis v 3 Übersicht von Rapid-Prototyping-Tools 3.1 Kriterien . . . . . . . . . . . . . . . . . . 3.2 2D Boy’s Rapid Prototyping Framework 3.3 Cogaen / ACES . . . . . . . . . . . . . . 3.4 Game Editor . . . . . . . . . . . . . . . 3.5 Game Maker . . . . . . . . . . . . . . . 3.6 PushButton Engine . . . . . . . . . . . . 3.7 Torque Game Builder . . . . . . . . . . 3.8 3D Lösungen . . . . . . . . . . . . . . . 3.8.1 ShiVa . . . . . . . . . . . . . . . 3.8.2 Unity . . . . . . . . . . . . . . . 3.8.3 Unreal Development Kit . . . . . 3.8.4 Quest3D . . . . . . . . . . . . . . 3.9 Fazit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 15 16 17 17 19 21 21 23 24 25 26 28 28 4 Entwurf und Implementierung 30 4.1 Ausgangssituation . . . . . . . . . . . . . . . . . . . . . . . . 30 4.2 Festlegungen . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 4.3 Grundlegende Architektur . . . . . . . . . . . . . . . . . . . . 32 4.3.1 View-Control . . . . . . . . . . . . . . . . . . . . . . . 32 4.3.2 Model . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 4.3.3 Kommunikation zwischen den Applikationsteilen . . . 33 4.4 Datenfluss Beispiele . . . . . . . . . . . . . . . . . . . . . . . 36 4.4.1 Start der Applikation . . . . . . . . . . . . . . . . . . . 36 4.4.2 Selektieren einer Entität . . . . . . . . . . . . . . . . . 36 4.4.3 Ändern einer Eigenschaft durch den Property Browser 37 4.5 Kernelemente im Detail . . . . . . . . . . . . . . . . . . . . . 39 4.5.1 Projektverwaltung . . . . . . . . . . . . . . . . . . . . 39 4.5.2 Entity Explorer . . . . . . . . . . . . . . . . . . . . . . 40 4.5.3 Property Browser . . . . . . . . . . . . . . . . . . . . . 41 4.5.4 Undo-/Redo-System . . . . . . . . . . . . . . . . . . . 41 4.5.5 Log View . . . . . . . . . . . . . . . . . . . . . . . . . 41 4.5.6 Component Browser . . . . . . . . . . . . . . . . . . . 42 4.5.7 Transformations-Gizmo . . . . . . . . . . . . . . . . . 42 4.5.8 Template Editor . . . . . . . . . . . . . . . . . . . . . 42 5 Ergebnisse 5.1 Jump-and-Run-Demo . . . . . . 5.1.1 Vorkommende Entitäten 5.2 Racing-Demo . . . . . . . . . . 5.2.1 Vorkommende Entitäten 5.3 Space-Shooter-Demo . . . . . . 5.3.1 Vorkommende Entitäten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 45 45 48 48 50 50 Inhaltsverzeichnis vi 6 Resümee 6.1 Diskussion der Ergebnisse . . . . . . . . . . . . . . 6.1.1 Entwicklungszeit und Wiederverwendbarkeit 6.1.2 Prototyp als Basis für ein fertiges Spiel . . . 6.2 Level Master 2000 . . . . . . . . . . . . . . . . . . 6.2.1 Gewählte Architektur . . . . . . . . . . . . 6.2.2 Verbesserungsvorschläge . . . . . . . . . . . 6.3 Abschlussbemerkungen und Ausblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 53 53 55 55 55 56 57 A Verwendete Komponenten A.1 Selbst erstellte Komponenten . . . . . . . . . . . . A.1.1 Namespace com.zog . . . . . . . . . . . . . A.2 Verwendete Komponenten der PushButton Engine A.2.1 Namespace com.pblabs.rendering2D . . . A.2.2 Namespace com.pblabs.box2D . . . . . . . A.2.3 Weitere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 59 59 61 61 62 63 . . . . 64 64 64 64 65 B Inhalt der CD-ROM B.1 Diplomarbeit . . . B.2 Projektdateien . . B.3 Webquellen . . . . B.4 Bilder . . . . . . . Literaturverzeichnis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 Vorwort „Undank ist der Welten Lohn.“ An dieser Stelle möchte ich mich bei allen Personen bedanken, die mich während meines Studiums unterstützt haben. Besonders hervorzuheben ist die Unterstützung von meinen Eltern und meiner Freundin Sonja. Großen Dank auch an iko, Meisi und Geo für das ausführliche Feedback zur Arbeit. vii Kurzfassung Die Entwicklungskosten von Computerspielen befinden sich heutzutage auf sehr hohem Niveau. Mithilfe eines Rapid-Prototyping-Tools kann ein Entwickler Computerspielprototypen effizient erstellen und auch möglichst früh im Entwicklungsprozess entscheiden, ob sich eine Idee oder ein Feature eignet oder nicht – und somit Kosten sparen. Die vorliegende Diplomarbeit behandelt die Grundlagen der Computerspielentwicklung, definiert die Begriffe rund um den Terminus Rapid-Prototyping und gibt einen Überblick über aktuelle Rapid-Prototyping-Tools. Um die Entwicklungskosten eines Spiels weiter zu senken, wird untersucht, ob aus dem erstellten Prototyp auch das finale Spiel erstellt werden kann, wenn ein dafür ausgelegtes Framework vorliegt. Die Behauptung, dass Prototyp-Code Wegwerf-Code ist, wird also hinterfragt. Zu diesem Zweck wird im praktischen Teil der Arbeit der „Level Master 2000“ vorgestellt, eine Applikation, die den Anforderungen eines RapidPrototyping-Tools gerecht werden soll. Es wird sowohl ein Einblick in den Entwurf, als auch in die konkrete Implementierung gegeben. Um die Möglichkeiten des „Level Master 2000“ zu demonstrieren und die Frage nach der Weiterverwendung eines Prototyps zu beantworten, wurden abschließend drei Demo-Spiele damit umgesetzt und analysiert. viii Abstract Development costs of computer games are at a high level nowadays. With the usage of rapid prototyping tools, a developer can efficiently create computer game prototypes and hence also decide very early in the development process, if an idea or a feature is good enough, to make it into the final game – and this way reduce costs. The presented thesis covers the basics of game development, defines the terms around rapid prototyping and gives an overview about current rapid prototyping tools. To further lower the development costs of a game, it is investigated, if one can create a final game out of the developed prototype, if a framework geared towards this task is available. The claim, such that prototype code is throw-away code, is questioned. In order to achieve this, the “Level Master 2000” is presented in the practical part of this thesis. It is an application, which wants to meet the requirements of a typical rapid prototyping tool. An indepth view about design and the concrete implementation is given. To further demonstrate the possibilities of the “Level Master 2000” and to answer the given question about reusing prototypes, three demo games are created and analyzed. ix Kapitel 1 Einleitung 1.1 Motivation Die Entwicklungskosten von Computerspielen steigen stetig. Mittlerweile haben international erscheinende Multi-Plattform-Titel, wie zum Beispiel die Grand Theft Auto- oder die Assassin’s Creed-Reihe, Kosten- und Einnahmedimensionen erreicht, die mit so manchem Kinofilm mithalten können1 . Laut Michael Pachter (Managing Director, Wedbush Morgan) zeichnet sich weiteres Wachstum der Branche ab. So prophezeihte er im Juni 20092 : In our view, the video game market is likely to grow at or above a 7.2 percent rate for the next 10 years, at least doubling over that time. Zeitgleich werden aber auch Bedenken laut, dass die Innovationskraft der Branche zum Stillstand kommt. Große Publisher tendieren dazu, ihre etablierten Marken weiter auszubauen, anstatt sich um neuartige Spielkonzepte zu kümmern, da sie keine zusätzlichen Kosten riskieren wollen. Um Innovationen sollen sich die Independent-Entwickler kümmern3 . Dabei handelt es sich um Entwickler, die ihre Spiele ohne Publisher entwickeln und vermarkten. Aufgrund dieser Tatsache verfügen diese jedoch meist über ein sehr begrenztes Budget, womit eine möglichst frühzeitige Einschätzung des Potentials eines Spiels, als auch die Minimierung der Entwicklungszeit, von großer Bedeutung ist. Hier kann das so genannte Rapid-Prototyping (siehe Abschnitt 2.4) den Entwickler unterstützen. Damit soll es möglich sein (egal ob IndependentEntwickler oder nicht), innerhalb kürzester Zeit neue Spielideen zu verwirklichen, wenn ein entsprechendes Framework zur Verfügung steht. Auf Grund 1 Kosten am Beispiel GTA 4: http://grandtheftauto.ign.com/articles/news/408/100Million-Spent-on-GTA-IV-Development. Einnahmen am Beispiel GTA 4: http://kotaku. com/387934/nyt-gta-ivs-sold-6-million-copies-made-500-million 2 http://www.gamespot.com/pc/strategy/starcraft/news.html?sid=6212790 3 http://www.gamasutra.com/php-bin/news_index.php?story=26128 1 1. Einleitung 2 dieser kurzen Entwicklungszeit ist es somit (meist) nicht kritisch, wenn ein Prototyp nach der Beurteilung verändert oder gar verworfen wird. 1.2 Fragestellung Im Rahmen dieser Arbeit sollen nun folgende Fragen geklärt werden: 1. Wie kann man möglichst viele verschiedene Arten von Computerspielprototypen möglichst einfach und schnell realisieren? 2. Gibt es eine Möglichkeit, aus diesen Prototypen ein finales Spiel zu erstellen? Der Fokus liegt hier also sowohl auf der Geschwindigkeit der Umsetzung, als auch auf der weiteren Verwendbarkeit des Prototyps hin zu einem fertigen Spiel. Der präsentierte Lösungsansatz fängt bei der Wahl der zu Grunde liegenden Architektur der Game-Engine (siehe Abschnitt 2.3) an und setzt sich bis zu dem konkreten Design eines Editors fort. Dieser Editor soll den Entwickler so weit unterstützen, dass der weitere Entwicklungsaufwand auf ein Minimum reduziert wird: Im Idealfall soll es möglich sein, ein vollständiges Spiel im Editor erstellen zu können, ohne auch nur eine Zeile Code schreiben zu müssen. Im Zuge dieser Arbeit wird auch ein Überblick über bereits vorhandene Rapid-Prototyping-Tools gegeben, um einen Vergleich mit dem präsentierten Ansatz ziehen zu können. 1.3 Übersicht Kapitel 2: „Theoretischer Hintergrund“ vermittelt die Grundlagen der Computerspielentwicklung, die für das Verständnis des Rapid-Prototyping benötigt werden. Es listet die Kernelemente auf, in die sich ein Spiel zerlegen lässt, und erklärt die einzelnen Produktionsphasen. Abschließend werden Begriffe rund um die Termini Game-Engine und Rapid-Prototyping definiert. Kapitel 3: „Übersicht von Rapid-Prototyping-Tools“ präsentiert die gängigsten Lösungen. Neben einer Zusammenfassung erfolgt eine Auflistung der jeweiligen Produktmerkmale. Da es auch viele 3D Rapid-PrototypingTools gibt, mit denen man aber auch 2D Spiele erstellen kann, werden die etablierteren Tools aus diesem Bereich ebenfalls angeführt. Kapitel 4: „Entwurf und Implementierung“ zeigt das Projekt, welches im Rahmen dieser Diplomarbeit entstand. Zunächst wird die Ausgangssituation erläutert. Danach wird ein Überblick über die gewählte Architektur gegeben und zum Schluss wird auf die einzelnen Kernelemente der Applikation näher eingegangen. 1. Einleitung 3 Kapitel 5: „Ergebnisse“ gibt einen Überblick über die drei erstellten Prototypen Jump-And-Run, Racing und Space Shooter. Neben einer Beschreibung des Funktionsumfanges jedes Prototyps werden die einzelnen GameObjects im Detail angeführt. Kapitel 6: „Resümee“ fasst die Erkenntnisse aus Kapitel 4 und Kapitel 5 zusammen, um die Fragestellung zu beantworten. Es werden auch Verbesserungsvorschläge präsentiert und ein kurzer Ausblick über die Zukunft des Projektes gegeben. Anhang A: „Verwendete Komponenten“ beschreibt alle Komponenten, die bei den drei Prototypen zum Einsatz kamen. Kapitel 2 Theoretischer Hintergrund Im ersten Abschnitt dieses Kapitels werden zunächst die Kernelemente, aus denen sich ein Computerspiel zusammensetzt, näher erläutert. In dem darauf folgenden Abschnitt wird darauf eingegangen, wie ein Computerspiel üblicherweise entwickelt und produziert wird. Abschließend werden Begriffe rund um die Termini Game-Engine und Rapid-Prototyping definiert. 2.1 Kernelemente eines Spiels Ein Computerspiel lässt sich in einzelne Elemente zerlegen. Klassischerweise sind dies laut [7, S. 28–49]: • Eingabe, • Gameplay, • Grafikausgabe, • Kollisionserkennung und Physik, • Sound • und Multiplayer. 2.1.1 Eingabe Eingabegeräte, auch Human Interface Devices (HID), dienen der Interaktion zwischen Mensch und Computer. Für Computerspiele gibt es eine Reihe von Eingabemöglichkeiten. Die gängigsten sind Tastatur, Maus, Joystick oder Gamepad. Immer mehr Verwendung finden auch Motioncontroller und Multitouch-Displays. Letztere werden vorzugsweise auf mobilen Endgeräten eingesetzt. Bei HIDs wird zwischen kontinuierlicher (auch analoger) und diskreter (digitaler) Eingabe unterschieden. So erzeugt der Ausschlag eines Joysticks einen Wert in dem Intervall [-1, 1], ein Tastendruck auf einer Tastatur entweder 0 oder 1. Dies muss wiederum vom Spielentwickler bei der Implementierung der Steuerung berücksichtigt werden. Zu diesem Zweck werden die jeweiligen Eingabemöglichkeiten üblicherweise auf Aktionen gelegt [7, S. 4 2. Theoretischer Hintergrund 5 Aktion Taste "A" "Bewegung nach links" Gamepad " Taste " " " Abbildung 2.1: Eingabe wird auf Aktionen gelegt, um eingabegeräteunabhängigen Code schreiben zu können. 43]. Wie in Abb. 2.1 dargestellt, kann man die Aktion „Bewegung nach links“ zum Beispiel mit der Taste „A“, Taste „Pfeil nach links“ oder mit dem Gamepad „Pfeil nach links“ verknüpfen. So kann der Entwickler unabhängig vom HID spielspezifischen Code schreiben. 2.1.2 Grafikausgabe Die Grafikausgabe ist dafür verantwortlich, den aktuellen Spielzustand auf dem Bildschirm zu zeigen. Dazu verwendet man meist eine Programmierschnittstelle wie OpenGL oder DirectX, welche auf die Grafikhardware des Computers zugreift. Je nach Art des Spiels, kann die dargestellte Grafik 2D oder 3D sein: 2D: Um 2D Grafikelemente darzustellen, werden üblicherweise Position, Rotation und die darzustellende Grafik (z.B. Textur oder Vektorgrafik) benötigt. 3D: Um 3D Grafikelemente darzustellen, werden üblicherweise Position, Orientierung im Raum und das 3D-Modell inkl. dessen Material benötigt. Vom gewählten Darstellungsraum unabhängig, gibt es noch folgende Unterkategorien (auf Implementierungsunterschiede zwischen 2D und 3D wird nicht weiter eingegangen)[7, S. 36–44]: • • • • Animation, visuelle Effekte, Szenenmanagement und das Frontend. Animation Diese kümmert sich um die Bewegung oder Veränderung von Grafiken über einen gewissen Zeitraum. In manchen Fällen ist das Animationssystem auch sehr eng an die Physik-Engine gebunden [7, S. 42ff]. 2. Theoretischer Hintergrund 6 Visuelle Effekte Hierbei handelt es sich zum Beispiel um die Darstellung von Materialeigenschaften, Partikeleffekten, Schatten oder sonstigen Postprocessingeffekten wie Tiefenunschärfe oder Überstrahleffekte [7, S. 38f]. Szenenmanagement Um Rechenleistung zu sparen, kümmert sich die Grafikausgabe um die (grafische) Optimierung der darzustellenden Szene. Dafür kommen Techniken wie ein Szenengraf, Culling, Material-Batching, Level-of-Detail u.s.w. zum Einsatz [7, S. 37f]. Frontend Hier wird zwischen der grafischen Benutzeroberfläche (Graphical User Interface, GUI) und dem Head-up-Display (HUD) unterschieden [7, S. 39f]. Die GUI ermöglicht die Interaktion zwischen dem Spieler und der Anwendung. Typische Spiele-GUI-Elemente sind: • Buttons (Navigieren durch ein Spielmenü), • Schieberegler (Einstellung der Mausgeschwindigkeit) oder • Drag and Drop Elemente (Ausrüsten eines Spielercharakters durch das Inventarmenü). Das HUD zeigt die für den Spieler relevanten Informationen auf dem Bildschirm an. Typische HUD-Elemente sind: • Die verbleibende Lebensenergie des Spielers, • eine Minimap als Orientierungshilfe oder • die aktuelle Punkteanzahl des Spielers. 2.1.3 Gameplay Unter dem Sammelbegriff Gameplay versteht man sehr viele verschiedenartige Aufgaben. Das Gameplay regelt die Spielwelt. Es definiert die Möglichkeiten des Spielers als auch die anderer Charaktere und Objekte. Darüber hinaus verwaltet es die Ziele und Aufgaben des Spielers [7, S. 45]. Konkrete Beispiele für Gameplayaufgaben sind: • Ermitteln, wann ein Spieler gewonnen oder verloren hat. • Wechseln der Spielwelt, wenn das Ende erreicht ist. • Reaktion auf die Eingabe (z.B. Steuerung des Spielcharakters). • Logik, z.B. anhand eines abgefeuerten Projektils: – Beim Abfeuern soll das Projektil in eine Richtung fliegen. – Beim Aufprall zerstört sich das Projektil selbst. 2. Theoretischer Hintergrund 7 – Beim Aufprall verursacht das Projektil ggf. Schaden beim Einschlagsobjekt. Ein Teilbereich des Gameplays ist die künstliche Intelligenz. Künstliche Intelligenz Künstliche Intelligenz (KI) in Computerspielen versucht, menschliches Verhalten nachzuahmen. Teilgebiete der KI sind unter anderem die Wegfindung oder das Nachbilden von Verhaltensmustern (z.B. angreifen oder flüchten). Dies ermöglicht u.a. die Simulation von so genannten Non-Player-Characters, mit denen ein Spieler interagieren kann – sei es in Form des Dialogs oder Konflikts [7, S. 47f]. 2.1.4 Kollisionserkennung und Physik Die Kollisionserkennung ist dafür verantwortlich, dass Kollisionen zwischen Objekten festgestellt und behandelt werden. Wie diese Behandlung aussieht, unterscheidet sich von Fall zu Fall. Kollidiert zum Beispiel der Spieler mit einer Wand, so wird dieser am Durchlaufen der Wand gehindert. Kollidiert der Spieler mit einem Trigger 1 , so kann der Spieler normal weiterlaufen. Generell ist für diese Art von Berechnung nicht zwangsläufig eine PhysikEngine notwendig. Eine Physik-Engine simuliert eine künstliche Welt physikalisch glaubhaft. Dies ist im Sinne von Computerspielen zu sehen, also nicht zu 100 % der Realität entsprechend. Wie Christian Herta in seinem Artikel Simulation und Spiele Physik (http://www.christianherta.de/physics.html) schreibt: Hier ist es besonders wichtig, dass die Algorithmen schnell sind, um in Echtzeit die Welt nachahmen zu können. Wird eine Physik-Engine eingesetzt, so verfügt diese bereits über eine integrierte Kollisionserkennung. Zusätzlich hat man Funktionalitäten, wie zum Beispiel die Simulation von: • starren Körpern, • deformierbaren Körpern, • Gelenken, • Federsystemen, • Flüssigkeiten, u.v.m2 . Mit zunehmender Leistung der Rechner werden Physik-Engines von immer mehr Spielen, in immer mehr Teilbereichen, eingesetzt. Deshalb wächst 1 Ein Trigger führt bei Berührung weitere Verhaltensweisen aus, die üblicherweise als Event oder Skriptereignis implementiert sind. 2 http://de.wikipedia.org/wiki/Physik-Engine 2. Theoretischer Hintergrund 8 Abbildung 2.2: Geo-Mod 2.0 Engine: vollkommen zerstörbare Spielwelt. Quelle: http://www.amazona.de/ die oben angeführte Liste ständig. Anfänglich für optische Spielereien verwendet (siehe das Spiel Trespasser, 1998), findet die Physik heutzutage auch Einzug ins tatsächliche Gameplay (siehe das Spiel Garry’s Mod, 2006). Besonders hervorzuheben ist auch Red Faction: Guerrilla von Volition, Inc. In diesem Spiel ist die gesamte Spielwelt zerstörbar, wodurch völlig neue Möglichkeiten im Gameplay offenbart werden. Abb. 2.2 zeigt die verwendete Geo-Mod 2.0 Engine im Einsatz. 2.1.5 Sound Die Sound-Engine kümmert sich darum, dass der Ton passend zur aktuellen Spielsituation abgespielt wird (man denke an den Doppler-Effekt oder die Wiedergabe von Projektileinschlägen auf verschiedenen Materialien). Für diesen Zweck bietet sie die Möglichkeit, Geräusche zu manipulieren: So können sämtliche Sounds zur Laufzeit mit diversen Effekten bearbeitet werden, wie zum Beispiel Echo, Hall, Distorsion oder Flanger. 2.1.6 Multiplayer Der Multiplayer-Modus eines Spiels ermöglicht das gleichzeitige Spielen von mehreren Personen gegen- oder miteinander. Es werden vier Arten von Multiplayer-Spielen unterschieden [7, S. 44f]: Single-Screen: Hier spielen mehrere Spieler mit demselben Gerät (z.B. PC oder Spielkonsole). Es gibt nur eine Ansicht für alle Spieler. 2. Theoretischer Hintergrund 9 Split-Screen: Die Situation ist ähnlich wie beim Single-Screen-Modus. Der Unterschied ist, dass pro Spieler eine eigene Ansicht existiert, und der Bildschirm dementsprechend auf die Teilnehmer aufgeteilt wird. Multiplayer über Netzwerk: Jeder Spieler verfügt über ein eigenes Gerät, welches mit dem der anderen kommuniziert. Im Gegensatz zu den beiden vorherigen Multiplayer-Modi ist somit auch eine räumliche Trennung möglich. Massive Multiplayer: Jeder Spieler verfügt über ein eigenes Gerät, welches mit einem Server kommuniziert. Hier spielen bis zu mehrere tausend Spieler gleichzeitig in einer persistenten Welt 3 . Technisch wird noch zwischen Peer-to-Peer und dem Client-Server-Modell unterschieden. Bei ersterem kommunizieren die einzelnen Teilnehmer direkt miteinander. Beim Client-Server-Modell kommuniziert jeder Client (Spieler) ausschließlich mit dem Server, der die Daten verarbeitet und wieder an die Clients retourniert. 2.2 Produktionsphasen eines Computerspiels Ein Computerspiel durchläuft während seiner Entwicklung verschiedene Produktionsphasen: Pre-Production, Production, Alpha-, Beta- und der GoldMaster-Status [3, S. 293–297]. 2.2.1 Pre-Production Die Pre-Production dient mehreren Zwecken gleichzeitig. In dieser Phase muss zunächst der Spielumfang spezifiziert werden (Game-Design-Document, Visual-Design-Document, Technical-Design-Document ) und die Projektplanung erfolgen. Auch dienen verschiedene Prototypen als Machbarkeitsstudie (siehe Abschnitt 2.4). Falls ein Publisher involviert ist, entscheidet dieser aufgrund der Ergebnisse der Pre-Production, ob und wie sich eine weitere Zusammenarbeit mit dem Entwickler ergibt [2, S. 207–212]. 2.2.2 Production Die Production ist die eigentliche Entwicklungsphase und dauert in der Regel sechs Monate bis zwei Jahre. In dieser Zeit werden alle vereinbarten Features implementiert und alle Assets (Grafiken, Sounds, u.s.w.) erstellt [2, S. 212ff]. 3 In einer persistenten Welt kann die Spielwelt von einem Spieler nicht pausiert werden. Es ist eine Spielwelt, in der der Zustand der Welt dauerhaft gespeichert wird und zu jeder Zeit für jeden Spieler zugänglich ist. 2. Theoretischer Hintergrund 2.2.3 10 Alpha Der Alpha-Status ist erreicht, wenn alle benötigten Features vollständig implementiert sind. Es wird von einem so genannten Feature-Lock gesprochen. Ab nun kümmert sich der Entwickler nur mehr darum, die Codebasis zu säubern, mögliche Fehler zu beheben und bei Bedarf die Performance weiter zu optimieren. Werden in oder nach diesem Status neue Features eingebaut, so ist das Projekt in den Production-Status zurückzustufen [3, S. 294]. 2.2.4 Beta Vom Erreichen des Beta-Status spricht man, wenn keine Fehler im Programmcode bekannt sind, die einer Auslieferung des Produkts im Wege stehen könnten. Fehler, die das Spielerlebnis nicht weiter stören, dürfen jedoch noch vorhanden sein [3, S. 294f]. 2.2.5 Gold-Master Der Gold-Master ist die Version, welche anschließend für die Herstellung des Spiels verwendet wird. Die Phase zwischen Beta und Gold-Master besteht für den Entwickler hauptsächlich aus Fehler Finden und Beheben. Je nach Qualitätsanspruch des Entwicklers/Publishers, kann diese Entwicklungsphase noch sehr viel Zeit in Anspruch nehmen. Es muss auch berücksichtigt werden, ob ein nachträglicher Patch ausgeliefert werden kann oder nicht [3, S. 295ff]. 2.3 Ansätze für Game-Engines 2.3.1 Definition des Begriffs Game-Engine Jason Gregory definiert in [7, S. 11] den Begriff Game-Engine wie folgt: We should probably reserve the term “game engine” for software, that is extensible and can be used as the foundation for many different games without major modification. In anderen Worten ist eine Game-Engine also ein Grundgerüst, das es dem Entwickler ermöglicht, ein Computerspiel zu entwickeln, ohne sich mit „LowLevel-Themen“, wie der Implementierung eines Rendersystems, auseinandersetzen zu müssen. Es sind in der Regel alle Kernelemente eines Spiels (siehe Abschnitt 2.1) von der Game-Engine abgedeckt. Nicht direkt ein Teil der Game-Engine, aber ein wichtiges Begleitprodukt – vor allem bei kommerziellen Game-Engines – sind Entwicklerwerkzeuge, die den Workflow unterstützen (z.B. Exporter für Assets, Level-Editor, Material-Editor, Partikel-Editor, Script-Editor). 2. Theoretischer Hintergrund 11 Eine der ersten Game-Engines war die, auf der das Spiel Doom (id Software, 1993) basierte. Aufgrund der Abgrenzung zwischen Kernelementen und spielspezifischem Content war es für externe Entwickler einfach, neue Spiele auf Basis dieser Engine zu entwickeln. Dies war jedoch auf das ShooterGenre begrenzt. Heutige Game-Engines zeichnen sich dadurch aus, dass sie modular aufgebaut und datengetrieben sind. Dadurch wird die Flexibilität und somit der potentielle Einsatzbereich über ein spezielles Genre hinaus erhöht [7, S. 11ff]. Das Geschäft um die Lizenzierung von Game-Engines an Drittentwickler wurde für viele Studios zu einem wichtigen wirtschaftlichen Faktor. In Bezug auf die Softwarearchitektur einer Game-Engine haben sich zwei Ansätze durchgesetzt: der objektorientierte (siehe Abschnitt 2.3.3) und der komponentenbasierte Ansatz (siehe Abschnitt 2.3.4) [7, S. 715–733]. Um die beiden Ansätze besser nachvollziehen zu können, sollte einem die Definition des Game-Objects bekannt sein (siehe nächster Abschnitt). 2.3.2 Definition des Begriffs Game-Object Marcin Chadym (Technical Director, Radical Entertainment) definiert ein Game-Object (auch Entity oder Actor) wie folgt [4]: A game object is anything that has a representation in the game world. Such as characters, props, vehicles, missiles, cameras, trigger volumes, lights, etc. Technischer formuliert, ist ein Game-Object als Sammlung von Attributen und Verhaltensmustern (Behaviors) zu sehen [7, S. 695f]. 2.3.3 Objektorientierter Ansatz Jason Gregory in [7, S. 718] dazu: A class hierarchy is the most intuitive and straightforward way to represent a collection of interrelated game object types. So it is not surprising that the majority of commercial game engines employ a class hierarchy based technique. Auf den ersten Blick erscheint es ausreichend, die benötigten Klassen hierarchisch nach ihrer Funktion zu gliedern. Dies führt aber im Problemfall zu sehr tiefen Hierarchien, welche für den Entwickler schwer zu überblicken, sowie schwer zu erweitern sind. Probleme, die auftreten, sind bei Mehrfachvererbung das Diamond-Problem oder der Bubble-Up Effect [7, S. 719–723]. In Abb. 2.3 sieht man ein Beispiel der Klassenaufteilung für den objektorientierten Ansatz. In (a) leitet sich das Visual vom GameObject ab, und Physical von Visual. Problematisch wird es nun, wenn man ein rein physikalisches 2. Theoretischer Hintergrund 12 GameObject GameObject Visual Physical Physical Visual (a) (b) Abbildung 2.3: Zwei objektorientierte Ansätze wie man ein Game-Object, bestehend aus Visual und Physical, erstellen kann. Objekt benötigt, wie z.B. einen Trigger. Dieser würde dann durch die gegebene Hierarchie trotzdem eine grafische Repräsentation besitzen. Wenn man die Situation wie in (b) umkehrt, steht man vor selbigem Problem, wenn man ein rein grafisches Objekt benötigt, welches keine physikalische Repräsentation hat. Ähnlich problematisch verhält sich die Situation, wenn man als Subklasse der Visual-Klasse eine Animated-Klasse einfügen will (welche sich um das Abspielen von Animationen kümmert): in (a) hätte jedes physikalische Objekt eine Animation und in (b) wäre jede Animation mit einem physikalischen Objekt ausgestattet. Wie man erkennt, treten schon alleine bei dieser simplen Hierarchie Probleme auf4 . 2.3.4 Komponentenbasierter Ansatz Ein Game-Object besteht hierbei aus beliebig vielen Komponenten, welche von einer gemeinsamen Basisklasse (Component) abgeleitet werden. Jason Gregory in [7, S. 724] dazu: A componentized design allows us to select only those features we need for each type of game object we create. In addition, it permits each feature to be maintained, extended, or re-factored without affecting the others. Je nach Implementierung können diese Komponenten über eine Schnittstelle miteinander kommunizieren (z.B. per Messages, Events oder PropertyReferences 5 ). Die Vorteile des komponentenbasierten Ansatzes sind die flache 4 Natürlich ließen sich diese mit z.B. Mix-In-Classes (vgl. [7, S. 721]) eingrenzen, es geht dem Autor jedoch primär um die Darstellung der Grundproblematik. 5 http://pushbuttonengine.com/docs/04-Components.html 2. Theoretischer Hintergrund 13 GameObject Component 1 N Physical Visual Abbildung 2.4: Komponentenbasierte Form eines Game-Objects, bestehend aus Visual und Physical. Hierarchie und die Wiederverwendbarkeit bereits erstellter Komponenten in anderen Projekten [9]. Diese Wiederverwendbarkeit ist ein wichtiger Aspekt für das Rapid-Prototyping, weshalb für den praktischen Teil dieser Arbeit eine komponentenbasierte Game-Engine verwendet wurde. In Abb. 2.4 sieht man ein Beispiel für den komponentenbasierten Ansatz. 2.4 Rapid-Prototyping Der Begriff Rapid-Prototyping kommt ursprünglich aus der Fertigungsindustrie. Dabei handelt es sich um Herstellungsverfahren, die es ermöglichen, beliebige Musterbauteile ohne zusätzliche Werkzeuge zu produzieren. Beispiele hierfür sind 3D-Drucker oder die Stereolithografie6 . Im Bereich der Computerspielentwicklung steht Rapid-Prototyping für das schnelle Entwickeln von Prototypen. Bei diesen kann es sich um GameplayPrototypen, technische Prototypen oder User-Interface-Prototypen handeln [12, S. 618–622]: Gameplay-Prototyp: Erfüllt den Zweck, Spielelemente zu testen. Einerseits, um festzustellen ob eine Spielidee Spaß macht, andererseits zum Balancieren des Spiels [12, S. 618–622]. Technischer Prototyp: Dient der Entscheidung, ob eine gewisse Technik oder ein Algorithmus geeignet ist. Er soll auch dazu dienen, die API eines Subsystems/Moduls im Vorfeld zu definieren, damit diese im Laufe der Entwicklung überschaubar und möglichst unverändert bleibt [12, S. 619f]. User-Interface-Prototyp: Bei diesem kann es sich sowohl um einen Papierprototypen als auch um eine interaktive Applikation handeln. Ziel ist es, die Mensch–Computer-Interaktion so zu gestalten, dass die Be6 http://de.wikipedia.org/wiki/Rapid_Prototyping 2. Theoretischer Hintergrund 14 nutzeroberfläche in den Hintergrund tritt und vom Spieler nicht als störend empfunden wird [12, S. 619]. Der Grundgedanke bei allen Prototypen ist, möglichst schnell zu einem bewertbaren Ergebnis zu kommen, um schon früh im Entwicklungsprozess entscheiden zu können, ob sich eine Technik, ein Feature oder eine Spielidee eignet. Deshalb muss zu Beginn für jeden Prototypen ein klares Ziel definiert werden. Die Qualität des Codes ist dabei zweitrangig [8]. Ferner wird empfohlen, den Prototypen nicht in der Programmiersprache des eigentlichen Spiels zu schreiben, um nicht in Versuchung zu geraten, den Code des Prototypen weiter zu verwenden [12, S. 618]. Andererseits schreibt selbiger Autor über die Lebensdauer dieser Prototypen [12, S. 619]: These prototypes will live and develop with the project. For example, we would fully expect the gameplay prototype (in whatever form it may take) to develop parallel to the game itself. As new ideas are added to the game design, they should first be field tested in the game design prototype. Um diese Dualwartung (Prototyp und eigentlicher Spielcode) zu eliminieren, möchte diese Arbeit einen anderen Ansatz verfolgen: Inspiriert vom Entwicklungsprozess des Iterativen Prototyping soll untersucht werden, ob sich ein Gameplay-Prototyp als Basis für ein vollständiges Spiel eignet, wenn ein dafür ausgelegtes Framework vorliegt. Bei Iterativem Prototyping nimmt man den vorangegangenen Prototypen als Basis für einen Neuen und optimiert diesen iterativ [2, S. 226]. Der Grundaspekt des RapidPrototyping – das Verwerfen fehlgeschlagener Prototypen – bleibt bestehen. Jedoch soll im Erfolgsfall die Möglichkeit gegeben sein, auf Basis dieses Prototyps das eigentliche Spiel zu entwickeln. Eine komponentenbasierte Architektur soll hierbei unterstützend eingreifen. Kapitel 3 Übersicht von Rapid-Prototyping-Tools 3.1 Kriterien In diesem Kapitel wird ein kurzer Überblick über aktuelle Rapid-PrototypingTools und -Frameworks gegeben. Neben einer Zusammenfassung erfolgt eine Auflistung der jeweiligen Produktmerkmale, welche sich wie folgt zusammensetzt: • Dokumentation und Community: Übersicht über die vorhandene Dokumentation und Aktivität der Community. • Editor: Gibt es einen Editor, in dem man Szenen interaktiv zusammenstellen kann? • Lizenzmodelle: Verfügbare Lizenzmodelle. • Kernelemente: Enthaltene Kernelemente eines Spiels (vgl. Abschnitt 2.1). • Verfügbare Plattformen: Die Endsysteme, auf denen damit erstellte Applikationen laufen. • Entwicklungssprache: Die Programmiersprache, mit der ein Entwickler Applikationen erstellt. • Sonstige Merkmale: Produktmerkmale wie z.B. Erweiterbarkeit, programmiertechnische Sonderheiten, workflowspezifische Eigenschaften u.s.w. Sämtliche der nachfolgenden Angaben beziehen sich auf den Stand vom Frühjahr 2010. Der Fokus der präsentierten Tools liegt projektbedingt im 2DBereich. Da es auch viele 3D-Rapid-Prototyping-Tools gibt, mit denen man aber ebenfalls 2D-Spiele erstellen kann, werden die etablierteren Lösungen aus diesem Bereich angeführt. Die Auflistung der Applikationen erfolgt in alphabetischer Reihenfolge. 15 3. Übersicht von Rapid-Prototyping-Tools 16 Abbildung 3.1: Screenshot von Demo2 aus 2D Boy’s Rapid Prototyping Framework. 3.2 2D Boy’s Rapid Prototyping Framework Der Name 2D Boy ist in der Independent-Entwicklerszene eng mit dem Begriff Rapid-Prototyping verknüpft. Bekannt ist dieses Unternehmen auch durch Vorträge und Artikel über Rapid-Prototyping geworden [5]. Mitte 2009 haben sie ihr Rapid Prototyping Framework veröffentlicht. Laut eigener Aussage wurde dieses für den Prototypen von World of Goo verwendet, jedoch für die finale Version dieses Spiels manche Elemente ausgetauscht. So wurde zum Beispiel die Physiksimulation mit Hilfe der Physik-Engine Open Dynamics Engine implementiert1 . Wie in Tabelle 3.1 ersichtlich, verfügt das Framework über eine geringe Basisfunktionalität. Dokumentation ist keine vorhanden, wenn etwas dokumentiert ist, dann inline im Code. Es wird mit zwei kleinen Demos ausgeliefert. Abb. 3.1 zeigt einen Screenshot von Demo2, einen Asteroids-Klon, welcher laut Readme des Frameworks innerhalb von zwölf Stunden entstanden ist. 1 http://2dboy.com/2009/05/25/the-world-of-goo-wasn%E2%80%99t-built-in-a-day%E2%80%94-part-7-of-7 3. Übersicht von Rapid-Prototyping-Tools 17 Tabelle 3.1: Eckdaten 2D Boy’s Rapid Prototyping Framework. Dokumentation und Community Grafischer Editor Lizenzmodell(e) Verfügbare Kernelemente Plattform(en) Entwicklungssprache Sonstige Merkmale 3.3 Forum: 83 Posts Nein Public Domain Sound, Grafikausgabe (PNGs), Input (Mouse, Keyboard, Gamepad), Circle-Circle Kollisionen Windows C++ Keine Cogaen / ACES Cogaen (Component-Based Game-Engine) wird an der Fachhochschule Hagenberg entwickelt. Neben der Core kann man je nach Bedarf auf verschiedene Subsysteme zurückgreifen, welche diverse Funktionalitäten zur Verfügung stellen. So existieren zum Beispiel einzelne Subsysteme für die Grafikausgabe oder die Physikberechnung (vgl. Tabelle 3.2). ACES ist im Prinzip die C# Portierung von Cogaen, mit der Erweiterung, dass hierarchische Komponenten umgesetzt wurden2 . Der große Vorteil dieser Engine ist der subsystem- und komponentenbasierte Ansatz. Dies ermöglicht es, die Entwicklung modular zu gestalten und bereits geschriebenen Code aus vorangegangenen Projekten wieder zu verwenden, was beim Erstellen von Prototypen ein großer Vorteil ist. Eine zentrale Sammelstelle für bereits vorhandene Komponenten fehlt aber ebenso wie eine detaillierte Anwenderdokumentation. Abb. 3.2 zeigt einen Screenshot des Projekts Revive, welches mit ACES für die Xbox360 umgesetzt wurde. 3.4 Game Editor Der Game Editor von Makslane Rodrigues ist ein Multiplattform-Tool. Die Anwendung selbst läuft unter Windows und Linux, die erstellten Anwendungen laufen auch auf mobilen Endgeräten (siehe Tabelle 3.3). Sämtliche Game-Objects (im Game Editor -Jargon als Actors bezeichnet) können einer Vererbungshierarchie unterliegen. Überschriebene Methoden haben aber keinen Zugriff mehr auf die Methode der Basisklasse. Im Game Editor läuft 2 Hierarchische Komponenten haben den Vorteil, dass die Komponenten eines GameObjects hierarchisch ineinander angeordnet werden können. 3. Übersicht von Rapid-Prototyping-Tools 18 Abbildung 3.2: Screenshot von Revive, welches mit ACES für die Xbox360 umgesetzt wurde. Tabelle 3.2: Eckdaten Cogaen/ACES. Dokumentation und Community Grafischer Editor Lizenzmodell(e) Verfügbare Kernelemente Plattform(en) Entwicklungssprache Sonstige Merkmale Wiki: 108 Seiten Nein Cogaen: MIT, ACES: N/A Alle Kernelemente abgedeckt Windows, Xbox360 Je nach Port: C++, C#, Java, AS2 Modular und sehr gut erweiterbar, komponentenbasiert alles über Aktionen und Events ab. Dabei muss eine Aktion durch einen Event angestoßen werden. Die Dokumentation ist sehr detailliert: neben einem Wiki und Foren, werden auch In-Editor-Demonstrationen angeboten. Eine Schwachstelle des Game Editors ist die Kollisionserkennung, die immer per Pixel erfolgt. Je nach angestrebter Hardwareanforderung sollte diese dementsprechend vorsichtig eingesetzt werden, da es schnell zu Performanceproblemen kommen kann3 . Abb. 3.3 zeigt einen Screenshot der Benutzeroberfläche, konkret die Actor Control und den Script Editor. 3 http://game-editor.com/Collision 3. Übersicht von Rapid-Prototyping-Tools 19 Abbildung 3.3: Benutzeroberfläche des Game Editors. Tabelle 3.3: Eckdaten Game Editor. Dokumentation und Community Grafischer Editor Lizenzmodell(e) Verfügbare Kernelemente Plattform(en) Entwicklungssprache Sonstige Merkmale 3.5 Forum: 53.101 Posts Wiki: 99 Seiten Online-Handbuch In-Editor-Demonstrationen Tutorials Ja Open-Source: GPL Closed-Source: kostenpflichtig Alle Kernelemente abgedeckt (außer Physik) Windows, Pocket PC, Handheld PC, GP2X, Windows Mobile-based Smartphones and Linux Core in C/C++, eigene Scriptsprache (C-ähnlich) Erweiterbarkeit durch Source-Code gegeben, generell erstellt man Logik aber möglichst im Editor Game Maker Der Game Maker von YoYo Games richtet sich sowohl an Einsteiger, als auch an erfahrene Programmierer. Für Erstere bietet das Tool einen GUI-basierten 3. Übersicht von Rapid-Prototyping-Tools 20 Abbildung 3.4: Benutzeroberfläche des Game Makers. Weg, Spiele zu erstellen. Für erfahrene Programmierer gibt es zudem einerseits die Game Maker Language (eine eigene Skriptsprache) und andererseits auch die Möglichkeit, das Programm um eigene Bibliotheken bzw. Plugins zu erweitern. Dies wird von der Game Maker -Community sehr genutzt: So wurden „Mankos“, wie eine nicht vorhandene Physik-Engine, durch Wrapperbibliotheken bekannter Physik-Engines behoben4 . Wie in Tabelle 3.4 ersichtlich, gibt es den Game Maker in zwei verschiedenen Ausführungen: einer Lite- und einer Pro-Version. Während die Lite-Version kostenlos ist, bietet die Pro-Version gegen Entgelt mehr Features. Dokumentation ist reichlich vorhanden, auch die Community ist sehr aktiv: So hatte das Forum zum Zeitpunkt der Datenerhebung 2.240.875 Posts. Negativ aufgefallen ist, dass Game-Objects nicht hierarchisch verschachtelt werden können. So kann man im Game Maker zum Beispiel keine Feind-Basisklasse erstellen und dann konkrete Gegner davon ableiten, sondern muss sich diese immer wieder neu erstellen (Abhilfe schafft hierbei eine Duplizierfunktion). Abb. 3.4 zeigt einen Screenshot der Benutzeroberfläche des Programms. 4 Es existieren Anbindungen für z.B. Newton Game Dynamics oder NVidia PhysX. 3. Übersicht von Rapid-Prototyping-Tools 21 Tabelle 3.4: Eckdaten Game Maker. Dokumentation und Community Grafischer Editor Lizenzmodell(e) Verfügbare Kernelemente Plattform(en) Entwicklungssprache Sonstige Merkmale 3.6 Forum: 2.240.875 Posts Wiki: 821 Seiten Handbuch (292 Seiten) Tutorials Ja Lite: kostenlos Pro: mehr Features, dafür kostenpflichtig Alle Kernelemente außer Physik abgedeckt (durch Plugins aber einbindbar) Windows Engine in C++, eigene Skriptsprache im Editor (Game Maker Language) Häufig grafisch zusammenklickbar (z.B. auch Collisionevents); Erweiterbarkeit durch Extensions, Plugins und Libraries. PushButton Engine Die PushButton Engine wird von den PushButton Labs unter der MIT-Lizenz entwickelt. Diese ist eine komponentenbasierte Engine (vgl. Abschnitt 2.3) für den Adobe Flash Player, welche in ActionScript 3 geschrieben ist. Wie man in Tabelle 3.5 sieht, werden alle Kernelemente eines Spiels durch die mitausgelieferten Komponenten abgedeckt. Eine große Stärke, neben diesem komponentenbasierten Ansatz, ist sicherlich die hilfsbereite Community. Die Engine-Dokumentation befindet sich noch im Aufbau. In Abb. 3.5 sieht man einen Screenshot von Social City, einer Facebook -Applikation, welche mit der PushButton Engine realisiert wurde. Aufgrund der Anforderungen an den praktischen Teil dieser Diplomarbeit wurde für die Implementierung die PushButton Engine verwendet. Mehr Details dazu in Kapitel 4. 3.7 Torque Game Builder Der Torque Game Builder (auch Torque 2D genannt) von GarageGames richtet sich mehr an professionelle Entwickler, was sich einerseits in den verfügbaren Lizenzmodellen (vgl. Tabelle 3.6), andererseits auch in der Präsentation des Tools an sich widerspiegelt. Mit der Standard Indie-Lizenz lässt sich ein Spiel um sogenannte Bahaviors erweitern. Diese kümmern sich um die eigentliche Logik eines Spiels und können über Callbacks an Er- 3. Übersicht von Rapid-Prototyping-Tools 22 Abbildung 3.5: Screenshot aus Social City, welches mit der PushButton Engine umgesetzt wurde. Tabelle 3.5: Eckdaten PushButton Engine. Dokumentation und Community Grafischer Editor Lizenzmodell(e) Verfügbare Kernelemente Plattform(en) Entwicklungssprache Sonstige Merkmale Wiki: 18 Seiten Forum: 4.707 Posts Online-Handbuch Tutorials Nein MIT Alle Kernelemente abgedeckt Flashplayertaugliche Systeme ActionScript3 Modular und sehr gut erweiterbar; komponentenbasiert eignisse der Engine anknüpfen. Die Dokumentation ist sehr ausgeprägt: es gibt unter anderem ein Wiki mit sehr vielen vorgefertigten Behaviors, ein Online-Handbuch und diverse Tutorials. Probleme könnte man bekommen, wenn man etwas implementieren will, das von der Scripting-API nicht unterstützt wird. Hier bräuchte man Zugang zum Source-Code und müsste in diesem Fall die Lizenz erweitern. In Abb. 3.6 sieht man einen Screenshot der Benutzeroberfläche des Torque Game Builders. Interessant wird sicherlich auch Torque 2D 2011, welches in C# geschrieben sein wird5 . Dieses wird über eine direkte Integration einer Physik-Engine 5 http://www.torquepowered.com/community/blogs/view/19477 3. Übersicht von Rapid-Prototyping-Tools 23 Abbildung 3.6: Benutzeroberfläche des Torque Game Builder. Tabelle 3.6: Eckdaten Torque Game Builder. Dokumentation und Community Grafischer Editor Lizenzmodell(e) Verfügbare Kernelemente Plattform(en) Entwicklungssprache Sonstige Merkmale Wiki: 116 Seiten Forum: 59.571 Posts Online-Handbuch Tutorials Ja Diverse kostenpflichtige Möglichkeiten Alle Kernelemente abgedeckt Windows, Mac, Xbox360, Wii, iPhone C++, TorqueScript Komponentenbasiert; durch Behaviors erweiterbar (Box2D, http://www.box2d.org/) verfügen, was physikalische Spielereien zugänglicher machen sollte6 . 3.8 3D Lösungen Da auch 3D-Pakete für das Rapid-Prototyping von 2D-Spielen verwendet werden können, sollen in diesem Abschnitt die gängigsten Programme dieser Kategorie vorgestellt werden. Generell ist hier anzumerken, dass die großen 6 http://www.torquepowered.com/community/blogs/view/19347 3. Übersicht von Rapid-Prototyping-Tools 24 Tabelle 3.7: Eckdaten ShiVa. Dokumentation und Community Grafischer Editor Lizenzmodell(e) Verfügbare Kernelemente Plattform(en) Entwicklungssprache Sonstige Merkmale Wiki: 99 Seiten Forum: 22.731 Posts API-Dokumentation ShiVa-Buch Tutorials Ja PLE: kostenlos Advanced & Unlimited: mehr Features, dafür kostenpflichtig Alle Kernelemente abgedeckt Windows, Mac, Linux, Webplayer, Wii, iPhone, Android, PalmOS Scripting in LUA, auch C++ möglich Komponentenbasiert; durch Scripting erweiterbar, einmal entwickeln – auf allen Systemen publizieren Game-Engine-Hersteller in letzter Zeit dazu tendieren, Gratisversionen ihrer jeweiligen Engine zu veröffentlichen. So wurden im Herbst 2009 nahezu zeitgleich jeweils eine kostenlose Version der Unity (siehe Abschnitt 3.8.2) und der Unreal Engine (siehe Abschnitt 3.8.3) publiziert. Zum Zeitpunkt des Verfassens dieser Arbeit hat auch Crytek angekündigt, an einer Gratisversion der Cry Engine 3 zu arbeiten7 . 3.8.1 ShiVa ShiVa von Stonetrip ist in drei Versionen verfügbar: einer kostenlosen Personal Learning Edition (PLE) und den zwei kostenpflichtigen Varianten Advanced und Unlimited. Letztere unterscheiden sich in der Anzahl an Features. Source-Code-Lizenzen des Tools werden standardmäßig nicht angeboten. Die Dokumentation erfolgt sehr detailliert in Form von API-Dokumentation, Wiki, Tutorials und einem ShiVa-Buch. Ein Hauptmerkmal von ShiVa ist sicherlich das ShiVa Authoring Tool: Mit diesem ist es möglich, ein Spiel für sämtliche unterstützten Plattformen (vgl. Tabelle 3.7) zu erstellen. In Abb. 3.7 sieht man einen Screenshot der Benutzeroberfläche des ShiVa Authoring Tools. Leicht unübersichtlich gestaltet sich die Undo-Funktionalität des Tools: Es gibt keinen konkreten Undo-Button (funktioniert nur über CTRL+Z) und man bekommt kein Feedback, wenn es für das aktuelle Editorfenster keine Undo-Funktionalität gibt. 7 http://www.develop-online.net/news/34466/Free-to-use-CryEngine-plans-emerge 3. Übersicht von Rapid-Prototyping-Tools 25 Abbildung 3.7: Benutzeroberfläche des ShiVa Authoring Tools. 3.8.2 Unity Seit Herbst 2009 gibt es eine Gratisversion der Unity-Engine (ehemals Unity Indie). Dabei handelt es sich um eine vorkompilierte und leicht an Features reduzierte Version der Unity Pro. Wie man aus Tabelle 3.8 entnehmen kann, bietet Unity die Möglichkeit, in drei verschiedenen Sprachen Scripte zu erstellen. Es gibt sehr viele Script-Erweiterungen von der Community, die in einer eigenen Script-Sektion im Wiki gesammelt werden. Die Dokumentation in Form von Wiki, Online-Handbuch und Tutorials ist ebenfalls sehr ausgereift. Als besondere Features der Engine hervorzuheben ist einerseits die sehr komfortable Assetpipeline, welche zum Beispiel native 3d Studio Max -Dateien verarbeiten kann und somit Zwischenformate für den Grafiker überflüssig macht, und andererseits der Unity Webplayer, der für “alle modernen Webbrowser“ 8 verfügbar ist. In Abb. 3.8 sieht man einen Screenshot der Benutzeroberfläche von Unity. Negativ anzumerken ist, dass die drei möglichen Scriptsprachen auch in der Community zum Einsatz kommen. So muss ein Entwickler unter Umständen immer zwischen den verschiedenen Sprachen hin- und herwechseln, was sicherlich den Workflow bremst. 8 Laut Unity-Homepage sind dies der Internet Explorer, FireFox und Safari. 3. Übersicht von Rapid-Prototyping-Tools 26 Abbildung 3.8: Benutzeroberfläche von Unity. Tabelle 3.8: Eckdaten Unity. Dokumentation und Community Grafischer Editor Lizenzmodell(e) Verfügbare Kernelemente Plattform(en) Entwicklungssprache Sonstige Merkmale 3.8.3 Wiki: 399 Seiten Forum: 313.511 Posts Online-Handbuch Tutorials Ja Free: kostenlos Pro: mehr Features, dafür kostenpflichtig Alle Kernelemente abgedeckt Windows, Mac, Webplayer, Wii, iPhone Scripting in JavaScript, C# und Boo möglich Komponentenbasiert; durch Scripting erweiterbar, komfortable Assetpipeline Unreal Development Kit Die Unreal Engine 3 von Epic Games gehört seit Jahren zu den am weitest verbreiteten Game-Engines9 . Seit Herbst 2009 bietet Epic Games das Unreal Development Kit (UDK) an. Dabei handelt es sich um eine voll funktionsfähige Version der Unreal Engine 3, welche in vorkompilierter Form verfügbar ist. Zugang zum Source-Code der Engine wird nicht gestattet. Die Lizenzmodelle sind in Tabelle 3.9 ersichtlich. Besonders hervorzuheben ist, dass das UDK für nahezu jeden Bereich einen eigenen grafischen Editor hat. In Abb. 3.9 sieht man neben der Benutzeroberfläche des Unreal Editors auch 9 http://en.wikipedia.org/wiki/List_of_Unreal_Engine_games 3. Übersicht von Rapid-Prototyping-Tools 27 Abbildung 3.9: Benutzeroberfläche des Unreal Editors. Rechts im Vordergrund: das Kismet -Fenster für visuelles Scripting. Tabelle 3.9: Eckdaten Unreal Development Kit. Dokumentation und Community Grafischer Editor Lizenzmodell(e) Verfügbare Kernelemente Plattform(en) Entwicklungssprache Sonstige Merkmale Wiki (Seitenzahl nicht ermittelbar) Forum: 51.214 Posts Tutorials Ja Gratis für nicht kommerzielle Spiele Verschiedene Optionen für kommerziellen Einsatz Alle Kernelemente abgedeckt, auch Künstliche Intelligenz Windows Scripting in UnrealScript Durch Scripting erweiterbar; visuelles Scripting; Es gibt für nahezu jeden Bereich einen Editor das Kismet -Fenster für visuelles Scripting. Die Dokumentation ist in Form des Unreal Development Networks sehr ausgeprägt vorhanden. In diesem finden sich neben schriftlichen Tutorials auch Videotutorials und eine handvoll Demoapplikationen samt Source-Code und zugehöriger Projektdokumentation. 3. Übersicht von Rapid-Prototyping-Tools 28 Abbildung 3.10: Benutzeroberfläche von Quest3D. 3.8.4 Quest3D Quest3D ermöglicht es, sämtliche Logikabfolgen rein grafisch zu programmieren. Es basiert auf sogenannten Channels und Nodes, die man miteinander verbindet. Alternativ kann man auch LUA-Scripte erstellen. Über ein SDK hat man zudem die Möglichkeit, neue Node-Klassen zu schreiben, wenn die Scripting-Funktionalität nicht mehr ausreicht. Wie in Tabelle 3.10 ersichtlich, werden in der Basisform von Quest3D alle Kernelemente eines Spiels abgedeckt. Auch Pathfinding und eine Finite-State-Machine sind inkludiert. Für Programmierer sicher ungewöhnlich ist die Tatsache, dass sich diese Node-basierte Programmierung bis in die tiefste Hierarchiestufe durchzieht: So muss man z.B. einen 3D-Vektor aus einem Vektor-Node und drei ZahlenNodes zusammenbauen. Auch wenn primär für Visualisierungen verwendet, so wurden mit Quest3D bereits einige Spiele umgesetzt10 . In Abb. 3.10 sieht man einen Screenshot der Benutzeroberfläche von Quest3D. 3.9 Fazit der vorgestellten Rapid-Prototyping-Tools Stellt man nun die präsentierten Rapid-Prototyping-Tools einander gegenüber, so lassen sich folgende Merkmale identifizieren, die ein ideales Tool ausmachen: Architektur: Die zugrundeliegende Architektur der Game-Engine sollte so 10 Siehe Showcase-Sektion der Quest3D-Homepage: http://quest3d.com/index.php? id=209 3. Übersicht von Rapid-Prototyping-Tools 29 Tabelle 3.10: Eckdaten Quest3D. Dokumentation und Community Grafischer Editor Lizenzmodell(e) Verfügbare Kernelemente Plattform(en) Entwicklungssprache Sonstige Merkmale Wiki: 539 Seiten Forum: 87.019 Posts Tutorials Knowledgebase (Sammlung von Erweiterungen) Ja Diverse kostenpflichtige Möglichkeiten Alle Kernelemente abgedeckt, auch Künstliche Intelligenz Windows, Webplayer LUA (Scripting), C++ (Plugins) Node/Channel basiert (grafische Programmierung); Durch Scripting und Plugins erweiterbar flexibel sein, dass es dem Benutzer möglich ist, Teile der Game-Engine auszutauschen oder diese um eine eigene Funktionalität erweitern zu können, wie z.B. der Anbindung einer anderen Physik-Engine oder der Implementierung von eigenen Schattenberechnungsalgorithmen. GUI-basiert: Eine grafische Benutzeroberfläche erhöht die Produktivität, wenn diese sinnvoll angeordnet und mit allen benötigten Features ausgestattet ist. Ein weiterer Vorteil ist, dass man nicht zwangsläufig programmieren können muss, um mit dem Programm zu arbeiten. Die oben angeführten Faktoren sollen bei der Planung des im Rahmen dieser Arbeit entwickelten Rapid-Prototyping-Tools berücksichtigt werden. Kapitel 4 Entwurf und Implementierung 4.1 Ausgangssituation Der praktische Teil dieser Diplomarbeit entstand in Kooperation mit der Broken Rules Interactive Media GmbH 1 (Broken Rules). Es sollte ein Tool entwickelt werden, mit dem man möglichst einfach verschiedene GameplayPrototypen erstellen kann: der Level Master 2000 (LM2k ). Ferner sollte im Falle einer positiven Beurteilung eines Gameplay-Prototyp ein finales Spiel daraus entstehen können. Um dies zu erreichen, wurden die zwei Säulen des LM2k wie folgt definiert (u.a. unter Berücksichtigung der Erkenntnisse aus Abschnitt 3.9): Architektur der Game-Engine: Game-Objects sollen möglichst flexibel gestalt- und erweiterbar sein. Um dies zu erreichen wurde beschlossen, eine komponentenbasierte Architektur zu verwenden (siehe Abschnitt 2.3.4). Mit der Zeit soll eine Komponenten-Datenbank aufgebaut werden. So verkürzt sich die Entwicklungszeit für neue Prototypen stetig, da bereits vorhandene Komponenten wiederverwendet werden können. Das Entwickeln von Prototypen soll auch ohne zweiter Säule (Editor) funktionieren. Editor: Dieser soll beim Zusammenstellen der Spielszene unterstützend eingreifen. Game-Objects werden im Editor aus den bereits geschriebenen Komponenten erstellt. Wenn alle benötigten Komponenten vorhanden sind, soll es im Idealfall möglich sein, Prototypen bzw. Spiele zu entwickeln ohne zusätzlich programmieren zu müssen. Der Anwender muss also nicht zwingend über Programmierkenntnisse verfügen. Bei der Erstellung des User-Interfaces sollen die 10 Usability Heuristiken von Nielsen so weit wie möglich berücksichtigt werden (vgl. [10, S. 115–164]). 1 http://brokenrul.es/ 30 4. Entwurf und Implementierung 4.2 31 Festlegungen Um die Anforderungen an das Projekt konkretisieren zu können, wurden nach einer ersten Recherchephase, nachstehende Festlegungen getroffen: Beschränkung auf 2D: Die meisten Spielideen lassen sich auf 2D-Gameplay beschränken. 3D bedeutet meist einfach mehr Aufwand bei gleichbleibendem Spielspaß und kann somit vernachlässigt werden. Adobe Flash: Die jeweiligen Prototypen sollen der Broken Rules-Community zum Testen bereitgestellt werden. Um dies zu erreichen, fiel die Wahl auf Adobe Flash, da dies plattformübergreifend verfügbar, einfach über den Webbrowser verwendbar und sehr weit verbreitet ist2 . Verwendung einer Game-Engine: Es wurde vereinbart – wenn möglich – eine Flash-Game-Engine zu verwenden, auf die der LM2k aufbaut. Jedoch musste diese eine komponentenbasierte Architektur aufweisen und über ein Lizenzmodell verfügen, welches den kommerziellen Einsatz erlaubt, ohne den Source-Code freigeben zu müssen. Im Zuge der Recherche fiel die Wahl auf die PushButton Engine (siehe Abschnitt 3.6), welche unter der MIT-Lizenz publiziert ist. GUI System: Die GUI des Editors wurde mit Qt 3 realisiert. Qt ist ein in C++ geschriebenes, plattformübergreifendes Applikations- und UserInterface-Framework. Flash hat zwar mit Flex ein sehr mächtiges GUISystem, Ben Garney (Chefentwickler der PushButton Engine) meinte aber in einem persönlichen Gespräch, dass die PushButton Labs an einen Editor mit einer auf Flex -basierten GUI gearbeitet hatten, diesen aber aus Gründen der Performance einstellen mussten. Wie nun die Qt-GUI (C++) mit Flash (ActionScript ) kommuniziert, ist in Abschnitt 4.3 beschrieben. Plattformunabhängigkeit: Bei Broken Rules werden PCs und MACs zur Entwicklung eingesetzt. Deshalb ist es wünschenswert, dass der Editor auch auf beiden Systemen läuft. Mit der Verwendung von Flash und Qt ist dies gewährleistet. Multi-Monitorunterstützung: Da typischerweise zwei Monitore gleichzeitig verwendet werden, wurde es als nice-to-have definiert, mehrere Monitore zu unterstützen. Mit der Verwendung von Qt ist dies vernünftig möglich, da native Betriebssystemfenster erstellt werden können. Dies ermöglicht es dem Benutzer, einzelne Fenster vom Hauptfenster loszulösen und so frei zu positionieren4 . 2 Laut Eigenaussage von Adobe hat der Flash Player eine Verbreitung von 99 %. Quelle: http://www.adobe.com/products/player_census/flashplayer/ 3 Version 4.6, http://qt.nokia.com/ 4 Mit einer rein Flash-basierten GUI müssen sich alle Elemente im Flash-Container befinden, es sei denn man verwendet Adobe Integrated Runtime (AIR). 4. Entwurf und Implementierung 32 View-Control C++/Qt Model Benutzer ActionScript PushButton Engine Abbildung 4.1: Kernarchitektur des Level Master 2000. Undo-/Redo-System: Um mit dem LM2k effizient arbeiten zu können, wurde es als unerlässlich angesehen, dass Benutzereingaben rückgängig gemacht werden können. Abschnitt 4.5.4 befasst sich näher mit dem Undo-/Redo-System. 4.3 Grundlegende Architektur Der LM2k basiert im Grunde auf dem Model-View-Control-Pattern (MVC). Dieses ist ein Software-Design-Pattern, welches eine flexible Architekur durch die Trennung in Darstellung, Logik und Daten ermöglicht [6, S. 4ff]. Wie in Abb. 4.1 ersichtlich, wurden jedoch die View und die Control zusammengefasst. Die View-Control unterteilt sich technischbedingt ferner in einen C++/Qt - und einen ActionScript -Teil. Das Model entspricht der PushButton Engine. Zunächst werden die einzelnen Teile und deren Funktionalität näher erläutert. Wie diese nun konkret miteinander kommunizieren, ist in Abschnitt 4.3.3 beschrieben. Auf die einzelnen Kernelemente des LM2k wird in Abschnitt 4.5 näher eingegangen. Ein abschließendes Resümee über die gewählte Architektur findet sich in Abschnitt 6.2.1. 4.3.1 View-Control C++/Qt-Teil Der C++/Qt -Teil ist hauptsächlich für die Frontend-GUI verantwortlich. Da Qt ebenfalls das MVC-Pattern implementiert, bietet es sich an, Teile der Logik mit Qt zu realisieren. Wenn möglich, werden Eingabefehler gleich hier erkannt und behandelt, bevor diese an den ActionScript -Teil übermittelt werden (und in weiterer Folge an die PushButton Engine). Auch ist der 4. Entwurf und Implementierung 33 Großteil der Editorlogik, wie z.B. ein Undo-/Redo-Mechanismus, in diesem Teil implementiert. Wenn es verlangt wird, könnte man performancelastige Vorgänge von ActionScript in C++ auslagern und die Ergebnisse danach erneut retournieren. Auch wäre es denkbar, externe Tools oder Bibliotheken, wie z.B. einem Sprite-Sheet-Generator, einzubinden. Ein explizites Pluginsystem für solche Zwecke wurde aber nicht vorgesehen. ActionScript-Teil Der ActionScript -Teil stellt einerseits die Verbindung zwischen der ViewControl und dem Model her, andererseits ist er auch für Flash-bezogene Editorfunktionalität, wie z.B. dem Selektieren von Objekten mit der Maus im Viewport, verantwortlich. Wenn nötig, wird hier auch auf mögliche Eingabefehler reagiert. 4.3.2 Model Das Model ist die PushButton Engine. Diese ist ein zentrales Element des LM2k und wurde von Anfang an bei der Planung der Architektur berücksichtigt. Um die PushButton Engine voll ausreizen zu können, wurde bewusst darauf verzichtet, eine Engine-Abstraktionsebene einzuführen. So konnte auf Engine-spezifische Eigenschaften eingegangen werden, wie: • Unterstützung von Component References, mit denen man auf andere Komponenten zugreifen kann. • Unterstützung von Property References, mit denen man auf einzelne Variablen einer anderen Komponente zugreifen kann. • Implementierung eines „intelligenten“ Transformations-Gizmos, der im Falle einer Transformation, je nach vorkommender TransformationsKomponente, sein Verhalten ändert (siehe Abschnitt 4.5.7). • Ein (geplanter) Template Editor, mit dem man PushButton Engine Templates erstellen kann (siehe Abschnitt 4.5.8). Ein weiterer Grund für diese Entscheidung war die Annahme, dass die PushButton Engine die richtige Wahl für dieses Tool ist und ein nachträglicher Austausch nicht in Frage kommt. 4.3.3 Kommunikation zwischen den einzelnen Applikationsteilen Um den Kommunikationsablauf besser nachvollziehen zu können, sollten das Qt Object Model, die Qt QWebview und das External Interface von Flash vertraut sein. Diese werden nachstehend erklärt. 4. Entwurf und Implementierung 34 connect(Object1, signal1, Object2, slot1) Object1 connect(Object1, signal1, Object2, slot2) signal1 signal2 Object2 signal1 slot1 slot2 Object3 connect(Object1, signal2, Object4, slot1) signal1 Object4 slot1 slot1 slot2 slot3 connect(Object3, signal1, Object4, slot3) Abbildung 4.2: Qt ’s Signal - und Slotsystem: Signale können mit Slots verknüpft werden. Quelle: Qt -Dokumentation. Qt Object Model Ein QObject hat die Möglichkeit, Signals, Slots oder Properties zu definieren. Signals und Slots: Signals und Slots ermöglichen die Kommunikation zwischen QObjects. Wenn also ein QObject ein anderes QObject über eine Zustandsänderung informieren will, sendet es ein Signal aus, welches von den damit verbundenen Slots verarbeitet wird. Ein Signal kann dabei mit beliebig vielen Slots beliebig vieler QObjects verbunden werden. Signale werden wie ein Funktionsaufruf sofort ausgeführt, verfügen aber über keinen Rückgabewert [11, Signals and Slots]. Eine grafische Darstellung des Signal - und Slot-Prinzips zeigt Abb. 4.2. Properties: Properties verhalten sich wie normale Klassenvariablen, erhalten aber durch das Qt Meta-Object System zusätzliche Funktionalität. Vereinfacht formuliert handelt es sich dabei um Klassenvariablen, denen man Getter- und Setter-Methoden zuweisen kann, ähnlich den Accessors in ActionScript oder Properties von C# 5 [11, Qt’s Property System]. 5 Das Qt Property System bietet weitaus mehr Funktionalität, für das Verständnis des Kommunikationsablaufes ist dies aber nicht von Relevanz. 4. Entwurf und Implementierung 35 QWebview Die QWebview ist ein Bestandteil des WebKit -Moduls6 von Qt, mit dem man Webseiten laden und verändern kann. So kann man QObjects dem JavaScript der geladenen Seite zur Verfügung stellen und dann im JavaScript auf diese Objekte zugreifen. Dabei werden Slots als Javascript-Methoden und Properties als JavaScript-Properties exponiert. Auch ist es möglich, von C++ aus konkrete JavaScript-Methoden aufzurufen. External Interface Das External Interface erlaubt die Kommunikation zwischen ActionScript und dem Flash Player-Container [1]. Dieser ist im Falle des LM2k eine HTML-Seite mit JavaScript, welche mittels QWebView geladen wurde. Kommunikationsablauf Die Kommunikation zwischen dem C++- und dem ActionScript -Teil der View-Control erfolgt mithilfe einer Communicator-Klasse. Diese ist auf beiden Seiten existent und empfängt, verarbeitet und versendet Kommandos. Ein Kommando entspricht dabei einem XML-String. Ein konkretes Kommando zeigt Prog. 4.1. Die Communicator-Klasse auf der ActionScript -Seite greift nach Verarbeitung eines Kommandos auf das Model respektive die PushButton Engine zu. Ausgehend von der C++-Seite, durchläuft ein XMLKommando folgende Stationen: 1. Die Communicator-Klasse (C++) erzeugt ein Kommando. 2. Die Communicator-Klasse (C++) ruft über QWebView eine JavaScriptFunktion auf und übergibt das Kommando. 3. Diese JavaScript-Funktion kommuniziert über ExternalInterface mit Flash und reicht das Kommando an ActionScript weiter. 4. Die Communicator-Klasse (ActionScript ) interpretiert das Kommando und ruft die dazugehörigen ActionScript -Funktionen auf. 5. Über diese Funktionen wird auf das Model (PushButton Engine) zugegriffen. 6. Optional sendet das Kommando eine Antwort über den neuen Status zurück. In die andere Richtung (ActionScript zu C++) funktioniert die Kommunikation nach demselben Prinzip. Mehr Details zum Datenfluss im nächsten Abschnitt. 6 QtWebKit ist eine Portierung des WebKit-Projektes – einer opensource WebbrowserEngine, die u.a. von Google Chrome, Apple Safari oder auch Adobe Integrated Runtime (AIR) verwendet wird. 4. Entwurf und Implementierung 36 Programm 4.1: Beispiel eines XML-Kommando-Strings. 1 <command type="selectEntities"> 2 <entities> 3 <entity name="Game"/> 4 <entity name="Player"/> 5 </entities> 6 </command> 4.4 Datenfluss anhand konkreter Beispiele Um einen besseren Einblick in die Architektur bzw. den Kommunikationsablauf zu bekommen, wird in diesem Abschnitt der Datenfluss anhand von drei Beispielen skizziert: • Dem Start der Applikation, • dem Selektieren einer Entität • und dem Ändern einer Eigenschaft durch den Property Browser. 4.4.1 Start der Applikation Beim Start des LM2k (siehe Abb. 4.3) wird zuerst die GUI auf der C++Seite initialisiert. Danach wird der ActionScript -Teil (Editor-SWF ) geladen. Dieser wiederum lädt die SWF -Datei, in der sich das PushButton EngineSpiel befindet. Ist das Spiel geladen, wird es zur Stage der Editor-SWF hinzugefügt. Nun werden sämtliche Komponentendaten und die Editorobjekte des ActionScript -Teils erstellt. Im Anschluss daran werden die Komponentendaten an den C++-Teil übermittelt. Der benötigt diese, um z.B. den Component Browser (siehe Abschnitt 4.5.6) mit Inhalt füllen zu können. Ist alles initialisiert, kann der Benutzer ein Level über den Level Manager (siehe Abschnitt 4.5.1) laden. 4.4.2 Selektieren einer Entität Selektiert man eine Entität im Viewport, so wird vom ActionScript -Teil ein Selection Request -Befehl an den C++-Teil gesendet. Dieser prüft, ob die Entität existiert und erstellt im Erfolgsfall einen Select Entity-Befehl, welcher auf den Undo-Stack gelegt wird. Danach sendet der C++-Teil einen Select Entity-Befehl an den ActionScript -Teil. Dieser selektiert nun ebenfalls die Entität und sendet deren Daten zurück an den C++-Teil, damit dieser sie visualisieren kann. Selektiert man eine Entität direkt im Entity Explorer (siehe Abschnitt 4.5.2), so fällt der erste Schritt – der Selection Request – weg. Abb. 4.4 zeigt den Ablauf beim Selektieren einer Entität. 4. Entwurf und Implementierung C++ Initialization Of Qt Widgets 37 ActionScript PushButton Engine (PBE) Ed Loa ito d rS W F On Added To Stage Lo Ga ad me PB SW E F ing d e ad Lo plet m o C Initialize PBE Add PBE Game To Stage Generate Schema Build Component Information en on mp tion o C ma r nd Se Info t Init Editor Objects Update Widgets With Data Ready To Load Level Abbildung 4.3: Kommunikationsablauf beim Starten der Applikation. 4.4.3 Ändern einer Eigenschaft durch den Property Browser Um mit dem Property Browser (siehe Abschnitt 4.5.3) Eigenschaften einer Entität ändern zu können, muss diese selektiert sein. Wird ein Wert geändert, erstellt der C++-Teil einen Update Property-Befehl und sendet die Daten an den ActionScript -Teil. Dieser sucht sich die Komponenten der selektierten Entität und aktualisiert den Wert der Eigenschaft. Abb. 4.5 zeigt den Ablauf beim Ändern einer Eigenschaft durch den Property Browser. 4. Entwurf und Implementierung C++ 38 ActionScript PushButton Engine (PBE) On Mouse Click Get Renderers Under Point est qu y Re ntit d E n Se lect Se Select Entity Command S lec end tE nt it Se y Select Entity nd ta Se Da ity nt E Update Widgets With Data Abbildung 4.4: Selektieren einer Entität. C++ ActionScript PushButton Engine (PBE) Value Changed Update Property Command Up da Send te Pr op e rty Update Property Lookup Entity Lookup Component Abbildung 4.5: Ändern einer Eigenschaft durch den Property Browser. 4. Entwurf und Implementierung 39 Abbildung 4.6: Die Benutzeroberfläche: Level Manager (1), Flash-Szene (2), Entity Explorer (3), Property Browser (4) und Log View (5). 4.5 Kernelemente im Detail In diesem Abschnitt näher wird auf die einzelnen Kernelemente eingegangen. Abb. 4.6 zeigt die Benutzeroberfläche des LM2k : Level Manager (1), FlashSzene (2), Entity Explorer (3), Property Browser (4) und Log View (5). Der Großteil der GUI-Elemente sind dockable Widgets, die vom Hauptfenster losgelöst oder an anderen Stellen angedockt werden können. Der Benutzer kann somit das Layout der Fenster frei und nach seinen Bedürfnissen einstellen. 4.5.1 Projektverwaltung Das eigentliche PushButton Engine-Spiel muss sich im AS3/bin-Verzeichnis des LM2k befinden und wird zur Laufzeit vom ActionScript -Teil des Editors geladen. Somit bleibt das Spiel vom Editor unabhängig und kann auch ohne diesen gestartet werden. Das Workspace-Verzeichnis des LM2k ist zugleich das Asset-Verzeichnis des PushButton Engine-Spiels. Dies gewährleistet, dass immer mit den gleichen Daten arbeitet werden kann und diese auch nur einmal auf der Festplatte gespeichert sein müssen. Der Level Manager interpretiert die PushButton Engine-Levelbeschreibungen und verwaltet die einzelnen Levels. Einen Screenshot der Benutzeroberfläche des Level Managers zeigt Abb. 4.7. 4. Entwurf und Implementierung 40 Abbildung 4.7: Screenshot des Level Managers. Entity Explorer Property Browser Abbildung 4.8: Screenshot des Entity Explorers und des Property Browsers. 4.5.2 Entity Explorer Mit dem Entity Explorer verwaltet man sämtliche in der Szene vorkommenden Entitäten und Gruppen von Entitäten. Man kann diese selektieren, neue erstellen, vorhandene bearbeiten oder löschen. Hat man eine Entität ausgewählt, werden alle ihre Komponenten angezeigt. Über den Entity Explorer kommt man auch zum Component Browser (siehe Abschnitt 4.5.6) für die Erstellung neuer Komponenten. Einen Screenshot der Benutzeroberfläche des Entity Explorers zeigt Abb. 4.8. 4. Entwurf und Implementierung 4.5.3 41 Property Browser Mit dem Property Browser kann man die Eigenschaften von Komponenten darstellen und manipulieren. Basierend auf dem QtPropertyBrowser 7 , mussten jedoch ein paar Änderungen durchgeführt werden, um mit dem Undo/Redo-System (siehe Abschnitt 4.5.4) kompatibel zu werden: So wurden zum Beispiel die Signale dahingehend umgeschrieben, dass diese neben dem neuen auch den alten Wert mitübertragen. Einen Screenshot der Benutzeroberfläche des Property Browsers zeigt Abb. 4.8. 4.5.4 Undo-/Redo-System Sämtliche Aktionen im Editor sind reversibel. Zu diesem Zweck verwendet das Undo-/Redo-System Qt’s Undo Framework, welches wiederum das Command-Pattern implementiert [6, S. 233–242]. Alle Commands werden auf einen Undo-Stack gelegt und bei Bedarf wieder von diesem entfernt. Es wurden folgende Commands benötigt: • • • • • • • • Create Component: Fügt einer Entität eine Komponente hinzu. Create Entity: Erzeugt eine Entität. Create Group: Erzeugt eine Gruppe. Delete Component: Löscht eine Komponente einer Entität. Delete Entity: Löscht eine Entität. Delete Group: Löscht eine Gruppe. Property Change: Ändert den Wert einer Komponente. Select Components: Selektiert eine, mehrere oder keine Komponente(n). • Select Entities: Selektiert eine, mehrere oder keine Entität(en). 4.5.5 Log View Die Log View ist hauptsächlich als Entwicklungswerkzeug zu sehen und dient dem Überblick über den aktuellen Systemzustand. Sie stellt sowohl die Nachrichten des C++-Teils, als auch die des ActionScript -Teils und der PushButton Engine dar. Neben den etablierten Log-Stufen Nachricht, Warnung und Fehler gibt es auch noch die Stufe Debug. Bei dieser handelt es sich um ActionScript -Anweisungen, die zum Debuggen des ActionScript -Teils verwendet werden können8 . Man kann sämtliche Log-Stufen zu- und abschalten. Zusätzlich zur Anzeige auf dem Bildschirm werden alle Nachrichten in einer Datei abgespeichert. 7 QtPropertyBrowser von QtSolutions, siehe http://qt.nokia.com/products/appdev/addon-products/catalog/4/Widgets/qtpropertybrowser/ 8 Aufgrund der Aufteilung der View-Control in C++- und ActionScript-Teil wird das Debugging erschwert, da immer nur ein Teil auf einmal debugged werden kann (siehe Abschnitt 6.2.1). 4. Entwurf und Implementierung 42 Abbildung 4.9: Screenshot des Component Browsers. 4.5.6 Component Browser Der Component Browser zeigt alle verfügbaren Komponentenklassen. Hat man eine Entität selektiert, kann man ihr die im Component Browser ausgewählte Komponente hinzufügen. Die nötigen Informationen bekommt der Component Browser beim Starten der Applikation. Dies erfolgt mit Hilfe der SchemaGenerator-Klasse der PushButton Engine, welche alle registrierten Komponenten durchläuft und die Information über die einzelnen Klassen über eine Callback-Methode an den C++-Teil bzw. den Component Browser weiterleitet. Einen Screenshot der Benutzeroberfläche des Component Browsers zeigt Abb. 4.9. Mehr zum Datenfluss beim Starten der Applikation siehe Abschnitt 4.4.1. 4.5.7 Transformations-Gizmo Mit dem Transformations-Gizmo kann man Entitäten translieren, rotieren oder skalieren. Es wird dabei versucht, „intelligent“ vorzugehen: Verfügt die Entität über eine IMobileSpatialObject2D-Komponente9 , so werden die Werte dieser Komponente manipuliert. Ist sie nicht verfügbar, wird geprüft, ob eine DisplayObjectRenderer-Komponente existiert. Ist dies der Fall, werden die Werte dieser Komponente verändert. 4.5.8 Template Editor Die PushButton Engine unterstützt sogenannte Templates. Templates sind Baupläne für Entitäten, die beim Template Manager registriert und über diesen instanziert werden können. Sie können entweder direkt in ActionScript 9 Das Interface IMobileSpatialObject2D stellt Variablen für Position, Rotation und Größe zur Verfügung. 4. Entwurf und Implementierung 43 Abbildung 4.10: Screenshot des Template Editors. oder per XML definiert werden. Ein Beispiel für ein XML-Template sieht man in Programm 4.2. Dieses definiert ein Physikobjekt (Box2DSpatialComponent) und eine Grafik (SpriteSheetRenderer). Die Transformation (Position, Rotation und Größe) der Grafik ist dabei an die des Physikobjektes gekoppelt (positionProperty, rotationProperty und sizeProperty). Der Template Editor soll den Entwickler dabei unterstützen, PushButton Engine Templates zu erstellen. Einen Screenshot der Benutzeroberfläche des Template Editors zeigt Abb. 4.10. Dieser existierte zum Zeitpunkt des Verfassens der Arbeit nur in Form eines GUI-Prototyps. Der Workflow verläuft wie folgt (von links nach rechts): 1. Zuerst wählt man die Komponenten des Templates aus. 2. Im zweiten Schritt benennt man die Komponenten. 3. Im dritten Schritt stellt man die Standardwerte der einzelnen Variablen der Komponenten ein. Auch kann man hier angeben, ob eine Eigenschaft für den Anwender editierbar sein soll oder nicht. LM2k -spezifische Metadaten, wie die Sichtbarkeit einer Eigenschaft, müssen vom LM2k verwaltet werden und können nicht in dem eigentlichen PushButton Engine Template abgespeichert werden. 4. Entwurf und Implementierung 44 Programm 4.2: Beispiel eines PushButton Engine Templates. 1 <things version="1"> 2 <template name="Platform"> 3 <component type="com.pblabs.box2D.Box2DSpatialComponent" name=" 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 Spatial"> <canMove>false</canMove> <canRotate>false</canRotate> <collidesWithTypes childType="String"> <_0>Dude</_0> </collidesWithTypes> <collisionShapes childType="com.pblabs.box2D.CollisionShape"> <_0 type="com.pblabs.box2D.PolygonCollisionShape"> <vertices childType="flash.geom.Point"> <_0 type=""><x>-1</x> <y>-1</y></_0> <_1 type=""><x>+1</x> <y>-1</y></_1> <_2 type=""><x>+1</x> <y>+1</y></_2> <_3 type=""><x>-1</x> <y>+1</y></_3> </vertices> </_0> </collisionShapes> <collisionType childType="String"> <_0>Platform</_0> <_1>Renderable</_1> </collisionType> <spatialManager componentReference="SpatialDB"/> <size type=""> <x>256</x> <y>64</y> </size> </component> <component type="com.pblabs.rendering2D.SpriteSheetRenderer" name=" Render"> <positionProperty>@Spatial.position</positionProperty> <rotationProperty>@Spatial.rotation</rotationProperty> <sizeProperty>@Spatial.size</sizeProperty> <spriteSheet componentReference="PlatformSpriteSheet"/> <scene componentReference="Scene"/> </component> </template> </things> Kapitel 5 Ergebnisse Um die Möglichkeiten des LM2k zu demonstrieren, wurden drei Prototypen für folgende Genres entwickelt: 1. Jump-and-Run, 2. Racing und 3. Space-Shooter. Diese wurden bewusst so gewählt, dass die einzelnen Genres möglichst unterschiedlich sind. Es folgt jeweils eine Beschreibung des Funktionsumfanges des Prototyps als auch eine Beschreibung der benötigten Entitäten und deren Komponenten-Zusammensetzung. Eine detaillierte Übersicht über alle verwendeten Komponenten findet sich in Anhang A. 5.1 Jump-and-Run-Demo Die Jump-and-Run-Demo stellt die Grundfunktionen für ein Jump-and-RunSpiel bereit. Dies beinhaltet u.a.: • Die Steuerung des Spielcharakters, • Plattformen, auf denen sich der Spieler bewegen kann und • Trigger, die beim Betreten bestimmte Events auslösen (seien es z.B. das Abziehen von Lebenspunkten oder das Erstellen neuer Gegner). Einen Screenshot der Jump-and-Run-Demo zeigt Abb. 5.1. 5.1.1 Vorkommende Entitäten Scene Die Scene beinhaltet alle Komponenten, die für die Verwaltung der Spielszene relevant sind und setzt sich wie folgt zusammen: 45 5. Ergebnisse 46 Abbildung 5.1: Screenshot der Jump-and-Run-Demo. Box2DManagerComponent: Verwaltet die Physikobjekte. DisplayObjectScene: Verwaltet die Grafiken. DebugView Die DebugView ist nur für Debuggingzwecke existent. Sie besteht aus einer Box2DDebugComponent, welche die Eigenschaften eines physikalischen Objektes visualisiert. Player Der Player ist das Herzstück der Jump-and-Run-Demo. Er kann sich nach links und rechts bewegen und springen, was sich in der Animation des Spielercharakters widerspiegelt. Ist seine Lebensenergie verbraucht, startet er das aktuelle Level neu. Der Player besteht aus folgenden Komponenten: Box2DSpatialComponent: Definiert das Physikobjekt. Es handelt sich dabei um ein Rechteck, dessen Rotationswert gesperrt ist. SpriteSheetComponent: Lädt das Sprite-Sheet des Spielers. SpriteSheetRenderer: Stellt das geladene Sprite-Sheet dar, hängt von der SpriteSheetComponent ab. AnimatorComponent: Animiert den Sprite-Index der SpriteSheetRendererKomponente. Es werden die Animationen idle, run und die verwendet. CharacterController: Ist für die Steuerung des Charakters verantwortlich. Greift dabei auf die Box2DSpatialComponent (Bewegung des Spielers) und die AnimatorComponent (abzuspielende Animation) zu. HealthComponent: Verwaltet die Lebensenergie. 5. Ergebnisse 47 PlayerLogic: Verarbeitet die Events der HealthComponent, z.B. respawn, wenn der Spieler stirbt. Platform Bei der Platform handelt es sich um ein Objekt, das mit dem Spieler kollidiert. Es besteht aus: SimplePlatform: Aushilfskomponente. Erstellt die Box2DSpatialComponent und SpriteRenderer-Komponente. Box2DSpatialComponent: Definiert das Physikobjekt. SpriteRenderer: Stellt die Grafik dar. DamageOtherEntity Die DamageOtherEntity fügt bei Kollision der anderen Entität Schaden zu. Sie besteht aus den Komponenten: DamageEntityOnCollision: Fügt im Falle einer Kollision via HealthComponent der anderen Entität Schaden zu. Box2DSpatialComponent: Definiert das Physikobjekt. SpriteRenderer: Stellt die Grafik dar. In der Demo kommt die DamageOtherEntity in zwei verschiedenen Varianten vor: dem RollingStone und dem TripStone. Der Unterschied zwischen den beiden ist, dass der RollingStone ein dynamisches und der TripStone ein statisches Objekt ist. Trigger Ein Trigger löst einen Event aus, wenn er von einem anderen Objekt berührt wird. Er setzt sich aus folgenden Komponenten zusammen: Box2DTrigger: Im Falle einer Kollision erstellt diese Komponente einen Event beliebigen Typs mit beliebigen Argumenten. Box2DSpatialComponent: Definiert das Physikobjekt. SpriteRenderer: Stellt die Grafik dar (ein Trigger -Icon zur besseren Überschaubarkeit im Editor). In der Demo kommt der Trigger in zwei verschiedenen Varianten vor: der ResetPlayerZone und der RollingStoneTrigger. Betritt der Spieler eine ResetPlayerZone, so wird er an eine bestimmte Position zurückgesetzt. Betritt der Spieler einen RollingStoneTrigger, erstellt dieser an einer bestimmten Position eine RollingStone-Entität. 5. Ergebnisse 48 Abbildung 5.2: Screenshot der Racing-Demo. DecorationObject Ein DecorationObject ist ein rein visuelles Objekt und besteht aus einer SpriteRenderer-Komponente. 5.2 Racing-Demo Die Racing-Demo stellt die Grundfunktionen für ein Top-Down-Rennspiel bereit. Dies beinhaltet u.a.: • die Steuerung des Rennautos, • Kollisionsobjekte, durch die das Auto nicht hindurchfahren kann, und • eine Strecken-Logik, die den Spieler daran hindert, unerlaubte Abkürzungen zu fahren. Einen Screenshot der Racing-Demo zeigt Abb. 5.2. 5.2.1 Vorkommende Entitäten Scene Die Scene beinhaltet alle Komponenten, die für die Verwaltung der Spielszene relevant sind und setzt sich wie folgt zusammen: Box2DManagerComponent: Verwaltet die Physikobjekte. DisplayObjectScene: Verwaltet die Grafiken. 5. Ergebnisse 49 DebugView Die DebugView ist nur für Debuggingzwecke existent. Sie besteht aus einer Box2DDebugComponent, welche die Eigenschaften eines physikalischen Objektes visualisiert. Player Der Player ist in diesem Fall das Rennauto. Es kann sich vor und zurück bewegen und währenddessen auch nach links oder rechts lenken. Das Rennauto beseht aus folgenden Komponenten: SpriteRenderer: Stellt die Grafik dar. Box2DSpatialComponent: Definiert das Physikobjekt. CarController: Ist für die Steuerung des Rennautos verantwortlich. Greift dabei auf die Box2DSpatialComponent zu. RacingLogic: Diese verarbeitet die Information der Marker -Entitäten und setzt den Spieler im Fehlerfall zurück zum letztgültigen Marker. Tyres Die Tyres kommen in zwei Versionen vor: einmal als einzelner Reifen und einmal als Fünferblock. Sie dienen als Streckenbegrenzung und blockieren das Rennauto. Tyres setzen sich wie folgt zusammen: SimplePlatform: Aushilfskomponente. Erstellt die Box2DSpatialComponent und SpriteRenderer-Komponente. SpriteRenderer: Stellt die Grafik dar. Box2DSpatialComponent: Definiert das Physikobjekt. Marker Beim Marker handelt es sich um einen Trigger, der bei Berührung die Markerdaten (Index, Position, Rotation) aktualisiert, welche wiederum von der RacingLogic-Komponente der Player -Entität verarbeitet werden. Er besteht aus folgenden Komponenten: Box2DTrigger: Im Falle einer Kollision erstellt diese Komponente einen Event beliebigen Typs mit beliebigen Argumenten. Box2DSpatialComponent: Definiert das Physikobjekt. SpriteRenderer: Stellt die Grafik dar (ein Trigger -Icon zur besseren Überschaubarkeit im Editor). Track Die Track besteht aus einer SpriteRenderer-Komponente, welche die Hintergrundgrafik darstellt. 5. Ergebnisse 50 Abbildung 5.3: Screenshot der Space Shooter-Demo. 5.3 Space-Shooter-Demo Die Space-Shooter-Demo stellt die Grundfunktionen für einen typischen Weltraum-Shooter bereit. Dies beinhaltet u.a.: • die Steuerung des Raumschiffes, • das Abfeuern von Projektilen und • Objekte, die durch den Raum fliegen und dem Spieler bei Kollision Schaden zufügen. Einen Screenshot der Space-Shooter-Demo zeigt Abb. 5.3. 5.3.1 Vorkommende Entitäten Scene Die Scene beinhaltet alle Komponenten, die für die Verwaltung der Spielszene relevant sind und setzt sich wie folgt zusammen: Box2DManagerComponent: Verwaltet die Physikobjekte. DisplayObjectScene: Verwaltet die Grafiken. DebugView Die DebugView ist nur für Debuggingzwecke existent. Sie besteht aus einer Box2DDebugComponent, welche die Eigenschaften eines physikalischen Objektes visualisiert. 5. Ergebnisse 51 Player Beim Player handelt es sich um das Raumschiff. Es kann sich nach links und rechts bewegen und Raketen abfeuern. Wenn es zweimal von einem Asteroiden getroffen wurde, wird es zerstört. Der Player setzt sich aus folgenden Komponenten zusammen: SpriteRenderer: Stellt die Grafik dar. Box2DSpatialComponent: Definiert das Physikobjekt. HealthComponent: Verwaltet die Lebensenergie. SpaceShipController: Ist für die Steuerung des Raumschiffes verantwortlich. Greift dabei auf die Box2DSpatialComponent zu. SpaceShipLogic: Verarbeitet die Events der HealthComponent, zerstört den Spieler, wenn dieser keine Lebensenergie mehr hat. Game Die Game-Entität kümmert sich um die Erstellung der Asteroiden an zufälligen Positionen in einem gewissen Intervall. Sie besteht aus den Komponenten: Zwei RandomPoint: Einen RandomPoint für die Position und einen für die Geschwindigkeit des Asteroiden. RandomNumber: Zufallswert für die Winkelgeschwindigkeit des Asteroiden. EntitySpawner: Erstellt in einem bestimmten Intervall eine beliebige Entität mit beliebigen Argumenten. SpriteRenderer: Stellt die Grafik dar (ein Trigger -Icon zur besseren Überschaubarkeit im Editor). GameBorder Die GameBorder -Entität besteht aus vier Box2DSpatialComponents. Zwei davon decken den linken und rechten Rand des Bildschirms ab, damit der Spieler diesen nicht verlassen kann. Die anderen zwei sorgen dafür, dass die Projektile den oberen und die Asteroiden den unteren Bildschirmrand nicht verlassen (Asteroiden und Projektile zerstören sich bei einer Kollision mit einem anderen Objekt selbst). Background Um das Gefühl eines Weltraumfluges zu vermitteln, wurde die Hintergrundgrafik mit Hilfe der ScrollingBitmapRenderer-Komponente animiert. 5. Ergebnisse 52 Bullet Ein Bullet wird vom Spieler abgefeuert und fliegt konstant in die Schussrichtung. Wenn es mit einem anderen Objekt kollidiert, zerstört das Bullet sich selbst. Es setzt sich wie folgt zusammen: SpriteRenderer: Stellt die Grafik dar. Box2DSpatialComponent: Definiert das Physikobjekt. DestroyEntityOnCollision: Zerstört die Entität bei einer Kollision mit einem anderen Objekt. Asteroid Ein Asteroid fliegt konstant in eine Richtung. Kollidiert er mit einem anderen Objekt, so versucht er, diesem Schaden zuzufügen und zerstört sich anschließend selbst. Er beinhaltet die Komponenten: SpriteRenderer: Stellt die Grafik dar. Box2DSpatialComponent: Definiert das Physikobjekt. DamageEntityOnCollision: Fügt im Falle einer Kollision via HealthComponent der anderen Entität Schaden zu. DestroyEntityOnCollision: Zerstört die Entität bei einer Kollision mit einem anderen Objekt. Kapitel 6 Resümee 6.1 Diskussion der Ergebnisse Die erstellten Demos Jump-and-Run, Racing und Space-Shooter entsprechen mehr einem Prototypen als einem Spiel. Da diese aber die Kernfeatures des jeweiligen Genres implementieren, lassen sich bereits in diesem Stadium gewisse Schlussfolgerungen ziehen. 6.1.1 Entwicklungszeit und Wiederverwendbarkeit In jede Demo wurden in etwa acht Stunden Entwicklungszeit investiert. Als große Zeitersparnis stellte sich dabei die Wiederverwendbarkeit der einzelnen Komponenten heraus. Tabelle 6.1 zeigt einen Überblick aller verwendeten Komponenten und in welchen Projekten sie konkret zum Einsatz kamen. Es mag zwar den Eindruck erwecken, als ob Komponenten mit spezieller Funktionalität (wie SpriteSheet, ScrollingBitmap oder RandomNumber/Point) nicht wiederverwendbar sind, dieser täuscht jedoch, da sie schlichtweg bei den anderen Demos nicht benötigt wurden. Um die Wiederverwendbarkeit weiter zu erhöhen, könnte man manche der verwendeten Komponenten weiter vereinheitlichen, z.B. aus der DamageEntityOnCollision und der DestroyEntityOnCollision eine FireEventOnCollision-Komponente machen, deren Event frei konfigurierbar ist. Alternativ könnte man den Box2DTrigger so umschreiben, dass er nicht eine Box2DSpatial-Komponente erzeugt, sondern davon ausgeht, dass diese in der Entität existiert und bloß auf Kollisionsnachrichten hört. Somit wären alle drei vorhin beschriebenen OnCollision-Komponenten überflüssig. Für die drei Demos nicht wiederverwendbar waren generell die LogikKomponenten. Diese sind in der Regel zu spielspezifisch und müssen wohl stets neu geschrieben werden. 53 6. Resümee 54 Tabelle 6.1: Verwendung der Komponenten in den erstellten Demos Jumpand-Run, Racing und Space-Shooter. Komponente AnimatorComponent Box2DDebugComponent Box2DManagerComponent Box2DSpatialComponent Box2DTrigger CarController CharacterController DamageEntityOnCollision DestroyEntityOnCollision DisplayObjectScene EntitySpawner HealthComponent PlayerLogic RacingLogic RandomNumber RandomPoint SceneView ScrollingBitmapRenderer SimplePlatform SimpleSpatialComponent SpaceShipController SpaceShipLogic SpriteRenderer SpriteSheetRenderer SpriteSheetComponent Jump Race Space x x x x x x x x x x x x x x x x x x x x x x x x x x x - x x x x x x x x x x x x x x x - Begrenzung des Spiel-Genres Da der LM2k generell alle Komponenten visualisieren kann, gibt es auch keine Begrenzung hinsichtlich des Spiel-Genres. Sofern die Komponenten verfügbar sind, kann damit also ein beliebiger Computerspielprototyp erstellt werden. 6. Resümee 6.1.2 55 Prototyp als Basis für ein fertiges Spiel Rechnet man das Ergebnis der Demos auf ein fertiges Spiel hoch, so lässt sich behaupten, dass sich mit dem LM2k (respektive einem Rapid-PrototypingTool) auch fertige Spiele erstellen lassen. Der komponentenbasierte Ansatz unterstützt dies, da er die Entwicklung sehr modular gestaltet: • Im Falle von Performanceproblemen kann man einzelne Komponenten optimieren, ohne die restliche Codebase zu beeinträchtigen. Das Prinzip der Dualwartung (den Prototyp getrennt vom eigentlichen Spiel zu entwickeln und zu warten) erweist sich laut dem präsentierten Ansatz als überflüssig. • Wird zusätzliche Funktionalität benötigt, so kann man diese durch das Erstellen von neuen Komponenten hinzufügen. 6.2 Level Master 2000 Der Prozess der Toolentwicklung ist sehr zeitintensiv. Der LM2k wurde knapp zwei Semester lang als „Projekt“ an der FH Hagenberg entwickelt, was schätzungsweise 600 Arbeits-Stunden entspricht. Das Ergebnis an sich ist – zumindest für den Autor – grundsätzlich sehr zufriedenstellend, jedoch mangelt es noch an gewisser Funktionalität, damit der LM2k in der Praxis auch wirklich vernünftig eingesetzt werden kann. Der Implementierungsaufwand für die noch fehlenden Features mag einzeln, für sich betrachtet, nicht so hoch sein, jedoch ist es die Summe dieser, die noch sehr viel Entwicklungszeit benötigen würde. 6.2.1 Gewählte Architektur Die Aufteilung der Applikation in View-Control und Model als auch die technischbedingte Unterteilung der View-Control in C++- und ActionScript Teil bringen gewisse Vor- und Nachteile mit sich. Diese wurden wie folgt identifiziert: Vorteile dieses Ansatzes • Durch die Verwendung von Qt auf der Frontend-Seite konnte man sehr viel Funktionalität von Qt übernehmen. So verfügt es z.B. über: – ein Undo-Framework, welches bereits das Command-Pattern implementiert. – einen Property-Browser, welcher sich um die Darstellung der Eigenschaften eines Objektes kümmert. – die Möglichkeit zur Verwendung mehrerer Monitore wird durch das Fenstersystem von Qt vernünftig ermöglicht. 6. Resümee 56 • Qt als auch Flash sind plattformübergreifend verfügbar. Somit ist der LM2k auf den Systemen Windows, OSX und Linux lauffähig1 . • Da der Editor-Code unabhängig vom Spiel-Code existiert, ist es möglich, ein beliebiges PushButton Engine-Spiel zu editieren. Wäre der Editor direkt in das Spiel integriert, wäre dies nur bei den Spielen möglich, die eben auch den Editor integrieren. Theoretisch wäre es sogar möglich, Spiele „übers Internet“ zu editieren, wenn das Spiel den Zugriff einer anderen Domain erlaubt. Zum Speichern der Levelfiles bräuchte man aber zusätzliche Schreibrechte auf dem Server. Nachteile dieses Ansatzes • Durch die Trennung von C++ und ActionScript wird der Debuggingprozess erschwert. Es ist kein Problem, jeden Teil für sich oder den C++-Teil, wenn die Aktionen vom ActionScript -Teil kommen, zu debuggen. Wenn man aber den ActionScript -Teil debuggen will und die Aktionen vom C++-Teil kommen sollen, wird es problematisch, da man die Editor-SWF im Debug-Mode starten müsste, auf die aber auch der C++-Teil beim Start zugreift – und dies ist nicht möglich2 . Abhilfe schaffen hierbei die Debugeinträge in der Log View. Bei diesen handelt es sich um ActionScript -Anweisungen, die bei jeder Aktion auf der C++-Seite erstellt werden. Somit kann man beim Debuggen des ActionScript -Teils C++-Befehle simulieren, indem man die DebugAnweisungen z.B. in der OnClick-Methode ausführt. • Erweiterungen müssen unter Umständen auf der C++- und der ActionScript -Seite implementiert werden, was den Entwicklungsprozess insgesamt verlangsamt. So existiert z.B. auf der C++-Seite eine EntityKlasse, die für eine Entität der PushButton Engine steht. Ein weiterer Umstand sind z.B. Tastatur-Shortcuts: diese müssen in C++ und ActionScript implementiert werden, da die Applikation je nach aktivem Fenster (Flash-Szene oder Editor-GUI) den Fokus anders setzt. 6.2.2 Verbesserungsvorschläge Um den LM2k effektiv in der Praxis einsetzen zu können, sollten noch folgende Features implementiert werden: Objekte duplizieren: Es ist derzeit nicht möglich, Entitäten bequem per Mausklick zu duplizieren. Der derzeitige Workaround besteht daraus, dass man die entsprechende Entität im Levelfile aufsucht und diese dort textbasiert dupliziert. 1 Bisher wurde der LM2k auf Windows und OSX erfolgreich getestet. Zumindest nicht mit den verwendeten Tools Qt Creator und FlashDevelop. Kostenpflichtige Alternativen wie z.B. Amethyst wurden nicht berücksichtigt. 2 6. Resümee 57 Template Editor: Um dem Adjektiv „rapid“ gerecht zu werden, benötigt der LM2k den Template Editor (siehe Abschnitt 4.5.8). Die DemoProjekte haben gezeigt, dass es zu aufwändig ist, die Entitäten ständig über den Component Browser (siehe Abschnitt 4.5.6) zusammenzustellen. Collision Shape Editor: Für physikbasierte Spiele ist ein Collision Shape Editor Pflicht. Derzeit ist es nur möglich, Collision-Shapes direkt per Hand im Levelfile zu definieren, da der Property Browser den CollisionShape-Datentyp nicht darstellen kann. Live- & Edit-Mode: Aufgrund der PushButton Engine gibt es derzeit nur einen Live- und Pause-Mode, wobei das Erstellen von Entitäten nur im Live-Mode funktioniert. Für die Implementierung eines Edit-Modes, also eines Modus, indem die Engine pausiert und man auch Entitäten erstellen kann, müssen aber wohl Änderungen an der PushButton Engine gemacht werden. Deployment: Um ein Spiel lokal auf der Festplatte bearbeiten zu können, müssen sowohl das Spiel, als auch der ActionScript -Teil des Editors mit dem Compiler-Flag use-network=false erstellt worden sein3 . Will man ein Spiel online stellen, muss dieses Flag auf true gesetzt werden. Die Idee ist nun, dass dieser Prozess bei Betätigung eines DeployButtons automatisiert wird. Optional sollten im Zuge dieses Prozesses auch gleich alle Assets in die Spiel-SWF eingebettet werden. Datentypen: Diverse Datentypen werden vom Property Browser (siehe Abschnitt 4.5.3) noch nicht unterstützt. Ziel ist es, alle relevanten Datentypen der PushButton Engine zu unterstützen. 6.3 Abschlussbemerkungen und Ausblick Abschließend soll erwähnt werden, dass es genug ausgereifte und dennoch kostengünstige Rapid-Prototyping-Tools gibt, die man einer eigenständig entwickelten Lösung bevorzugen kann (z.B. ShiVa oder Unity). So ist es einem gleich von Beginn an möglich, sich auf die Entwicklung des eigentlichen Spiels zu konzentrieren, anstatt sich um die Entwicklung eines Tools kümmern zu müssen. Zahlreiche erfolgreich entwickelte Spiele – sei es mit ShiVa oder Unity – beweisen dies. Natürlich muss man im Vorfeld eines Projektes aber immer abwägen, ob die gewählte Applikation auch alle benötigten Features bereitstellt, oder ob man diese über eigene Plugins einbinden kann. Heutige Tools sind in ihrer Architektur aber meist flexibel genug, sodass dies nicht zu einem Problem wird. 3 Die Gründe hierfür liegen in der Flash-Sandbox-Security, siehe http://blog.natebeck. net/2010/01/developing-games-with-pushbutton-engine-understanding-local-flash-playersecurity/ 6. Resümee 58 Trotz dieser Empfehlung gegen die eigene Toolentwicklung könnte die Entwicklung des LM2k fortgesetzt werden: Editor für die PushButton Engine: Der Source-Code wird auf http:// code.google.com/p/levelmaster2000/ unter der MIT-Lizenz freigegeben. Die PushButton Engine verfügt derzeit noch nicht über einen Editor und der LM2k könnte der Grundstein für ein solches Unterfangen werden. Eine Möglichkeit, die Entwicklung voranzutreiben, wäre die aktive Einbindung der Community. Editor für die Broken Rules Engine: Broken Rules arbeitet derzeit an einer plattformübergreifenden Game-Engine und möchte den LM2k für diese weiterverwenden. Inwiefern die benötigte Adaption der Architektur mit dem offiziellen Level Master 2000 -Projekt auf Google Code kompatibel bleibt, wird sich allerdings zeigen. Wieviel Zeit schlussendlich von mir persönlich noch in dieses Projekt gesteckt wird, lässt sich zu diesem Zeitpunkt noch nicht abschätzen. Anhang A Verwendete Komponenten A.1 Selbst erstellte Komponenten Die in diesem Abschnitt angeführten Komponenten wurden für die drei Demo-Applikationen erstellt. A.1.1 Namespace com.zog Box2DTrigger Der Box2DTrigger ist ein Box2D-Objekt, welches bei Kollision mit einem anderen Box2D-Objekt einen beliebig konfigurierbaren Event mit beliebigen Argumenten erstellt. CarController Der CarController stellt die Steuerungsfunktion für ein Top-Down-Rennauto zur Verfügung. Er hört auf die Nachrichten GoForward, GoBackward, GoLeft und GoRight, die auf beliebige Tasten gelegt werden können. Für die eigentliche Bewegung des Rennautos benötigt diese Komponente eine Box2DSpatialComponent. CharacterController Beim CharacterController handelt es sich um eine Jump-and-Run-Spielersteuerung. Dieser hört auf die Nachrichten GoLeft, GoRight und Jump, die auf beliebige Tasten gelegt werden können. Für die eigentliche Bewegung des Charakters benötigt diese Komponente eine Box2DSpatialComponent. DamageEntityOnCollision Die DamageEntityOnCollision verursacht, bei einer Kollision mit einem Box2DObjekt, einen gewissen Schaden bei der anderen Entität – dies aber nur, 59 A. Verwendete Komponenten 60 wenn die Kollisionsgruppen übereinstimmen. Der Schaden wird über die HealthComponent verursacht. DestroyEntityOnCollision Die DestroyEntityOnCollision zerstört sich bei einer Kollision mit einem anderen Box2D-Objekt selbst. EntitySpawner Der EntitySpawner erzeugt in einem gewissen Intervall Entitäten eines beliebigen PushButton Engine-Templates. Die Argumente des Templates können ebenfalls frei konfiguriert werden. PlayerLogic Die PlayerLogic wurde vorrangig für die Jump-and-Run-Demo entwickelt. Diese verarbeitet HealthEvents und ResetPlayerEvents: HealthEvent: Bei Auftreten des Sterbe-Events spielt die PlayerLogic eine Sterbeanimation ab. Darüber hinaus deaktiviert sie die Kollision mit der Spielwelt und gibt dem Charakter einen kurzen, vertikalen Impuls nach oben (dies erzeugt eine Sterbesequenz, wie man es z.B. von Super Mario 3 gewohnt ist). ResetPlayerEvent: Wird der Spieler zurückgesetzt, so wird die Animation Idle abgespielt, die Kollision mit der Spielwelt wieder aktiviert und der Spieler an eine bestimmte Position gesetzt. RacingLogic Die RacingLogic wurde vorrangig für die Racing-Demo entwickelt. Sie hört auf Marker -Events. Marker werden dabei auf der Rennstrecke platziert und mit einem ansteigenden Index versehen. Passt der Index des passierten Markers nicht mit dem des vorherigen zusammen, so kümmert sich die RacingLogic darum, dass der Spieler zum letztgültigen Marker zurückgesetzt wird. RandomNumber Die RandomNumber liefert eine Zufallszahl mit einstellbarem Minimal- und Maximalwert zurück. Diese wird bei jedem Zugriff neu erstellt. RandomPoint Mit einstellbarem Minimal- und Maximalwert jeder Komponente eines Punktes liefert der RandomPoint einen zufälligen Punkt zurück. Dieser wird bei jedem Zugriff neu erstellt. A. Verwendete Komponenten 61 SimplePlatform Vorwort: Die SimplePlatform sollte in dieser Form nicht verwendet werden. Benötigt man Baupläne für Entitäten, so empfiehlt sich der Einsatz von Templates. Die SimplePlatform entstand in einer sehr frühen Phase des Projektes und hielt sich hartnäckig, was vor allem darin begründet liegt, dass der Editor noch keine Templates verwalten kann. Bei der SimplePlatform handelt es sich um eine Aushilfs-Komponente. Diese erstellt eine Box2DSpatialComponent und ein SpriteRenderer-Komponente, die miteinander verknüpft sind (Position, Rotation und Größe des Spatials wirken sich auf die jeweiligen Eigenschaften des Renderers aus). SpaceShipController Beim SpaceShipController handelt es sich um eine Top-Down-Raumschiffsteuerung im Stil eines Space-Shooters. Er hört auf die Nachrichten GoLeft, GoRight und Shoot, die auf beliebige Tasten gelegt werden können. Für die eigentliche Bewegung des Raumschiffes benötigt diese Komponente eine Spatial-Komponente. SpaceShipLogic Die SpaceShipLogic wurde vorrangig für die Space-Shooter-Demo entwickelt. In der vorliegenden Form verarbeitet diese den Die-Event der HealthComponent. Tritt dieser auf, zerstört die SpaceShipLogic die Entität. A.2 Verwendete Komponenten der PushButton Engine In diesem Abschnitt finden sich die Komponenten der PushButton Engine wieder, die bei den Demos zum Einsatz kamen. A.2.1 Namespace com.pblabs.rendering2D Das Package rendering2D beinhaltet Komponenten, die man für die Grafikausgabe benötigt. DisplayObjectScene Die DisplayObjectScene kümmert sich um das Rendern einer 2D-Szene. Sie verwaltet die Grafik-Komponenten und kümmert sich darum, dass sie in der richtigen Reihenfolge gerendert werden. A. Verwendete Komponenten 62 SimpleSpatialComponent Bei SimpleSpatialComponent handelt es sich um eine Komponente, die neben den räumlichen Daten Position, Rotation und Größe auch eine Geschwindigkeits-Eigenschaft hat. Sie hat aber keine Anbindung an eine Physik-Engine, Kollisionen zwischen zwei SimpleSpatialComponents werden nicht erkannt. SpriteRenderer Der SpriteRenderer stellt eine einzelne Grafik dar. SpriteSheetRenderer Der SpriteSheetRenderer stellt ein Sprite-Sheet dar und benötigt eine SpriteSheetComponent. spritesheet.SpriteSheetComponent Die SpriteSheetComponent lädt eine Sprite-Sheet-Grafik und stellt diese zur Verfügung. Um die geladene Sprite-Sheet darstellen zu können, benötigt man z.B den SpriteSheetRenderer. A.2.2 Namespace com.pblabs.box2D In diesem Package befinden sich Komponenten für die Integration der PhysikEngine Box2D. Box2DDebugComponent Mit der Box2DDebugComponent kann man Box2D-Objekte visualisieren. Die darzustellenden Eigenschaften sind konfigurierbar. Box2DManagerComponent Die Box2DManagerComponent ist die Hauptanbindung an Box2D und stelllt die Schnittstelle zur Box2D-Welt her. Allgemeine Eigenschaften, wie die Schwerkraft, lassen sich mit dieser Komponente einstellen. Box2DSpatialComponent Die Box2DSpatialComponent integriert einen Box2D-Body in die PushButton Engine. Eigenschaften wie Masse, Reibung, Form des Kollisionskörpers u.s.w. sind hier einstellbar. A. Verwendete Komponenten A.2.3 63 Weitere com.pblabs.animation.AnimatorComponent Die AnimatorComponent animiert einen Wert einer anderen Komponente. Bei der Wiedergabe der Animation unterscheidet man in: • keine Wiedergabe, • einmalige Wiedergabe, • Endloschleife oder • Ping-Pong-Wiedergabe (ist die Animation am Ende angelangt, wird die Abspielrichtung umgekehrt). com.pblabs.components.basic.HealthComponent Die HealthComponent verwaltet die Lebensenergie (LE). Damit andere Komponenten über den aktuellen Zustand informiert werden, versendet die HealthComponent folgende Events: HEALED: Wenn die LE zunimmt und diese zuvor noch > 0 war. DAMAGED: Wenn die LE abnimmt und diese zuvor noch > 0 war. DIED: Wenn die LE 0 ist. RESURRECTED: Wenn LE 0 war, und nun > 0 ist. com.wyrmtale.pbe.ScrollingBitmapRenderer Der ScrollingBitmapRenderer von Martijn Segers1 stellt eine Grafik dar, dessen Texturkoordinaten animiert werden können. 1 http://www.makeyourflashgame.com/ Anhang B Inhalt der CD-ROM Format: Mode: B.1 ISO9660/Joliet Single-Session (CD-ROM) Diplomarbeit Pfad: / dm08016_herzog_christian_da.pdf Diplomarbeit (PDF-Datei) dm08016_herzog_christian_da.ps Diplomarbeit (PostScript-Datei) B.2 Projektdateien Pfad: /src/ Cpp/* . . . . . . . . . . AS3/* . . . . . . . . . . DemoJumpAndRun/* . DemoRacing/* . . . . . DemoSpace/* . . . . . B.3 Source-Code Level Master 2000 (C++) Source-Code Level Master 2000 (ActionScript ) Source-Code der Jump-And-Run-Demo Source-Code der Racing-Demo Source-Code der Space-Shooter-Demo Webquellen Pfad: /webquellen/ *.pdf . . . . . . . . . . Kopien der im Literaturverzeichnis aufgelisteten Webquellen 64 B. Inhalt der CD-ROM B.4 65 Bilder Pfad: /images/ *.eps . . . . . . . . . . . Die verwendeten Bilder im EPS-Format Literaturverzeichnis [1] Adobe: Komponenten-Referenzhandbuch für ActionScript 3.0, 2007. http://livedocs.adobe.com/flash/9.0_de/ActionScriptLangRefV3/flash/ external/ExternalInterface.html, Kopie auf CD-ROM. [2] Bates, B.: Game Design, Second Edition. Course Technology PTR, Sep. 2004, ISBN 978-1-59200-413-5. [3] Bethke, E.: Game Development and Production. Wordware Publishing Inc., 2003, ISBN 1-55622-951-8. [4] Chady, M.: Theory and Practice of Game Object Component Architecture. Game Developers Conference Canada, 2009. http://www.gdcvault. com/play/1911/, Kopie auf CD-ROM. [5] Gabler, K., K. Gray, M. Kucic und S. Shodhan: How to Prototype a Game in Under 7 Days, 2005. http://www.gamasutra.com/features/ 20051026/gabler_01.shtml, Kopie auf CD-ROM. [6] Gamma, E., R. Helm, R. Johnson und J. Vlissides: Design Patterns. Addison-Wesley, März 2007, ISBN 0-20-163361-2. [7] Gregory, J.: Game Engine Architecture. Transatlantic Publishers, Wellesley, Masachusetts, Apr. 2009, ISBN 978-1-56881-413-1. [8] Kosak, D.: Game Prototyping: How the Skunkworks Work. GameSpy, 2006. http://pc.gamespy.com/pc/spore/698263p1.html, Kopie auf CDROM. [9] Lange, T.: Das komponentenbasierte GameObject-System. Making Games Magazin, 3:40–43, Apr. 2010. [10] Nielsen, J.: Usability ISBN 0-12-518406-9. Engineering. Academic Press, 1993, [11] Nokia Corporation: Qt Assistant, 2009. Auch online unter: http://doc. trolltech.com/4.6/. 66 Literaturverzeichnis 67 [12] Rollings, A. und D. Morris: Game Architecture and Design. New Riders Publishing, Nov. 2003, ISBN 0-7357-1363-4. Messbox zur Druckkontrolle — Druckgröße kontrollieren! — Breite = 100 mm Höhe = 50 mm — Diese Seite nach dem Druck entfernen! — 68