Final Starfighter Deluxe Die Patterns Ein Spielentwicklungsprojekt von Stefan Radicke && Thomas Fuchsmann.

Slides:



Advertisements
Ähnliche Präsentationen
der Universität Oldenburg
Advertisements

der Universität Oldenburg
Klassen - Verkettete Liste -
Einführung in die Programmierung Ausführbare Klassen
Kapselung , toString , equals , Java API
Threads Richard Göbel.
Java: Objektorientierte Programmierung
Java: Dynamische Datentypen
Listen Richard Göbel.
Indirekte Adressierung
Java: Grundlagen der Objektorientierung
Polymorphie (Vielgestaltigkeit)
Polymorphie (Vielgestaltigkeit)
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (05 – Elementare Datenstrukturen) Prof. Th. Ottmann.
V09 Fallende Formen, Geschwindigkeitsregelung und Timing Daniel Ebner Spieleprogrammierung mit DirectX und C++
Benötigte Applets Startseite: in HTML-Format Applet auf der Startseite Das Applet, das auf der Startseite geladen wird, wird die vier Buttons und die eine.
Praktikum Entwicklung und Einsatz von Geosoftware I - Sitzung 6 Model-View-Controler als Grundlage für Nutzerschnittstellen Sommersemester 2003 Lars Bernard.
Praktikum Entwicklung und Einsatz von Geosoftware I - Sitzung 3 Klassen, Objekte, Arrays und Kontrollstrukturen Sommersemester 2003 Lars Bernard.
Vererbung Spezialisierung von Klassen in JAVA möglich durch
PRJ 2007/1 Stefan Dissmann Motivation Problem: gleiche Datenstrukturen werden für verschiedene Objekte gebraucht: z.B. Listen von Studierenden, Kunden,
PKJ 2005/1 Stefan Dissmann Ausblick Es fehlen noch: Möglichkeiten zum Strukturieren größerer Programme Umgang mit variabler Zahl von Elementen Umgang mit.
PKJ 2005/1 Stefan Dissmann Rückblick auf 2005 Was zuletzt in 2005 vorgestellt wurde: Klassen mit Attributen, Methoden und Konstruktoren Referenzen auf.
PKJ 2005/1 Stefan Dissmann Klassenhierarchie Person Kunde Goldkunde Lieferant Object.
Listen Prof. Dr. Christian Böhm in Zusammenarbeit mit Gefei Zhang
Entwurfsmuster – Iterator
Software Design Patterns Creational Patterns Structural Patterns Behavioral Patterns –Behavioral Class Patterns Interpreter Template Method Pattern –Behavioral.
DVG Interfaces. DVG mehrfache Vererbung 4 Mehrfache Vererbung ist die Ableitung einer Klassen von mehreren anderen Klassen. –farbigerPunkt.
07-GraphischeObjekte Graphische Objekte in EMMA301Paint.
DVG Klassen und Objekte
EDV Parallelprogrammierung1 Parallelprogrammierung mit JAVA.
Einführung in die Programmierung Vererbung
Einführung in die Programmierung Datensammlung
© 2002 Dr. Cavelius - Ley - Pohlig - Taulien Programmierung im Netz und Internet: Einführung in die Programmiersprache Java Teil I 1 Klassen Objekte von.
Template Pattern Richard Göbel.
Seite 1 Interface - Konzept Ein Interface führt einen neuen Datentyp ein: interface Frau {... } Das Interface enthält Deklarationen ( keine Definitionen.
Sitzung 3: Klassen, Objekte, Arrays und Kontrollstrukturen
Sommersemester 2004 Jan Drewnak Entwicklung und Einsatz von Geosoftware I Praktikum Sitzung 6 Sitzung 6: Model-View-Controller als Grundlage.
PRJ 2007/1 Stefan Dissmann Verkettete datenstruktur: Liste Problem: Liste, die eine beliebige Zahl von Elementen verwaltet Operationen: Erzeugen, Anfügen,
Grundkonzepte Java - Klassendefinition
Java programmieren mit JavaKara
Übungen zum Vortrag „Backtracking mit Heuristiken“
Abteilung für Telekooperation Übung Softwareentwicklung 1 für Wirtschaftsinformatik Dr. Wieland Schwinger
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Einführung in die Programmierung
Einführung in die Programmierung Wintersemester 2009/10 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Javakurs FSS 2012 Lehrstuhl Stuckenschmidt
Vom Umgang mit Daten. public void myProgram() { int[] saeulenWerte = new int[world.getSizeX()]; for (int i = 0; i < saeulenWerte.length; i++) { saeulenWerte[i]
Variablenkonzept Klassisch, in Java Basistyp
Einfach und doppelt verkettete Listen in JAVA by Jens Weibler
EPROG Tutorium #3 Philipp Effenberger
Learning By Doing Parallelverarbeitung Multithreading (Nebenläufigkeit) Alte Idee der Parallelverarbeitung statt rein sequentieller Prozesse Parallelverarbeitung.
Unity 4.x Cookbook Softwaretechnologie II (Teil 2) - Maximilian Berndt.
Java-Kurs - 8. Übung Besprechung der Hausaufgabe.
Polymorphie (Vielgestaltigkeit). Wenn eine Methode, wie z.B. print für verschiedene Programmteile steht (und z.B. einmal Objekte verschiedener Klassen.
Mag. Thomas Hilpold, Universität Linz, Institut für Wirtschaftsinformatik – Software Engineering 1 Programmierpraktikum Java SS 2005 Mag.Thomas Hilpold.
Software Design Patterns
Mag. Thomas Hilpold, Universität Linz, Institut für Wirtschaftsinformatik – Software Engineering 1 Algorithmen und Datenstrukturen 1 SS 2002 Mag.Thomas.
Java-Kurs Übung Besprechung der Hausaufgabe Vererbung
Java-Kurs Übung Besprechung der Hausaufgabe
Java-Kurs Übung Besprechung der Hausaufgabe Vererbung
Einführung in die Programmierung mit Java
Java Server Pages Technologie zur Erzeugung dynamischer Webseiten basierend auf Java-Servlets Blockseminar Wintersemester 2001/2002Jochen Pfeiffer Seite.
ROBERT NYSTROM GAME PROGRAMMING PATTERNS III.8 Thema: Sequencing Patterns Seminar: Softwaretechnologie II (Teil 2) Dozent: Prof. Dr. Manfred Thaller Referent:
Java Programme nur ein bisschen objektorientiert.
Tutorium Software-Engineering SS14 Florian Manghofer.
Vererbung in Java. public abstract class Form { protected int breite; protected int hoehe; protected String farbe; /** * Erzeuge eine Form der Breite.
Die Klasse Geist.
Felder in Java.
Grundkurs Informatik 11-13
Implementieren von Klassen
 Präsentation transkript:

Final Starfighter Deluxe Die Patterns Ein Spielentwicklungsprojekt von Stefan Radicke && Thomas Fuchsmann

sr038 && tf0142 Inhalt 1 1. Einführung 1.1 Grober Überblick über das Projekt 1.2 Das Spiel: Ein virtueller Ausflug 2. Game Patterns, zum Ersten (ein grober Überblick) 2.1 Erklärung vom PollingThread 2.2 Vom PollingThread zur Session 2.3 Scrolling und Zeichenvorgang 3. Game Patterns, zum Zweiten (Objekte im Detail) 3.1 Karl, der Raumschiff 3.2 Feinde 3.3 Bewegungsmuster 3.4 Komm, wir basteln uns einen Feind

sr038 && tf0143 Inhalt 2 4. Objekte erzeugen Objekte: Die Schüsse 4.1 Was unterscheidet Schüsse von den anderen Objekten? 5. Kollisionserkennung 5.1 Problematik – Kleine Fragestunde 5.2 Das Konzept: Die konkreten Kollisionsklassen (Chain Of Responsibility, Strategy) 6. Das Level: Von der Engine zum Spiel 6.1 Ein vereinfachter Iterator 6.2 Konstruktoren und Arrays: Wunder der Technik 6.3 Zusatzinformationen 7. Der Punkt, zu dem wir nicht mehr kommen werden, falls doch Danksagung und Ressourcen

sr038 && tf Grober Überblick über das Projekt - Statt Patterns ein Projekt - Das Rad neu erfunden? - Entwicklungszeit / Umfang - Erste Planung - Ziel 1. Einführung 1.2 Das Spiel: Ein virtueller Ausflug - Patterns in Aktion

sr038 && tf Erklärung vom PollingThread - Grundlegender Spielablauf (Endlosschleife) - Einzelne Schritte (berechnen, rendern, zeichnen, warten) 2. Game Patterns, zum Ersten 2.2 Vom PollingThread zur Session - Zentrale Klasse (Mediator) - Alle Objekttypen (Diagramm) - Listen und Manager - Zusammenhang zwischen Session und PollingThread 2.3 Scrolling und Zeichenvorgang - Der Eindruck von Bewegung - Darstellung in mehreren Ebenen (Multiscrolling)

sr038 && tf Erklärung vom PollingThread Vereinfachter Spielablauf: while (true) { //Aktuellen Zustand des Spiels berechnen. berechnen(); //Das Spiel rendern und auf den Bildschirm zeichnen. zeichnen(); //Ein wenig schlafen. Thread.sleep(25); }

sr038 && tf0147 Session 2.2 Vom PollingThread zur Session Karl Feinde Wände Items Factories Datenbanken Schüsse Level Session als zentrale Klasse: Mediator

sr038 && tf Vom PollingThread zur Session Listen und Manager: Die Session hält alle Feinde, Schüsse, Items und Wände in ArrayListen. => Alle Objekte, die in den Listen gespeichert sind, sind am aktuellen Spielgeschehen beteiligt. Für alle Objekttypen sind Manager-Methoden vorhanden, die vom PollingThread in einer bestimmten Reihenfolge aufgerufen werden. Funktionsweise der Manager: => über die entsprechende ArrayList wird iteriert => Objekt wird bewegt => Kollision wird geprüft

sr038 && tf Vom PollingThread zur Session enemyManager() als Beispiel: public void enemyManager() { for (iterator = enemies.iterator(); iterator.hasNext();) { enemy = (IEnemy)iterator.next(); if (enemy.isAlive()) { enemy.move(); //Kollision wird an anderer Stelle geprüft } else { enemy.suicide(); }

sr038 && tf Vom PollingThread zur Session Zusammenhang zwischen Session und PollingThread: PollingThread Session levelManager() wallManager() enemyManager() enemyShootManager() shootManager() itemManager() karlManager() repaint() Spielzustand berechnen rendern, zeichnen

sr038 && tf Scrolling und Zeichenvorgang Der Eindruck von Bewegung:

sr038 && tf Scrolling und Zeichenvorgang Der Eindruck von Bewegung:

sr038 && tf Scrolling und Zeichenvorgang Darstellung in mehreren Ebenen:

sr038 && tf Game Patterns, zum Zweiten 3.1 Karl, der Raumschiff - Wichtige Attribute - Ergänzung zur Session: Der KeyListener - Steuerung und Bewegung - Waffen für Karl: Ballern wie gestört 3.2 Feinde - Wichtige Attribute - Analogie zu den Grundpatterns (State, Template und Facade) - Das Interface: Jeder Feind wird gleich behandelt (Facade) 3.3 Bewegungsmuster - Lustig, aber wahr: Feinde dekorieren Bewegungsmuster (Decorator) - Die Hierarchie der MovePatterns und ihrer Datenbank - Problemloser Wechsel, zu Laufzeit (State) 3.4 Komm, wir basteln uns einen Feind

sr038 && tf Karl, der Raumschiff Attribute für die Steuerung: + isMovingUp : boolean + isMovingDown : boolean + isMovingLeft : boolean + isMovingRight : boolean + isShooting : boolean => In den Methoden keyPressed(...) und keyReleased(...) werden die boolschen Variablen gesetzt. => Dadurch ist eine flüssige Steuerung, unabhängig von Interruptzeiten, möglich. Ergänzung zur Session: Der KeyListener

sr038 && tf Karl, der Raumschiff Waffen für Karl: Ballern wie gestört => Im shootManager() wird von Karl ein Schuss angefordert, wenn karl.isShooting auf true steht. => Karl entscheidet selbstständig, ob er zum aktuellen Zeitpunkt schießen darf. => Unter folgenden Voraussetzungen darf Karl schießen: - Es befinden sich nicht mehr Schüsse im Bild, als erlaubt. - Die vorgegebene Verzögerungszeit ist abgelaufen. Die nötigen Variablen sind in der allgemeinen abstrakten Klasse Shoot statisch festgelegt. => Die Verzögerungszeit wird ignoriert, wenn der Spieler die Feuern-Taste schnell hintereinander mehrmals betätigt.

sr038 && tf Feinde => State: Bewegung und Schussverhalten => Template: Algorithmen und deren Reihenfolge in abstrakten Superklassen. Subklassen bestimmen nur die Attributwerte. => Facade: Allgemeines Interface für alle Feinde Wichtige Attribute # isAlive : boolean # hp : int # points : int - enemyImage : Image - suicideImage : Image - lineArray : Line2D[ ] # movePattern : IMovePattern # isHitByShoot : boolean Analogie zu den Grundpatterns

sr038 && tf Feinde Jeder Feind wird gleich behandelt: Das Feindkonzept > Enemy AnimatedEnemy Weitere Klassen: Datenbanken, Karl, Level, etc. Fighter5 GroundCannon1 Session > Subsystem Facade

sr038 && tf Bewegungsmuster Feinde dekorieren Bewegungsmuster: Decorator + State > MovePattern PointMovePatternSimpleMovePattern > +move() : void Session => Das Interface IEnemy sieht eine Methode setMovePattern(...) vor, mit der es möglich ist, die Movepatterns zur Laufzeit auszutauschen. PointListData

sr038 && tf Komm, wir basteln uns einen Feind! public class FieserFeind extends Enemy { } public FieserFeind(Session session) { super(session); } public int getHeight() { return 60; } public int getWidth() { return 80; } public int getHP() { return 100; } public int getPoints() { return 10999; } public Image getEnemyImage() { return session.graphicData.getFieserFeindImage(); } public Image getSuicideImage() { return session.graphicData.getExplosion1Image(); } public void playSuicideSound() { session.soundData.playExplosion1(); } IMovePattern movePattern = new SimpleMovePattern(...); public IMovePattern getMovePattern() { return movePattern; }

sr038 && tf Objekte erzeugen Objekte: Die Schüsse 4.1 Was unterscheidet Schüsse von den anderen Objekten? - Die Hierarchie aller Schüsse - Karls Schüsse und feindliche Schüsse im Vergleich - Factories: Unterbindung von new

sr038 && tf Was unterscheidet Schüsse von anderen Objekten? => Schüsse werden zu unvorhersehbaren Zeiten in beliebiger Anzahl erzeugt. => Weiteres Problem: Schüsse dürfen nicht zur Laufzeit initialisiert werden. Lösung: Factories, die alle Schüsse beim Laden der Engine in ausreichender Anzahl erzeugen. => Worin unterscheiden sich Karls Schüsse von feindlichen Schüssen? - Art der Erzeugung - Karls Schüsse haben Trefferpunkte - feindliche Schüsse vernichten Karl sofort - feindliche Schüsse fliegen auf einen konkreten Zielpunkt zu

sr038 && tf Was unterscheidet Schüsse von anderen Objekten? Die Hierarchie aller Schüsse > Shoot KarlShootEnemyShoot EnemyShootFactory Session Fireball1RedLaser1 KarlShootFactory n Karl

sr038 && tf01424 Factories: Unterbindung von new EnemyShootFactory als Beispiel: 4.1 Was unterscheidet Schüsse von anderen Objekten? EnemyShootFactor y - redLaser1Array : EnemyShoot [ ]... //weitere Schusstypen-Arrays + getEnemyShoot(shootName:String) : EnemyShoot Enemy + createShoot() : void

sr038 && tf Kollisionserkennung 5.1 Problematik – Kleine Fragestunde - Anforderungen an die Kollision - ??? 5.2 Das Konzept: Die konkreten Kollisionsklassen (Chain Of Responsibility, Strategy) - Prinzipielle Zusammenarbeit der Klassen - Unterscheidung von Objekttypen - Performance, was ist das? (Grobüberprüfung, Reihenfolge)

sr038 && tf Kollisionserkennung 5.1 Anforderungen an die Kollisionserkennung: => Möglichst pixelgenaue Prüfung => Zuverlässigkeit => Einfache Handhabung: Flexibilität => Performance: Welche Prüfung ist wirklich nötig? Welche Lösung erfüllt diese Anforderungen? Unsere Lösung: Vektoren zur Kollisionsprüfung

sr038 && tf Die konkreten Kollisionsklassen Prinzipielle Zusammenarbeit der Klassen > + check(obj:Object) : boolean AbstractCollision # session : Session Collision + check(obj:Object) : boolean Session KarlShootCollision EnemyShootCollision ItemCollision KarlCollision

sr038 && tf Die konkreten Kollisionsklassen Unterscheidung von Objekttypen in der Klasse Collision public boolean check(Object obj) { if (obj instanceof Karl) { return karlCollision.check(obj); } if (obj instanceof KarlShoot) { return karlShootCollision.check(obj); } if (obj instanceof EnemyShoot) { return enemyShootCollision.check(obj); } if (obj instanceof Item) { return itemCollision.check(obj); } return false; }

sr038 && tf Die konkreten Kollisionsklassen Kollisionserkennung im Detail: KarlCollision Schritt 1 => Grobe Überprüfung, um Performance zu sparen: Bounding-Box Kollision kann ausgeschlossen werden. => Abbruch der Überprüfung

sr038 && tf Die konkreten Kollisionsklassen Kollisionserkennung im Detail: KarlCollision Schritt 2 => Grobe Überprüfung, um Performance zu sparen: Bounding-Box Kollision ist möglich. => Überprüfung auf Vektorebene

sr038 && tf Die konkreten Kollisionsklassen Kollisionserkennung im Detail: KarlCollision Schritt 3 => Genaue Überprüfung: Vektoren Vektoren überschneiden sich nicht. => keine Kollision

sr038 && tf Die konkreten Kollisionsklassen Kollisionserkennung im Detail: KarlCollision Schritt 4 => Genaue Überprüfung: Vektoren Vektoren überschneiden sich. => Kollision.. Karl ist tot!

sr038 && tf Das Level: Von der Engine zum Spiel 6.1 Ein vereinfachter Iterator - Hierarchie der Level - Skriptprinzip (Iterator) 6.2 Konstruktoren und Arrays: Wunder der Technik - Woraus besteht ein Objekt? => Teilung schwergewichtiger Ressourcen 6.3 Zusatzinformationen: - Hintergrundbild, Scrolling, Musik, besondere Ereignisse

sr038 && tf Ein vereinfachter Iterator > + hasNextStep() : boolean + nextStep() : void + putWallsIntoList() : void + putEnemiesIntoList() : void Level + nextStep() : void + putWallsIntoList() : void + putEnemiesIntoList() : void Hierarchie der Level Level1_1 - enemyArray : IEnemy [ ] [ ] - wallArray : IWall [ ] [ ] + hasNextStep() : boolean Der levelManager() in der Session iteriert mit den Methoden hasNextStep() und nextStep() über die Arrays der konkreten Level. => Das Level wird wie ein Skript abgearbeitet.

sr038 && tf Konstruktoren und Arrays Erzeugung der Feinde und Wände => Alle im Level vorkommenden Objekte werden beim Laden des Levels im Konstruktor initialisiert und in Arrays gespeichert. Dadurch gibt es praktisch kein new zur Laufzeit. => Vor beginn des Levels sind bereits alle Feinde komplett einsatzbereit zusammengebaut (inklusive aller denkbaren Verhaltensmuster). => Eine so riesige Menge von Objekten im Speicher zu halten, ist kein Problem, da alle schwergewichtigen Resourcen (Bilder, Sounds,...) über Datenbanken geteilt werden. Somit besteht ein konkreter Feind nur aus ein paar Zahlenwerten und benötigt kaum Speicherplatz. => Zur Laufzeit des Spiels werden lediglich Referenzen kopiert bzw. verschoben (Level => Session) und nur in Sonderfällen neu erzeugt.

sr038 && tf Konstruktoren und Arrays Erzeugung der Feinde und Wände II: Codebeispiel public class Level1_1 extends Level { //... private IEnemy[][] enemyArray = new IEnemy[5000][]; //... IEnemy[] e101; //... public Level1_2(Session session) { //... e101 = new IEnemy[] { new Fighter5(session) }; e101[0].setPosition(500, 0); e101[0].setMovePattern(new PointMovePattern( e101[0], session.pointListData.getDropIn(true, 100, 5))); e101[0].setShoot( EnemyShoot.ROUNDFIREBALL1, session.shootBehaviorData.shootRepeatedlyToKarl(80, 6)); //... enemyArray[101] = e101; //... }

sr038 && tf Zusatzinformationen Hintergrundbild, Scrolling, Musik, besondere Ereignisse => Das Level kann zu jedem beliebigen Zeitpunkt angehalten werden: + stopLevel() : boolean Beliebige Bedingungen, z.B. Endgegner im Bild, sind möglich. => Informationen über Scrolling-Verhalten: - weit entferntes Hintergrundbild - näheres Hintergrundbild - Wände Alle drei Schichten können sowohl einzeln, als auch in Abhängigkeit zueinander bewegt werden. => Es können zu beliebigen Zeitpunkten Musikstücke oder Geräusche abgespielt oder gestoppt werden. => Beim Start eines Levels kann eine Animation abgespielt werden. => Zur Laufzeit kann jedes Objekt beliebig manipuliert werden.

sr038 && tf Schussverhalten - Datenbanken für Sound und Grafik - Vererbungshierarchien im Detail - Animationen: => Zwischensequenzen - Auch Feinde haben das Recht recycelt zu werden! - Viele bunte Items - Karls magisches Schutzschild - Zusammenspiel und Abhängigkeiten zwischen Objekten: => Wände und Feinde - Intelligente Feinde - Animierte Feinde - Die Pausefunktion: versteckte Problematik - Ein Ladebildschirm - Geschichten eines Entwicklers: => Nette Bugs! (Freude am Iterator) 7. Der Punkt, zu dem wir nicht mehr kommen werden, falls doch:

sr038 && tf Danksagung und Ressourcen Großen Dank an Tobias Herborth für seine Nachhilfe in Sachen Animation, Threads und Softwaredesign.... Rebecca Trippe für ihre tollen Charakterdesigns und Spielgrafiken.... Nicolas Schmid für nützliche Tipps und seine ausgiebigste Misshandlung unserer Engine.... Herrn Walter Kriha für sein Talent, uns massiv zu motivieren.... alle Studenten, die uns durch ihre Design Patterns Präsentation in vielerlei Hinsicht die Augen geöffnet haben.... nicht zuletzt alle Testspieler, Kritiker und Versuchkaninchen (Die Flosse bleibt!) Ressourcen: - GOF-Book (Die Pattern-Bibel) Spieleentwicklung in Java: - Java2D, OReilly-Verlag