JOGL Ausarbeitung im Rahmen der Lehrveranstaltung „Graphische Interaktive Systeme“ Haitham Hamdani WS 2010/2011 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 Gliederung 1. Zusammenfassung ............................................................................ 3 2. Was ist JOGL? ................................................................................... 3 2.1. Kurze Beschreibung .......................................................................................... 3 2.2. Die wichtigsten Klassen und Interfaces ............................................................. 3 3. Installation .......................................................................................... 4 3.1. Download .......................................................................................................... 5 3.2. Einbindung in Eclipse ........................................................................................ 6 3.3. Ein erstes Eclipse Projekt ................................................................................ 12 3.3.1. Fenster erzeugen ..................................................................................... 12 3.3.2. Dreieck zeichnen...................................................................................... 13 3.4. Einige Unterschiede JOGL 1.x zu JOGL 2.0 .................................................. 14 4. Fallbeispiel: Pacman........................................................................ 16 4.1. Spielbeschreibung / Konzept ........................................................................... 16 4.2. Werkzeuge und Betriebsmittelumgebung ........................................................ 17 4.3. Pacman und Labyrinth zeichnen ..................................................................... 17 4.3.1. Pacman zeichnen..................................................................................... 17 4.3.2. Labyrinth zeichnen ................................................................................... 18 4.4. Auf Tastaturereignisse reagieren .................................................................... 19 4.5. Pacman animieren .......................................................................................... 21 4.6. Kollisionskontrolle............................................................................................ 23 5. Diskussion und Fazit ....................................................................... 24 6. Anhang ............................................................................................. 25 6.1. Abkürzungsverzeichnis ................................................................................... 25 6.2. Abbildungsverzeichnis..................................................................................... 25 6.3. Quellen ............................................................................................................ 26 6.4. Klassendiagramm Pacman ............................................................................. 27 6.5. Aufwandsdarstellung ....................................................................................... 28 6.6. readme.txt ....................................................................................................... 29 Seite 2 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 1. Zusammenfassung In dieser Ausarbeitung wird ein Überblick über die Bibliothek JOGL in der neuesten Version 2.0 gegeben. Dabei wird kurz auf die wichtigsten Klassen eingegangen und anschließend der Download, die Installation und die Einbindung in Eclipse erklärt. Anhand eines kleinen Tutorials wird ein erstes Projekt in Eclipse erstellt, welches ein Dreieck in einem Fenster zeichnet. Anschließend wird gezeigt, wie man ein 2D-Spiel in JOGL implementiert. Dazu wurde ein Pacman-Spiel programmiert, das auf die Tastaturereignisse reagiert und sich mit der Kollisionskontrolle beschäftigt. 2. Was ist JOGL? Dieses Kapitel gibt eine kurze Beschreibung von JOGL und nennt die wichtigsten Klassen und Interfaces. 2.1. Kurze Beschreibung Java Bindings for OpenGL (JOGL) ist ein Open-Source Projekt, das im Jahr 2003 von Sun Microsystems und Silicon Graphics Incorporated (SGI) gestartet wurde.1 Ziel dieses Projekts ist die Möglichkeit, die Programmiersprache Java bei der Spielentwicklung einzusetzen. Mit Hilfe von JOGL kann der Javaprogrammierer auf alle Funktionen von OpenGL zugreifen. Die aktuelle Version ist JOGL 2.0, die auch in dieser Ausarbeitung verwendet wird. 2.2. Die wichtigsten Klassen und Interfaces In diesem Abschnitt werden die wichtigsten Klassen erläutert, die man für die Umsetzung von JOGL-Projekten braucht. - GLEventListener: ist ein Interface, das die auftretenden Ereignisse behandelt bzw. verarbeitet. Es ist in der Regel wie die anderen Java-Event-Listener zu betrachten. Wenn eine Klasse das Interface implementiert, dann muss sie folgende Methoden überschreiben: init(), reshape(), display(), dispose(). Näheres im Kapitel 3.3.2. 1 Vgl. o.V., [1]. Seite 3 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani - WS 2010/2011 FPSAnimator: ist die Subklasse der Klasse Animator und wird für die Animation der Objekte benutzt, indem sie in vorgegebenen Abständen die display() – Methode aufruft. Man kann dem FPSAnimator-Konstruktor die Anzahl der Frames pro Sekunde übergeben, um festzulegen, wie oft die display() –Methode aufgerufen wird. - KeyListener: ist ein Java-Interface(nicht JOGL-spezifisch), das die Tastaturereignisse mit Hilfe seiner drei Methoden keyPressed(), keyReleased(), keyTyped() verarbeitet. Eine genauere Beschreibung wird in Kapitel 4.4 gegeben. - GLU: OpenGL Utility Library ist eine sehr wichtige Bibliothek, mit der man verschiedene Geometrie Primitiven darstellen kann. Diese arbeitet nach dem "Quadrics"-Konzept. - GL2: ist das Interface, das nur in der neuen Version benutzt wird und den Zugriff auf alle OpenGL-Funktionen bietet. - GLCanvas: ist eine Unterklasse der Klasse Canvas und implementiert das Interface AWTGLAutoDrawable. Sie symbolisiert eine Fläche, auf der man die Geometrie Daten zeichnen kann. - GLAutoDrawable: ist eine Unterklasse der Klasse GLDrawable, die sich mit dem OpenGL-Rendering beschäftigt, sodass für jedes ausgelöste Ereignis versucht wird, das aktuelle Rendering zu optimieren. 3. Installation Dieses Kapitel geht auf den Download und die Einbindung der JOGL-Bibliothek in Eclipse ein. Anschließend wird ein kleines Beispielprojekt erläutert, was ein Fenster erzeugt und ein Dreieck zeichnet. Zum Schluss wird noch kurz auf Unterschiede in der Programmierung der aktuellen JOGL-Version 2.0 im Vergleich zur Vorgängerversion eingegangen. Seite 4 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 3.1. Download Bevor man JOGL installiert, sollte man zuerst überprüfen, ob Java Development Kit (JDK mindestens in der Version 1.4.2.) auf dem Rechner installiert ist. Das kann man auf der Kommandozeile mit dem Befehl " java –fullversion" herausfinden. Falls das JDK noch nicht installiert ist, kann man es von Sun (www.java.sun.com) herunterladen und installieren. Der zweite Schritt ist das Herunterladen von JOGL auf http://jogamp.org. Dabei sollte die Version unter dem Link "Signed Release" gewählt werden, wie in Abb.: 3.1-1 Abb.: 3.1-1 dargestellt. Bei ihr handelt es sich um die stabilste und von JogAmp empfohlene Version. Abb.: 3.1-1 Startseite JogAmp Auf der folgenden Seite muss dann die passende JOGL-Version gefunden werden. Wenn man nicht einzelne jar-Archive herunterladen möchte, bietet es sich an, in den Seite 5 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 Ordner "archive" zu wechseln (sieheAbb.: 3.1-2) und dort die benötigte JOGL-Version herunter zu laden. Abb.: 3.1-2 JOGL Downloadseite Übersicht Für ein 32-bit Windows-System wählt man die zip-Datei mit der Endung "windows-i586" aus, für andere Betriebssysteme entsprechend eine der anderen Dateien. Die JavadocDateien können ebenfalls heruntergeladen werden (siehe Abb.: 3.1-3). Abb.: 3.1-3 JOGL Downloadseite Archive Anschließend müssen die heruntergeladenen Dateien nur noch entpackt werden, um mit der Einbindung in Eclipse zu starten. 3.2. Einbindung in Eclipse Es gibt mehrere Möglichkeiten, die JOGL-Bibliotheken in Eclipse zu verwenden. Eine Möglichkeit ist, sie direkt in das JDK / JRE Installationsverzeichnis zu importieren. Man kann auch ein eigenes Verzeichnis für die Bibliotheksdateien anlegen (z.B. "C:\lib\jogl- Seite 6 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 2.0") und dieses dann in sein Projekt importieren. Eine genauere Anleitung ist unter: https://sites.google.com/ssite/justinscsstuff/jogl-tutorial-1 zu finden. In dieser Ausarbeitung werden die benötigten JOGL-Dateien direkt im Projekt gespeichert. Das hat den Vorteil, dass man das Projekt auf unterschiedlichen Rechnern ausführen kann, ohne dass man die Bibliothek neu einbinden muss. Um JOGL einbinden zu können, muss man zuerst ein Projekt erzeugen, in dem man auf File -> New -> Java Project geht (siehe Abb.: 3.2-1). Abb.: 3.2-1 Eclipse: neues Java Projekt anlegen Nun geht man auf Dateiebene zum erzeugten Projekt und legt zwei neue Ordner "jar" und "lib" an (siehe Abb.: 3.2-2). Danach wechselt man zu den entpackten Dateien und kopiert aus dem "jar"-Ordner die folgenden Dateien: "gluegen-rt.jar", "jogl.all.jar", "nativewindow.all.jar" und "newt.all.jar". Diese legt man dann in seinem eigenen Projekt im "jar"-Ordner ab (siehe Abb.: 3.2-3). Anschließend kopiert man den kompletten Inhalt des entpackten "lib"-Ordners in den entsprechenden "lib"-Ordner des eigenen Projekts (siehe Abb.: 3.2-4). Abb.: 3.2-2 Ordnerstruktur Abb.: 3.2-3 Inhalt Ordner Abb.: 3.2-4 Inhalt Ordner Projekt "jar" "lib" Seite 7 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 Damit die neuen Ordner und Dateien auch in Eclipse sichtbar werden, muss man im Package Explorer einmal F5 drücken. Jetzt müssen in dem neuen Projekt die eingefügten Dateien verlinkt werden. Dazu klickt man rechts auf das aktuelle Projekt und wählt Build Path -> Configure Build Path aus (siehe Abb.: 3.2-5). Abb.: 3.2-5 Eclipse: Build Path konfigurieren Seite 8 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 Danach kommt man auf das folgende Fenster (Abb.: 3.2-6). Mit "Add JARs…" kann man die JAR-Dateien zum Projekt hinzufügen. Abb.: 3.2-6 Eclipse: neue JAR-Datei zum Projekt hinzufügen Seite 9 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 Man wählt die entsprechenden JAR-Dateien aus dem "jar" –Ordner des eigenen Projekts aus (siehe Abb.: 3.2-7). Abb.: 3.2-7 Eclipse: JAR-Dateien auswählen Nun fehlt noch die Einbindung des "lib"-Ordners (.dll Dateien). Dazu wählt man zuerst "Native library location" aus, dann klickt man auf "Edit" dann auf "Workspace" (siehe Abb.: 3.2-8). Abb.: 3.2-8 Eclipse: Bibliotheken von JAR-Dateien einbinden Seite 10 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 Hier wählt man den "lib"-Ordner des eigenen Projekts aus. Das Gleiche wird auch bei den restlichen "Native library location" gemacht (siehe Abb.: 3.2-9). Abb.: 3.2-9 Eclipse: Bibliothekspfad auswählen Das Bibliotheksfenster sollte nun wie Abb.: 3.2-10 aussehen. Dabei sind sowohl die JAR-Dateien als auch die DLL-Dateien über relative Pfade eingebunden. Will man die Javadoc-Dateien in sein Eclipse-Projekt einbinden, passt man den Punkt "Javadoc location" an. Abb.: 3.2-10 Eclipse: Eingebundene JAR-Dateien Seite 11 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 Nur noch mit "OK" bestätigen und der Package Explorer sollte wie in Abb.: 3.2-11 aussehen. Abb.: 3.2-11 Eclipse: fertige Projektstruktur 3.3. Ein erstes Eclipse Projekt In diesem Abschnitt wird ein erstes Fenster erzeugt und darin ein Dreieck gezeichnet. 3.3.1. Fenster erzeugen Jogl stellt die Klasse GLCanvas bereit, die von der AWT Component Klasse abgeleitet ist und somit ohne Probleme wie jede andere AWT-Komponente benutzt werden kann. Folgende Schritte sind für das Erzeugen eines Fensters einzuhalten: 1. Wählen eines GLProfile 2. Konfigurieren von GLCapabilities 3. Erzeugen eines GLCanvas 4. Erzeugen eines Frames, dem das GLCanvas-Objekt übergeben wird. Hier ist ein sehr einfaches Beispiel, wie man ein AWT-Fenster erzeugt und zum laufen bringt.1 1 Vgl. Stoecker, Justin, [2]. Seite 12 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani import import import import import WS 2010/2011 java.awt.Frame; java.awt.event.WindowAdapter; java.awt.event.WindowEvent; javax.media.opengl.*; javax.media.opengl.awt.GLCanvas; public class FensterErzeugen { public static void main(String[] args) { GLProfile.initSingleton(true); //Schritt 1 GLProfile glp = GLProfile.getDefault(); //Schritt 1 GLCapabilities caps = new GLCapabilities(glp); //Schritt 2 GLCanvas canvas = new GLCanvas(caps); //Schritt 3 Frame frame = new Frame("AWT Window Test"); frame.setSize(300, 300); frame.add(canvas); //Schritt 4 frame.setVisible(true); // EventListener um Fenster zu schließen frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); } } 3.3.2. Dreieck zeichnen Als ersten Schritt zum Zeichnen muss die Klasse FensterErzeugen das Interface GLEventListener implementieren. public class FensterErzeugen implements GLEventListener Dieses Interface erfordert es, folgende Methoden zu überschreiben: 1. public void init(GLAutoDrawable drawable) : OpenGL Initialisierungscode 2. public void display(GLAutoDrawable drawable): OpenGL Zeichnen (Geometriedaten) 3. public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height): Wird aufgerufen, wenn die Fenstergröße sich ändert. 4. public void dispose(GLAutoDrawable drawable): Aufräumarbeiten zu Programmende Seite 13 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 Im zweiten Schritt muss dem GLCanvas-Objekt ein GLEventListener zugeordenet werden. Dieser GLEventListener ist in unserem Beispiel die Klasse FensterErzeugen. Folgender Code wird der main-Methode hinzugefügt. canvas.addGLEventListener(new FensterErzeugen()); Jetzt kann mit dem Zeichnen in der display-Methode begonnen werden. In diesem Fall ein Dreieck1(siehe Abb.: 3.3-1). public void display(GLAutoDrawable drawable) { GL2 gl = drawable.getGL().getGL2(); //alle Pixel auf schwarz setzen gl.glClear(GL.GL_COLOR_BUFFER_BIT); //Dreieck zeichnen gl.glBegin(GL.GL_TRIANGLES); gl.glColor3f(1, 0, 0); gl.glVertex2f(-1, -1); gl.glColor3f(0, 1, 0); gl.glVertex2f(0, 1); gl.glColor3f(0, 0, 1); gl.glVertex2f(1, -1); gl.glEnd(); } Abb.: 3.3-1 Ausgabefenster Beispielprojekt Dreieck 3.4. Einige Unterschiede JOGL 1.x zu JOGL 2.0 In diesem Abschnitt wird gezeigt, wie man ein Programm, das in JOGL 1.x erstellt wurde in JOGL 2.0 portiert. Mit Hilfe der folgenden Lösungsvorschläge kann man alte Tutorial-Beispiele in der aktuellen Version 2.0 ausführen: 1. Es wird keine GLDrawableFactory mehr für die Erzeugung des canvas-Objekts benötigt. Dieses kann nun durch den Aufruf seines Konstruktors erzeugt werden. 2. Der Konstruktor von GLCapabilities erwartet ein GLProfile-Objekt als Übergabeparameter. 1 Vgl. Stoecker, Justin, [3]. Seite 14 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 Version 1.x GLCapabilities glcaps = new GLCapabilities(); GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(glcaps); Version 2.0 GLProfile.initSingleton(true); GLProfile glp = GLProfile.getDefault(); GLCapabilities caps = new GLCapabilities(glp); GLCanvas canvas = new GLCanvas(caps); 3. Das GLEventListener-Interface verwendet anstatt der Methode public void displayChanged(GLDrawable arg0, boolean arg1, boolean arg2) die Methode public void dispose(GLAutoDrawable arg0). 4. Den vier überschriebenen Methoden von GLEventListener wird ein GLAutoDrawable-Objekt übergeben, anstatt eines GLDrawable-Objekts. 5. Es wird nicht mehr mit einem Objekt der Klasse GL gearbeitet, sondern mit einem Objekt der Klasse GL2. Das bedeutet auch, man muss alle Übergabeparameter vom Datentyp GL entsprechend in GL2 ändern, z.B. private void setCamera(GL gl, GLU glu) in private void setCamera(GL2 gl, GLU glu). 6. Objekte der Klasse GLU werden nun direkt durch Aufruf des GLU-Konstruktors erzeugt. 7. Der Zugriff auf alle statischen Variablen von GL z.B. gl.glMatrixMode(GL.GL_MODELVIEW); werden auf statische Variablen der Klasse GL2 geändert z.B. gl.glMatrixMode(GL2.GL_MODELVIEW) Seite 15 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 Version 1.x public void init(GLDrawable arg0) { GL gl = arg0.getGL(); GLU glu = arg0.getGLU(); gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); gl.glMatrixMode(GL.GL_MODELVIEW); } Version 2.0 public void init(GLAutoDrawable arg0) { GL2 gl = arg0.getGL().getGL2(); GLU glu = new GLU(); gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); gl.glMatrixMode(GL2.GL_MODELVIEW); } 8. Einige Methoden müssen zusätzliche Übergabeparameter erhalten, wie z.B. gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, light_pos,0), hier ist der letzte Parameter neu (int params_offset). 9. Für Texturen: das Attribut BufferUtils.SIZEOF_INT gibt es nicht mehr, stattdessen kann GLBuffers.SIZEOF_INT benutzt werden. Auf dem Objekt von ByteBuffer muss zusätzlich die Methode rewind() aufgerufen werden. 4. Fallbeispiel: Pacman Dieses Kapitel beschreibt das Fallsbeispiel dieser Ausarbeitung. Dabei wird auf die wichtigsten Aspekte der Programmierung eingegangen. Im Anhang unter 6.4 ist ein vollständiges Klassendiagramm des Projekts zu sehen. 4.1. Spielbeschreibung / Konzept Das Pacman-Spiel besteht aus einer Spielfigur, die Punkte in einem Labyrinth isst. Wenn man alle Punkte gegessen hat, kommt man zum nächsten Level. Der Benutzer kann sein Labyrinth bzw. sein Level in einer csv-Datei zeichnen, ohne den Quelltext ändern zu müssen, da das Programm diese automatisch einliest. Der Benutzer kann folgender Tasten benutzen um das Spiel zu steuern: - Taste Links: Pacman geht nach links - Taste Rechts: Pacman geht nach rechts - Taste Unten: Pacman geht nach unten Seite 16 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 - Taste Oben: Pacman geht nach oben - Escape: Programm beenden Leider hat die Zeit nicht ausgereicht, um die Gespenster zu implementieren, die den Pacman kollisionsfrei verfolgen und versuchen ihn zu zerstören. Dies wurde mit Prof. Dr. Heinzel abgesprochen. 4.2. Werkzeuge und Betriebsmittelumgebung Das Spiel wurde unter Microsoft Windows XP Professional Version 2002 Service Pack 3 entwickelt. Als Grafikkarte wurde eine ATI Radeon X1250 mit 128 MB Speicher verwendet. Programmierumgebung war Eclipse Java EE IDE for Web Developers. JOGL wurde in der aktuellsten Version 2.0 verwendet. 4.3. Pacman und Labyrinth zeichnen Dieses Kapitel beschäftigt sich mit der Darstellung des Pacmans und des Labyrinths. 4.3.1. Pacman zeichnen Um die Pacman-Figur zu realisieren, wurde der Befehl gluPartialDisk verwendet, der einen Ausschnitt einer Scheibe zeichnet (siehe Abb.: 4.3-2). Abb.: 4.3-1 Pacman Abb.: 4.3-2 Partielle Disk mit Loch Quelle: o.V., [4] Folgender Code erzeugt den Pacman aus Abb.: 4.3-1: gl.glColor3f(1.0f, 1.0f, 0.0f); glu.gluPartialDisk(form, 0, radius, 20, 1, winkelStart, winkelGroesse); Seite 17 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 Folgende Übergabeparameter wurden ausgewählt: quadObject form ist vom Typ GLUquadric und gibt das Quadric-Objekt an. innerRadius outerRadius slices loops startAngle sweepAngle Definiert den inneren Radius der Scheibe. Es wurde 0 gewählt, um eine ausgefüllte Scheibe zu erhalten. Definiert den äußeren Radius der Scheibe. Orientiert sich an der Fenstergröße. Gibt die Anzahl der Unterteilungen um die Z-Achse an. (Vergl. Pizzastücke) Bei 20 sieht der Pacman relativ rund aus. Gibt die Anzahl der konzentrischen Ringe um das Zentrum an, in welche die Scheibe unterteilt ist. 1 ist völlig ausreichend für den Pacman. Definiert den Startwinkel des Scheibenausschnitts in Grad. Es wurde 0 bei der Initialisierung gewählt. Definiert die Größe des Scheibenausschnitts in Grad. Es wurde 310 bei der Initialisierung gewählt. Tabelle 4.3-1 Übergabeparameter von gluPartialDisk Quelle: Vgl. o.V., [4] 4.3.2. Labyrinth zeichnen Das Labyrinth kann für jedes Level mit Hilfe einer csv-Datei erstellt werden (siehe Abb.: 4.3-3). Um das Labyrinth zu zeichnen, wurde das Fenster in Spalten und Zeilen eingeteilt. Die Anzahl der Zeilen und Spalten kann variieren, je nachdem welches Level gerade geladen ist. Die rechteckigen Zellen werden über die Klasse Zelle repräsentiert. Ihre Größe ist abhängig von der Fenstergröße. Es gibt drei verschiedene Arten von Zellen: 1. Labyrinthelement 2. freie Zelle mit Essen 3. freie Zelle ohne Essen Labyrinthelemente werden als blaue Rechtecke mit Hilfe der Methode glRectf() gezeichnet: void glRectf(float x1, float y1, float x2, float y2) Seite 18 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 Für freie Zellen mit Essen wird die Methode gluDisk() verwendet. Das Essen skaliert ebenfalls mit der Fenstergröße. public final void gluDisk(GLUquadric quad, double inner, double outer, int slices, int loops) Die csv-Datei muss folgender Maßen aufgebaut sein: In der ersten Zeile stehen die Anzahl der Spalten(A1) und Zeilen(B1). Da in dem Projekt ein quadratisches Fenster erzeugt wird (600x600), sollte die gleiche Anzahl an Spalten und Zeilen verwendet werden. Danach werden Labyrinthelemente mit 'x', freie Zellen mit '0' und die Startposition von Pacman mit 'p' gekennzeichnet (vgl. Abb.: 4.3-3 und Abb.: 4.3-4). Abb.: 4.3-3 Labyrinth in Excel Abb.: 4.3-4 Labyrinth im Spiel 4.4. Auf Tastaturereignisse reagieren Um auf die Tastaturereignisse reagieren zu können, muss man in Java das Interface KeyListener in der entsprechenden Klasse implementieren. In diesem Projekt ist das die Klasse Fensterinhalt. Dieses Interface erfordert es, folgende Methoden zu überschreiben: 1. public void keyPressed(KeyEvent e): wird aufgerufen, wenn eine Taste gedrückt wird. 2. public void keyReleased(KeyEvent e): wie der Name schon sagt, wird aufgerufen, wenn die Taste losgelassen wird. 3. public void keyTyped(KeyEvent e): wird aufgerufen, wenn die Taste kurz gedrückt und gleich wieder losgelassen wird. Seite 19 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 In diesem Spiel wurde nur die Methode keyPressed () verwendet, weil man nur einmal auf die Taste drücken muss, damit der Pacman in die entsprechende Richtung läuft. Folgender Code wurde für die Tastaturereignisse verwendet public void keyPressed(KeyEvent arg0) { int keyCode = arg0.getKeyCode(); if (keyCode == KeyEvent.VK_ESCAPE) System.exit(0); if (keyCode == KeyEvent.VK_RIGHT) { //rechts pacman.setRichtung(2); } if (keyCode == KeyEvent.VK_LEFT) { //links pacman.setRichtung(0); } if (keyCode == KeyEvent.VK_UP) { //oben pacman.setRichtung(1); } if (keyCode == KeyEvent.VK_DOWN) { //unten pacman.setRichtung(3); } } Seite 20 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 4.5. Pacman animieren Das Projekt basiert auf dem in Abb.: 4.5-1 dargestellten Diagramm. Diese Aufteilung des Programmcodes wird für das Rendern von Spielen in Echtzeit empfohlen. Es ist in kleineren Projekten zwar auch möglich, die drei Schritte in der Game Loop zu einem zusammen zu fassen, aber aufgrund der besseren Übersichtlichkeit und eines besseren Programmentwurfs ist es empfehlenswert, diese Schritte zu trennen. Abb.: 4.5-1 Darstellung Game Loop Quelle: Stoecker, Justin, [3] Hier eine kurze Erklärung der einzelnen Schritte inklusive Erläuterung, wie jeder Schritt im Pacman-Projekt umgesetzt wurde (siehe auch Abb.: 4.5-2): Initialization: Initialisierungscode, wie z.B. GLProfile wählen und GLCapabilities konfigurieren oder den Animator-Thread starten. Dies wird in der Klasse Steuerung und in der init-Methode der Klasse Fensterinhalt implementiert. Process input: auf Maus- und Tastatur-Events reagieren. Die Klasse Fensterinhalt überschreibt dafür die Methode KeyPressed des Interface KeyListener (siehe Kapitel 4.4). Aus dieser Methode wird setRichtung() in der Pacman-Klasse aufgerufen (siehe Code in Kapitel 4.4). Die Methode setRichtung setzt die Attribute 'richtung' und 'winkelStart'. Eine Wirkung auf die Darstellung des Pacman ergibt sich allerdings erst, Seite 21 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 wenn die display-Methode der Klasse Fensterinhalt das nächste Mal vom FPSAnimator (siehe Kapitel 2.2 Klasse FPSAnimator) aufgerufen wird. Um eine Trennung der Schritte 'render' und 'simulate game world' zu realisieren, wird die display-Methode der Klasse Fensterinhalt in die beiden Methoden 'aktualisiere()' und 'zeichne()' aufgeteilt. Render: Geometriedaten zeichnen. Entspricht der Methode 'zeichne()' der Klasse Fensterinhalt. Diese ruft jeweils die zeichne-Methode der Klassen Pacman und Labyrinth auf. Simulate game world: Geometriedaten neu berechnen. Entspricht der aktualisiereMethode von Fensterinhalt, welche die aktualisiere-Methode von Pacman aufruft. In der aktualisiere-Methode werden die Mundöffnung und die Position des Pacmans neu berechnet. Shut down: Daten speichern und Resourcen freigeben. Entspricht dispose-Methode der Klasse Fensterinhalt1 Abb.: 4.5-2 Klassendiagramm-Ausschnitt Fensterinhalt und Pacman 1 Vgl. Stoecker, Justin, [3] Seite 22 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 4.6. Kollisionskontrolle Die Kollisionskontrolle bestimmt, wie der Pacman auf andere Objekte des Spiels reagiert. Wie bereits in Kapitel 4.3.2 erläutert, ist das Labyrinth in Zeilen und Spalten aufgeteilt. Dadurch entstehen Zellen, die durch die Klasse Zelle repräsentiert werden. Bei der Kollisionskontrolle muss verhindert werden, dass der Pacman in den Bereich einer Zelle eintritt, die als Labyrinthelement (Hindernis) markiert ist. Dazu wird in der Klasse Labyrinth die Methode 'istFrei()' implementiert, welche die zukünftige Zelle des Pacmans ermittelt und überprüft. Ist diese kein Labyrinthelement, wird 'true' zurückgegeben, ansonsten 'false'. In der aktualisiere-Methode des Pacmans wird die istFrei-Methode aufgerufen, bevor die neue Position des Pacmans berechnet wird. Gibt die istFrei-Methode 'false' zurück, bleibt der Pacman in seiner alten Position stehen. Bei der ursprünglichen Umsetzung der istFrei-Methode haben wir zunächst nur die x und y Koordinaten des Pacmans (den Mittelpunkt) + den Radius übergeben. Dargestellt durch den roten Punkt in Abb.: 4.6-1. public boolean istFrei(int x, int y) Abb.: 4.6-1 Übergabepunkt ursprüngliche Kollisionskontrolle Dies führte zu dem in Abb.: 4.6-2 dargestellten Effekt, wenn man seitlich auf ein Hindernis zulief. Es wurde das Hindernis in Laufrichtung gut erkannt, aber Hindernisse parallel zur Laufrichtung führten zum dargestellten Effekt. Abb.: 4.6-2 ursprünglicher Fehler bei Kollisionsberechnung Seite 23 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 Die Lösung lag in der Überprüfung von 2 Punkten, nämlich dem oberen und unteren Punkt von Pacman aus gesehen in Laufrichtung. (siehe Abb.: 4.6-3) public boolean istFrei(int x1, int y1, int x2, int y2) Abb.: 4.6-3 Übergabepunkte aktuelle Kollisionskontrolle 5. Diskussion und Fazit Mir hat das Programmieren in JOGL sehr viel Spaß gemacht, man kann sogar süchtig danach werden. Ich hätte gerne das Spiel weiter entwickelt, aber leider hat die Zeit dafür nicht ausgereicht. Ich hoffe, dass ich mit meiner Ausarbeitung zeigen konnte, wie man sehr schnell in JOGL einsteigen kann bzw. wie man ein kleines Spiel implementieren kann. Die OpenGL-Programmierer haben mit JOGL einen großen Vorteil, weil sie mit allen OpenGL-Funktionen weiter arbeiten können. Bei der Installation von JOGL sind kleine Probleme aufgetaucht, wie der Umzug der Webseite und die ständige Veränderung des Inhalts der neuen Webseite, die nicht sehr übersichtlich ist. JOGL entwickelt sich sehr schnell, was dazu geführt hat, dass die vielen Beispiele und Tutorials im Internet veraltet sind und somit kaum verwendbar in der aktuellen Version. Seite 24 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 6. Anhang 6.1. Abkürzungsverzeichnis JOGL Java Bindings for OpenGL SGI Silicon Graphics Incorporated JDK Java Development Kit JRE Java Runtime Environment 6.2. Abbildungsverzeichnis Abb.: 3.1-1 Startseite JogAmp ......................................................................................... 5 Abb.: 3.1-2 JOGL Downloadseite Übersicht .................................................................... 6 Abb.: 3.1-3 JOGL Downloadseite Archive ....................................................................... 6 Abb.: 3.2-1 Eclipse: neues Java Projekt anlegen ............................................................ 7 Abb.: 3.2-2 Ordnerstruktur Projekt ................................................................................... 7 Abb.: 3.2-3 Inhalt Ordner "jar".......................................................................................... 7 Abb.: 3.2-4 Inhalt Ordner "lib" .......................................................................................... 7 Abb.: 3.2-5 Eclipse: Build Path konfigurieren................................................................... 8 Abb.: 3.2-6 Eclipse: neue JAR-Datei zum Projekt hinzufügen ......................................... 9 Abb.: 3.2-7 Eclipse: JAR-Dateien auswählen ................................................................ 10 Abb.: 3.2-8 Eclipse: Bibliotheken von JAR-Dateien einbinden....................................... 10 Abb.: 3.2-9 Eclipse: Bibliothekspfad auswählen ............................................................ 11 Abb.: 3.2-10 Eclipse: Eingebundene JAR-Dateien ........................................................ 11 Abb.: 3.2-11 Eclipse: fertige Projektstruktur................................................................... 12 Abb.: 3.3-1 Ausgabefenster Beispielprojekt Dreieck ...................................................... 14 Abb.: 4.3-1 Pacman ....................................................................................................... 17 Abb.: 4.3-2 Partielle Disk mit Loch................................................................................. 17 Abb.: 4.3-3 Labyrinth in Excel ........................................................................................ 19 Abb.: 4.3-4 Labyrinth im Spiel........................................................................................ 19 Abb.: 4.5-1 Darstellung Game Loop .............................................................................. 21 Abb.: 4.5-2 Klassendiagramm-Ausschnitt Fensterinhalt und Pacman ........................... 22 Abb.: 4.6-1 Übergabepunkt ursprüngliche Kollisionskontrolle ....................................... 23 Abb.: 4.6-2 ursprünglicher Fehler bei Kollisionsberechnung.......................................... 23 Abb.: 4.6-3 Übergabepunkte aktuelle Kollisionskontrolle ............................................... 24 Seite 25 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 6.3. Quellen [1] o.V.: JOGL, 12/10, http://de.wikipedia.org/wiki/JOGL, 29. Dez. 2010 [2] Stoecker, Justin: JOGL Tutorial 2 - Creating a Window, o.J., https://sites.google.com/site/justinscsstuff/jogl-tutorial-2, 02. Jan. 2011 [3] Stoecker, Justin: JOGL Tutorial 3 - Creating a Render Loop, o.J., https://sites.google.com/site/justinscsstuff/jogl-tutorial-2, 02. Jan. 2011 [4] o.V.: gluPartialDisk, 03/09, https://sites.google.com/site/justinscsstuff/jogltutorial-2, 02. Jan. 2011 Seite 26 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 6.4. Klassendiagramm Pacman Seite 27 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 6.5. Aufwandsdarstellung Informationsbeschaffung: 20 Std. Programmierarbeit: 25 Std. Dokumentation: 35 Std. Präsentation: 08 Std. Fehlersuche: 05 Std. Gesamt: 93 Std. 35 30 25 Informationbeschaffung Programmierarbeit Dokumentation Präsentation Fehlersuche 20 15 10 5 0 Seite 28 von 29 Graphische Interaktive Systeme - JOGL Haitham Hamdani WS 2010/2011 6.6. readme.txt Dateistruktur des Datenträgers: internetquellen Ordner mit allen Internetquellen programm |- ausfuehrbare_jar_datei Ordner mit Fallbeispiel Pacman Ordner mit ausführbarer jar-Datei von Pacman Ordner mit Eclipse-Projekt. Dieses enthält das Tutorial zum Zeichnen eines Dreiecks und das Pacman-Spiel |- eclipse_projekt dokumentation_jogl_haitham_hamdani.pdf Datei mit der Dokumentation des Projekts praesentation_jogl_haitham_hamdani.odp Datei mit der Präsentation des Projekts readme.txt Datei mit Dateistruktur des Datenträgers Seite 29 von 29