Java ME

Transcrição

Java ME
Fachhochschule Fulda
Angewandte Informatik – Applied Computer Science
Ausarbeitung
M3G auf Symbian OS (Java ME) –
mit ergänzender schwerpunktmäßiger Betrachtung der
2D Spieleentwicklung auf Java ME
Betreuer :
Prof. Dr. Werner Heinzel
Bearbeitet von:
Christian Burmeister
Abgabetermin:
07.01.2009
I
NHALT
1. Kurzzusammenfassung......................................................................................3
2. Einleitung.............................................................................................................3
3. Java für mobile Endgeräte.................................................................................4
3.1 Konfigurationen, Profile und optionale Pakete ..................................................................... 4
3.1.1 Konfigurationen ........................................................................................................... 5
3.1.1.1 CLDC (Connected Limited Device Configuration) ....................................................... 5
3.1.1.2 CDC (Connected Device Configuration) ..................................................................... 5
3.1.2 Profile.......................................................................................................................... 5
3.1.3 optionale Pakete .......................................................................................................... 6
3.2 MIDlet-Grundlagen .............................................................................................................. 6
3.3 Erste Schritte mit Java ME .................................................................................................. 7
3.4 Entwicklungswerkzeuge ...................................................................................................... 8
3.5 Installation auf mobilem Endgerät ..................................................................................... 10
4. Mobile 3D Graphics API (M3G)......................................................................11
4.1.1 Immediate Mode ........................................................................................................ 12
4.1.2 Retained Mode .......................................................................................................... 12
5. 2D Spieleprogrammierung...............................................................................13
5.1 Einführung in die Spieleprogrammierung ..........................................................................
5.1.1 Grundgerüst mit Spielschleife ...................................................................................
5.1.2 Animation ..................................................................................................................
5.1.3 Tastensteuerung........................................................................................................
5.1.4 Erstellung eines Levels ..............................................................................................
5.1.5 Scrolling des Levels ...................................................................................................
5.1.6 Zeichnen des Levels ..................................................................................................
5.1.7 Kollisionserkennung im Level ....................................................................................
5.1.8 Kollisionserkennung bei Objekten .............................................................................
5.2 Beispielprogramme ............................................................................................................
13
13
14
18
19
20
21
22
24
25
6. Abschluss..........................................................................................................27
6.1 Anmerkungen zur Ausarbeitung ....................................................................................... 27
6.2 Schlusswort....................................................................................................................... 27
7. Literatur und Verzeichnisse.............................................................................28
7.1 Literaturverzeichnis ........................................................................................................... 28
7.2 Internetquellen .................................................................................................................. 28
7.3 Abkürzungsverzeichnis ...................................................................................................... 30
8. Anhang...............................................................................................................31
8.1 Einrichten von Eclipse ...................................................................................................... 31
8.1.1 Installation des Java SE Development Kit ................................................................. 31
8.1.2 Installation des Sun Java Wireless Toolkit for CLDC ................................................. 31
8.1.3 Installation von Eclipse .............................................................................................. 31
8.1.4 Installation von EclipseME ......................................................................................... 31
8.1.5 EclipseME einrichten ................................................................................................. 31
8.1.6 Anlegen eines JavaME-Projekes in Eclipse .............................................................. 34
8.2 Erstellen einer Karte mit Tile Studio .................................................................................. 38
8.3 Beispielprogramme (Anwenderdokumentation) ................................................................. 45
8.3.1 JavaME_01_HelloWorld ............................................................................................ 45
8.3.2 Game_01_GameLoop ............................................................................................... 46
8.3.3 Game_02_WalkMario ................................................................................................ 47
8.3.4 Game_03_WalkMarioTiles ........................................................................................ 48
8.3.5 Game_04_WalkMarioTilesCollision ........................................................................... 49
8.3.6 Game_05_SuperMarioBros ....................................................................................... 50
8.4 Zeitaufwand ....................................................................................................................... 52
8.5 Inhalt der CD-Rom ............................................................................................................. 53
Christian Burmeister
Anhang 3
1.Kurzzusammenfassung
Wie bereits aus dem Titel dieser Ausarbeitung zu entnehmen ist, soll im Rahmen dieser
Ausarbeitung auf M3G sowie auf die 2D-Spieleprogrammierung eingegangen werden. Dies kommt
daher, weil zunächst das Thema M3G ausgearbeitet werden sollte, dann aber relativ schnell
festgestellt wurde, dass Herr Werder [WERM3G] dieses Thema schon in aller Ausführlichkeit
behandelt hatte. Daher wurde in Absprache mit Prof. Dr. Werner Heinzel beschlossen, dass diese
Ausarbeitung schwerpunktmäßig das Thema 2D-Spieleprogrammierung behandelt, aber dennoch
sehr kurz auf das Thema M3G eingegangen werden muss.
Daher wird im Rahmen dieser Ausarbeitung zunächst auf das Thema JavaME eingegangen,
welches für beide Themengebiete relevant ist, da beide JavaME voraussetzen. Dabei wird
zunächst auf das modulare Konzept von JavaME eingegangen, welches sich aus Konfigurationen,
Profilen und optionalen Paketen zusammensetzt. Danach werden die Grundlagen einer JavaMEAnwendung beschrieben, welche danach in einem praktischen Beispiel demonstriert werden
sollen. Abschließend wird noch auf die notwendigen Entwicklungswerkzeuge für JavaME
eingegangen.
Nach diesem einführenden Teil wird kurz auf M3G eingegangen, danach beginnt der eigentliche
Hauptteil dieser Ausarbeitung. In diesem Teil sollen die Grundlagen der 2D-Spieleprogrammierung
vermittelt werden. Unter anderem wird beschrieben, wir man eine Spielfigur animieren und mithilfe
der Tastatur über den Bildschirm bewegt kann. Anschließend wird auf das Erstellen, Scrollen und
Zeichnen eines Levels eingegangen, in dem sich die zuvor erstellte Spielfigur bewegen kann.
Abschließend soll noch auf das Thema Kollisionserkennung eingegangen werden.
2.Einleitung
Anfang der 90er Jahre begann der Siegeszug des Mobiltelefons, oder ganz allgemein der mobilen
Endgeräte. Zunächst waren die verfügbaren Endgeräte noch sehr groß, schwer und unhandlich,
doch dies änderte sich im Zuge des technischen Fortschrittes recht schnell. Heutzutage sind
mobile Endgeräte aus unserem Alltag kaum mehr wegzudenken. Dabei werden sie längst nicht
mehr nur zum Telefonieren genutzt. Mobile Endgeräte stellen heute eher Multimediazentrale im
Miniaturformat da, mit der es möglich ist Emails zu schreiben, im Internet zu surfen, Musikdateien
abzuspielen, Termine zu verwalten und sogar Spiele zu spielen.
Gerade der Spielebereich ist ein interessanter Markt, denn fast jeder Mensch in der westlichen
Welt besitzt mindestens ein Mobiltelefon. Von diesen Verbreitungszahlen können
Spielekonsolenhersteller zurzeit nur träumen. Daher wird es mit der zunehmenden
Leistungsfähigkeit der mobilen Endgeräte immer interessanter für diesen Markt Spiele zu
entwickeln. Momentan dominieren noch 2D-Spiele den Markt, doch mit zunehmender
Rechenleistung werden sich wahrscheinlich 3D-Spiele immer weiter durchsetzen.
Stellt sich nur die Frage, in welcher Programmiersprache man diese Spiele entwickeln soll? Dabei
bietet sich Java an, da Java bereits im Desktop und Server-Bereich weiter Verbreitung befunden
hat. Dabei muss aber auf eine spezielle Edition von Java zurückgegriffen werden, die sich JavaME
nennt. JavaME ist dabei eine speziell für mobile Endgeräte angepasste Java Edition, die der
beschränkten Leistungsfähigkeit der Endgeräte Rechnung trägt. Sie bietet dabei, genau wie die
größeren Editionen vom Java, den Vorteil, dass sie nahezu Plattformunabhängig ist und damit die
zu entwickelnde Anwendung auf allen JavaME unterstützten Plattformen lauffähig sind. Dies ist
gerade im Bereich der mobilen Endgeräte sehr wichtig, da fast jeder Hersteller sein eigenes
Betriebssystem verwendet. Eines dieser Betriebssysteme ist zum Beispiel Symbian OS der Firma
Nokia. JavaME bietet dabei sowohl eine Unterstützung für 2D, wie auch für die 3DSpieleprogrammierung. Für die 3D Unterstützung wird aber eine Erweiterung namens „Mobile 3D
Graphics“ (M3G) benötigt.
Eigentlich sollte auf diese 3D-Erweiterng, im Rahmen dieser Ausarbeitung, eingegangen werden.
Nach ersten Recherchen stellte sich aber heraus, dass bereits eine sehr ausführliche Ausarbeitung
zu diesem Thema von Herrn Werder [WERM3G] existiert und so wurde in Absprache mit Herrn
Prof. Dr. Werner Heinzel beschlossen, dass schwerpunktmäßig das Thema 2DSpieleprogrammierung bearbeitet wird.
Christian Burmeister
Anhang 4
3.Java für mobile Endgeräte
Java erfreut sich in den letzten Jahren immer größerer Beliebtheit, mit der zunehmenden
Leistungsfähigkeit von mobilen Endgeräten, wie etwa Mobiltelefone oder PDAs, wird auch der
Einsatz der Java-Technologie auf diesen Geräten immer attraktiver. Dabei ist allerdings zu
beachten, dass mobile Endgeräte eine Reihe von Einschränkungen gegenüber normalen DesktopSystemen besitzen.
Die Speicherkapazität und Rechenleistung ist im Vergleich zu aktuellen Desktop-Systemen
sehr gering.
Die Ein- und Ausgabemöglichkeiten auf mobilen Endgeräten muss aufgrund von Platz-,
Gewichts- und Energiespargründen eingeschränkt werden. Daher besitzen mobile
Endgeräte meist nur kleine Displays und wenige Tasten zur Eingabe.
Da mobile Endgeräte nur über einen Akku zur Energieversorgung verfügen, muss sehr
sparsam mit der zur Verfügung stehenden Energie umgegangen werden.
Aus den erwähnten Einschränkungen erscheint es nur konsequent, dass auf mobilen Endgeräten
nicht die gleiche Java-Laufzeitumgebung wie auf Servern oder Desktops zum Einsatz kommt. Aus
diesem Grunde existieren drei verschiedene Editionen von Java, die von der Firma Sun kostenlos
zur Verfügung gestellt werden.
Java Enterprise Edition (JavaEE) – für den Einsatz auf Serversystemen
Java Standard Edition (JavaSE) – für den Einsatz auf Desktopsystemen
Java Micro Edition
(JavaME) – für den Einsatz auf ressourcenbeschränkten Geräten
Die Java Micro Edition (JavaME) oder auch die früher Bezeichnung Java 2 Micro Edition (J2ME) ist
eine Java-Edition, die speziell für die Anforderungen auf mobilen Endgeräten angepasst wurde.
Dabei wurde besonderen Wert auf eine ressourcenschonende Implementierung gelegt.
Wie man vielleicht vermuten könnte, stellt JavaME keine Teilmenge von JavaSE/JavaEE da. Es
wurden zwar einige bekannte Klassen aus JavaSE übernommen, diese wurden aber an die
speziellen Anforderungen mobiler Geräte angepasst. Weiterhin wurden zusätzliche Klassen
hinzugefügt, die im Namensraum javax.microedition.* angesiedelt sind.
3.1Konfigurationen, Profile und optionale Pakete
Die J2ME-Architektur basiert auf einem Konzept, das sich aus Konfiguration, Profil und optionalen
Pakten zusammensetzt. In Abbildung 3.1 ist eine Übersicht über die einzelnen Module gegeben,
auf die im Folgenden noch näher eingegangen werden soll.
Christian Burmeister
Anhang 5
Abbildung 3.1 Quelle: [SUN1]
Der Grund für diese Aufspaltung, die nur in JavaME vorgenommen wird, ist, dass mobile
Endgeräte, im Unterschied zu normalen Computern, sehr unterschiedliche Leistungsklassen
besitzen. Zum einen sind es ganz einfache Mobiltelefone mit nur sehr wenigen Zusatzfunkionen
und zum anderen die High-End PDAs, die leistungsfähige Mikroprozessoren und mehrere
Gigabyte Speicher besitzen. Daher entschied man sich für ein modulares Konzept, da so die
Softwarefähigkeiten der Java-API sehr gut an die Hardwarefähigkeiten des Gerätes angepasst
werden können.
3.1.1Konfigurationen
Die Konfiguration stellt sozusagen das Basismodul von JavaME dar. Es stellt zum einen die
grundlegenden Java-Funktionalitäten zur Verfügung und zum andern die virtuelle Maschine, in der
der Java-Code ausgeführt werden kann. Das darüber angesiedelte Profil und die optionalen
Pakete setzen wiederum auf dieses Basismodul auf. Zurzeit unterscheidet man zwischen zwei
Konfigurationen: CLDC und CDC.
3.1.1.1CLDC (Connected Limited Device Configuration)
Wie das Wort „Limited“ im Namen schon andeutet, ist diese Konfiguration für Ressourcen
beschränkte Endgeräte, wie z.B. Mobiltelefone und Einstiegs-PDAs, gedacht. Um der geringen
Leistungsfähigkeit Rechnung zu tragen, wird die virtuelle Maschine in dieser Konfiguration auch
„K(ilobyte) Virtual Machine“ (KVM) genannt. Wie man erahnen kann, ist diese stark eingeschränkt
gegenüber der JVM in der JavaSE oder JavaEE Edition.
Momentan existieren zwei Versionen der CLDC-Konfiguration, zum einen die CLDC 1.0 [JSR30]
und zum andern die CLDC 1.1 [JSR139]. Der wohl größte Unterschied zwischen beiden Versionen
ist die fehlende Fließkommaunterstützung (float, double) in der 1.0 Version..
3.1.1.2CDC (Connected Device Configuration)
Die CDC-Konfiguration ist im Gegensatz zur CLDC-Konfiguration für leistungsfähigere Endgeräte
entwickelt worden, z.B. High-End PDAs und TV Set-Top-Boxen. Eine CDC-Implementierung
unterstützte daher eine weitaus größere Menge der Klassenbibliothek der JavaSE Edition, daher
erfordert die CDC auch eine nahezu vollwertige JVM. Zurzeit sind zwei Versionen verfügbar,
sowohl Version 1.0 (JSR36) als auch Version 1.1.2 (JSR218).
Da diese Konfiguration sehr selten auf den heutigen Mobiltelefonen zum Einsatz kommt, soll im
Nachfolgenden nicht weiter auf diese Konfiguration eingegangen werden. In ein paar Jahren
könnte dies aber schon ganz anders aussehen.
3.1.2Profile
Die beschriebenen Konfigurationen werden mithilfe von Profilen erweitert. Dabei stellt das MIDP
(Mobile Information Device Profile) eines der wichtigsten Profile da. Es setzt auf die CLDC-
Christian Burmeister
Anhang 6
Konfiguration auf und stellt zusammen mit dieser die Kernfunktionen für mobile Anwendungen,
durch eine standardisierte Ablaufumgebung und Java APIs, zur Verfügung.
Momentan existieren zwei Versionen von MIDP, zum einen die Version 1.0 [JSR37] und zum
andern die Version 2.0 [JSR118], dabei kann die MIDP-Version unabhängig von der CLDC-Version
verwendet werden. Das MIDP ist unter anderem für folgende Aufgagen zuständig:
Benutzerschnittstelle, Ereignisverarbeitung, Management der Installation und Steuerung des
Lebenszyklus von Anwendungen. Das MIDP gibt den sogenannten MIDlets auch ihren Namen, auf
diese wird im Abschnitt 3.2 noch näher eingegangen.
3.1.3optionale Pakete
Je nach Ausstattung des mobilen Endgerätes kann die bestehende Kombination aus Konfiguration
und Profil noch durch optionale Pakete erweitert werden. Diese optionalen Pakete werden, genau
wie auch alle anderen Module von einer JCP-Expertengruppe in einem JSP (Java Specificaton
Request) spezifiziert. Eine kleine Auswahl dieser optionalen Pakete ist im Folgenden aufgelistet:
Java APIs for Bluetooth (JSR82), Mobile Media API (JSR135), M3G (JSR184)
Auf das optionale Paket „Mobile 3D Graphics“ (M3G) wird in Abschnitt 4 noch näher eingegangen.
3.2MIDlet-Grundlagen
JavaME-Anwendungen, die für ein MIDP-Profil entwickelt werden, nennen sich MIDlets. Jedes
Endgerät, auf dem ein MIDlet ausgeführt werden soll, benötigt eine Umgebung, die es erlaubt ein
MIDlet zu starten, auszuführen und zu beenden. Diese Umgebung wird Application Management
Software (AMS) genannt. Die AMS übernimmt dabei die komplette Ablaufsteuerung eines MIDlets.
Deshalb verfügen MIDlets auch über keine Main-Methode, da es der AMS so nicht möglich wäre,
in den Programmablauf einzugreifen. MIDlets werden daher über einen Zustandsautomaten
gesteuert, der aus den drei Zuständen: active, paused, destroyed besteht. Im „active“-Zustand läuft
das MIDlet aktiv im Vordergrund und kann auf die bereitgestellten Ressourcen zugreifen. Im
„paused“-Zustand ist das MIDlet zwar initialisiert, aber es ist nicht möglich aktiv auf Ressourcen
zuzugreifen, daher sollten diese ggf. vorher freigegeben werden. Wenn ein MIDlet beendet werden
soll, wird es in den „destroyed“-Zustand versetzt. Im Folgenden ist der erwähnte Zustandsautomat
abgebildet.
Abbildung 3.2 Quelle: [KARBACHER]
Über die abgebildeten Methoden (startApp(), destroyApp(), pauseApp()) steuert die AMS den
Programmablauf des MIDlets. Die Methoden werden dabei jeweils vor einem Zustandsübergang
aufgerufen. Um sicherzustellen, dass jedes MIDlet diese Methoden bereitstellt, muss jedes MIDlet
von der abstrakten Klasse MIDlet (javax.microedition.midlet.MIDlet) abgeleitet werden.
Christian Burmeister
Anhang 7
Ein MIDlet kann durch die Methoden „notifyPaused()“ und „notifyDestroyed()“ auch von sich aus
versuchen, dass die AMS ein Zustandsübergang durchführt. Die „notifyDestroyed()“-Methode ist
dabei die einzige Möglichkeit für ein MIDlet sich ordnungsgemäß zu beenden.
Durch diese zustandsbasierte Programmsteuerung ist es nun möglich auf asynchron auftretende
Ereignisse z.B. ein Telefonanruf oder SMS zu reagieren, da die AMS die Kontrolle über den
Programmablauf eines MIDlets besitzt.
3.3Erste Schritte mit Java ME
Da wir nun die Grundlagen eines MIDlets kennengelernt haben, soll nun beschrieben werden wie
man ein einfaches MIDlet erstellt. Am besten für solche Zwecke eignet sich ein klassisches „Hello
World“-Programm. Um dies zu realisieren, wurden die beiden Klassen „MyMIDlet“ und „MyCanvas“
erstellt, die in Quelltext 3.1 bzw. Quelltext 3.2 abgebildet sind.
Wie man in der Abbildung 3.1 erkennen kann, wurde die Klasse „MyMIDlet“ von der Klasse
„MIDlet“ abgeleitet, dadurch mussten auch die drei bereits erwähnten Methoden (startApp(),
destroyApp(), pauseApp()) implementiert werden. Für unser kleines Beispiel ist dabei nur die
Methode „startApp()“ von Interesse. In dieser Methode wird in Zeile 3 die Referenz auf das
Handydisplay gespeichert, dies geschieht durch den Aufruf der statischen Methode „getDisplay()“
der Display-Klasse.
In Zeile 4 wird eine Leinwand erstellt, dem Konstruktor wird dabei eine Referenz auf das MIDlet
übergeben, damit die Anwendung später ordnungsgemäß beendet werden kann. Um die Leinwand
nun auf dem Display anzuzeigen, muss es der Methode „setCurrent()“, des Display-Objektes,
übergeben werden.
Quelltext 3.1 (Programm: „JavaME_01_HelloWorld“)
Wie man erkennen kann, dient die Klasse „MyMIDlet“ nur dazu, eine Leinwand-Objekt auf dem
Display anzuzeigen. Das eigentliche Zeichnen auf die Leinwand findet dagegen in der Klasse
„MyCanvas“ statt.
Christian Burmeister
Anhang 8
Quelltext 3.2 (Programm: JavaME_01_HelloWorld)
Die Klasse „MyCanvas“ ist ebenfalls von einer abstrakten Klasse abgeleitet, in diesem Fall aber
von „Canvas“. Daher muss die Methode „paint()“ implementiert werden (Zeile 7 – 10), die für das
Zeichen unseres „Hello World“ Textes verantwortlich ist. Durch den Methodenaufruf „setCurrent()“
in Quelltext 3.1, Zeile 4 wird einmalig die paint-Methode aufgerufen und ein Graphics-Objekt
übergeben, dieses Objekt stellt Methoden bereit um auf die Leinwand zu zeichnen. Durch die
Methode „drawString()“, des Graphics-Objektes, wird nun der String „Hello World!“ auf das Display
gezeichnet, der 2. und 3. Parameter geben dabei die X und Y-Koordinate ausgehend von der
oberen linken Ecke (4. Parameter) an. Die Koordinaten werden jeweils in Pixeln angegeben. Über
die beiden Methoden „getWidth()“ und „getHeight()“ kann die jeweilige Pixelgröße der Leinwand
abgefragt werden, dabei ist diese jeweils abhängig vom eingesetzten Endgerät.
Um die größtmögliche Zeichenfläche zu erlangen, wurde im Konstruktor der MyCanvas-Klasse die
Methode „setFullScreenMode()“ aufgerufen, dadurch verschwindet der am unteren Displayrand
befindliche Softkey-Balken.
Um das MIDlet ordnungsgemäß beenden zu können, wird im Konstruktor eine Referenz auf das
MIDlet gespeichert (Zeile 4). In Zeile 11 – 14 wird überprüft, ob die *-Taste gedrückt wurde. Wenn
dies der Fall ist, wird die Methode „motifyDestroyed()“ des MIDlet-Objektes aufgerufen, und damit
das MIDlet beendet.
3.4Entwicklungswerkzeuge
Im Gegensatz zu JavaEE und JavaSE Programmen können JavaME Programme nicht direkt auf
dem Gerät entwickelt werden, auf dem sie später ausgeführt werden sollen. Aus diesem Grund
benötigt man zusätzlich zur eigentlichen Entwicklungsumgebung auch einen Emulator, der die
KVM des mobilen Endgerätes auf dem Entwicklungs-Computer emuliert. Somit findet die komplette
Entwicklung auf dem Entwicklungs-Computer statt, und erst nach der Fertigstellung wird das
JavaME-Programm auf das mobile Endgerät übertragen.
Um nun ein JavaME-Programm zu entwickeln, werden eigentlich nur 3 Komponenten benötigt.
-
Java SE Development Kit (JDK) [SUNJDK]
-
Sun Java Wireless Toolkit for CLDC (WTK) [SUNWTK]
-
Einfacher Texteditor
Das JDK legt den Grundbaustein für die Java-Programmierung, dabei enthält es noch keine
JavaME spezifischen Komponenten. Erst mit der Installation des WTK werden die zusätzlichen
Klassen für JavaME (javax.microedition.*) installiert. Das WTK stellt aber nicht nur eine einfache
Erweiterung für JavaME-Klassen dar, es ist vielmehr eine komplette Entwicklungsumgebung. Es
beinhaltet sowohl die erwähnten Emulatoren und auch eine einfache grafische Oberfläche zum
Christian Burmeister
Anhang 9
Erstellen von JavaME-Programmen. Der Nachteil des WTKs ist, dass es keine vollwertige
integrierte Entwicklungsumgebung (IDE) ist, denn es enthält weder einen Texteditor, noch eine
Möglichkeit Quellcode zu debuggen. Es ist natürlich möglich einen einfachen Texteditor zu
verwenden, doch dies ist meist wenig komfortabel. Daher bieten die meisten IDEs Erweiterungen
an, um das WTK innerhalb der IDE verwenden zu können. Im Folgenden sind zwei IDEs mit den
erforderlichen Erweiterungen aufgelistet.
-
Eclipse [ECLIPSE]
o
-
Erweiterung für WTK: EclipseME [ECLIPSEME]
Netbeans [NETBEANS]
o
Erweiterung für WTK: Mobility Packs (in „Java“ Edition von Netbeans enthalten)
Der Einsatz einer solchen IDE bietet gegenüber der Verwendung des reinen WTK natürlich
erhebliche Vorteile, da es viele Hilfestellungen bei der Entwicklung und Fehlersuche bietet. Aus
diesem Grunde empfiehlt es sich fast immer eine solche IDE einzusetzen. Im Anhang 8.1 wird
daher anhand des Beispielprogramms „HelloWorld“ gezeigt, wie man Eclipse, unter Verwendung
der Erweiterung EclipseME, mit dem WTK verwenden kann.
Außer der Firma Sun bieten aber noch einige andere Hersteller Software Development Kit (SDK)
für JavaME an. Zu ihnen zähnen meist Firmen, die selbst JavaME fähige Mobiltelefone herstellen.
Als Beispiel sei hier die Firma Nokia genannt, die unter der Webadresse [NOKIASDK] ihr eigenes
SKD kostenlos zur Verfügung stellt. In diesem SKD sind wie beim WTK zum einen die Emulatoren
enthalten und zum andern die Erweiterungen für JavaME, die aber auch Hersteller spezifische
Erweiterungen enthalten.
Christian Burmeister
Anhang 10
3.5Installation auf mobilem Endgerät
Nachdem man ein JavaME-Programm erstellt hat, stellt sich bald die Frage, wie man das
Programm auf dem mobilen Endgerät installiert.
Die Installation unterscheidet sich etwas zu konventionellen Installationen, denn bei JavaMEProgrammen wird die eigentliche Installationsdatei auf zwei Dateien aufgesplittet. Zum einen in
eine JAD-Datei (Java Application Descriptor) und zum anderen in eine JAR-Datei (Java Archive).
Die JAD-Datei teilt dabei dem Mobiltelefon Vorabinformationen über das zu installierende
Programm mit. In der JAR-Datei befindet sich das eigentliche Programm.
Doch warum diese Aufsplittung? Dies liegt daran, das JavaME-Programme meist über die
Luftschnittstelle („Over the Air“) installiert werden. Da über diesen Wege die Übertragung von
Daten meist relativ teuer und langsam ist, wird zunächst nur eine einfach Textdatei übermittelt
(JAD-Datei) in der Programminformationen gespeichert sind. Dies ermöglicht es dem Mobiltelefon
vorab festzustellen, ob es über die geforderten Anforderungen verfügt, wie z.B. genügend
Speicherplatz, Unterstützung für Konfiguration und Profil der Anwendung.
In der nachfolgenden Abbildung ist die JAD-Datei des HelloWorld-Programms abgebildet.
Quelltext 3.3 (JAD-Datei des HelloWorld-Programms)
Wie man erkennen kann, ist in Zeile 2 die Größe des Programms angegeben und in Zeile 7 und 8
die erforderliche Konfiguration und das Profil.
Um nun ein JavaME Programm zu installieren, benötigt man zunächst die JAD-Datei. Das
Mobiltelefon überprüft dann zuerst die Angaben und installiert, wenn alle Bedingungen erfüllt sind,
die unter Zeile 3 angegebene JAR-Datei. So muss die JAR-Datei nur übertragen werden, wenn sie
auch wirklich auf dem Mobiltelefon ausgeführt werden kann.
Um ein Programm ohne Luftschnittstelle installieren zu können, benötigt das Mobiltelefon eine
Datenschnittstelle z.B. Bluetooth oder eine Anschlussmöglichkeit für ein Datenkabel. Für die
meisten Mobiltelefone stellen die Hersteller auf ihren Webseiten entsprechende Programme bereit,
die es erlauben auf den internen Speicher zuzugreifen. Damit ist es dann sehr einfach und sogar
kostenlos möglich JavaME-Programme zu installiere. Dazu kopiert man einfach die erstellten JAD
und JAR-Dateien auf das Mobiltelefon und installiert sie. Wie man die Anwendung installieren
kann, hängt dabei vom jeweiligen mobilen Endgerät ab.
Wie man an die beiden Dateien gelangt, hängt jeweils von der eingesetzen
Entwicklungsumgebung ab. Im Falle von Eclipse werden sie bereits automatisch erstellt, da der
Emulator mit genau diesen beiden Dateien gestartet wird. Um an die beiden Dateien zu gelangen,
muss man, nachdem man ein JavaME-Projekt erstellt und das Programm mindestens einmal im
Emulator ausgeführt hat, in das Projektverzeichnis wechseln, welches sich im Eclipse-WorkspaceOrdner befindet. Die beiden Dateien befinden sind nun im Unterordner „.eclipseme.tmp\emulation“.
Christian Burmeister
Anhang 11
4. Mobile 3D Graphics API (M3G)
Wie bereits im Abschnitt 3.1.3 erwähnt, stellt M3G ein optionales Paket für JavaME dar. Wie alle
optimalen Pakete setzt es auf die vorhandene Kombination aus Konfiguration (CLDC) und Profil
(MIDP) auf und erweitert dadurch die vorhandene API um zusätzliche Funktionalitäten. Im Fall von
M3G sind dies 3D Funktionen, die im Namensraum „javax.microedition.m3g“ untergebracht sind.
Um M3G nutzen zu können, ist mindestens die Konfiguration CLDC 1.1 benötigt, da erst ab dieser
Version die Fließkommaunterstützung implementiert wurde.
M3G wurde von einem unabhängigen Komitee in einem „Java Community Process“ entwickelt und
standardisiert. Zu diesem Komitee gehörten insgesamt 26 Mitglieder, zu denen unter anderm Sun
Microsystems, Sony Ericsson, Symbian, Motorola, ARM, Cingular Wireless und Nokia gehörten
[SUNM3G]. Die Ergebnisse dieses Prozesses wurden in [JSR184] festgehalten und beschreibt die
Version 1.0 und 1.1 von M3G. Zurzeit ist Version 2.0 in Entwicklung und wird unter dem Namen
[JSR297] standardisiert werden.
Bei der Entwicklung des JSR184 Standards wurden vom Standardisierungskomitee einige
Anforderungen festgelegt, die die API erfüllen sollte [SUNM3G].
Die API soll zwei Modi unterstützen, den „retained-mode“ (high-level Schnittstelle mit
Scene-Graphen) und den „immediat-mode“ (low-level Schnittstelle, die ähnlich oder gleich
der von OpenGL ES sein sollte). Dabei sollte es möglich sie, die Modi einzeln, wie auch in
Kombination nutzen zu können.
Die API darf keine optionalen Teile enthalten; alle Methoden müssen implementiert
werden.
Um die Programmierarbeit zu reduzieren, benötigt die API Importer für
Schlüsseldatentypen, wie Meshes, Texturen und Scene-Graphen. (M3G-Dateiformat)
Die Daten müssen für eine kompakte Speicherung und Übertragung in einem Binärformat
codiert werden.
Es muss möglich sein, auch ohne Hardwareunterstützung für Fließkommaberechnungen,
effizient auf OpenGL ES aufzusetzen.
Die API muss den Fließkomma-Datentyp von Java benutzen und soll keinen eigenen
Datentyp dafür einführen.
Weil der Einsatz von Integer-Arithmetik schwierig und fehleranfällig ist, sollen FließkommaWerte überall dort eingesetzt werden, wo es möglich ist.
Der benötige Rom und Ram sollte sehr gering sein; die API sollte mit lediglich 150KB auf
einem Gerät implementierbar sein.
Die API soll eine minimale „garbage collection“ zur Verfügung stellen.
Die API muss korrekt mit andern Java APIs interagieren, speziell MIDP.
Im Folgenden soll noch kurz auf die beiden erwähnten Modi, „immediate mode“ und „retained
mode“, eingegangen werden.
Christian Burmeister
Anhang 12
4.1.1Immediate Mode
Der „immediate mode“ stellt „low-level“ 3D-Funktionalitäten für JavaME zur Verfügung, dabei baut
es weitgehend auf dem 3D-Standard OpenGL-ES der Firma Khronos auf. OpenGL-ES (OpenGL
for Embedded Systems) ist eine Teilmenge von OpenGL die speziell an die Bedürfnisse von
ressourcenschwachen Geräten angepasst wurde.
Der Modus wird deshalb „immediate“ (deut. direkt, umgehend) genannt, weil alle Objekte direkt
gerendert und danach gezeichnet werden. Dadurch ist der Programmierer zwar in der Lage auf alle
Teile seiner Anwendung direkten Einfluss zu nehmen, wie z. B. die Erzeugung von Objekten,
setzen des Lichtes, ändern der Kameraposition und das rendern einzelner Objekte, aber dies ist
meist mit sehr viel Arbeit verbunden, da man jeden Schritt detailliert festlegen muss.
Ein sehr schönes Tutorial zum „immediate mode“ lässt sich unter [IBMM3G] finden.
4.1.2Retained Mode
Der „retained mode“, stellt dagegen „high-level“ 3D-Funktionalitäten zur Verfügung. Der Vorteil
dieses Modus ist der, dass Objekte nicht direkt gerendet und gezeichnet werden müssen, sondern
die Objekte zunächst in einer Datenstruktur, dem sogenannten „Scene Graph“, abgespeichert
werden. Daher stammt auch der Name „retainted“ (deut. zurückbehalten) dieses Modus.
Die Datenstruktur ist dabei in Art eines Baumes aufgebaut, wobei jedes 3D-Objekt ein Knoten
darstellt. Die Wurzel dieses Baumes bildet die Klasse „World“, unterhalb der Wurzel werden dann
Kamera, Licht und andere 3D-Objekte platziert. In Abbildung 4.1 ist ein Beispiel dieser
Baumstruktur zu sehen.
Abbildung 4.3 Quelle: [IBMM3G]
Ein weiter Vorteil dieser Baumstruktur ist, dass man Objekte gruppieren kann und sie dadurch
gemeinsam ansprechbar sind. In der Abbildung 4.1 ist dies am Beispiel von acht Würfeln
demonstriert. Durch Ansprechen der Gruppe 1 können alle acht Würfel gemeinsam rotiert werden,
durch Ansprechen der Gruppen 2 und 3 können dagegen je vier Würfel getrennt voneinander
angesprochen werden, im Beispiel ist dies anhand einer Skalierung demonstriert. Um alle 3DObjekte zu rendern und zu zeichnen muss lediglich die Wurzel des „Scene Graph“, also die Klasse
„World“, übergeben werden, den Rest der Arbeit übernimmt M3G. Eine ausführliche Beschreibung
des Beispiels ist unter [IBMM3G] zu finden.
Ein weiterer Vorteil, den der „retainted mode“ bietet, ist die Unterstützung für ein eingenes
Dateiformat zum Importieren von 3D-Objekten. Dies bietet die Möglichkeit komplexe Scenen mit
einem 3D-Werkzeug, wie z. B. Lightwave oder Maya, zu erstellen und dann in M3G zu importieren.
Als Dateierweiterung kommt dabei „.m3g“ zum Einsatz. Um die erstellte 3D-Scene mit M3G
anzeigen zu können, muss sie lediglich mit der „Loader“-Klasse geladen werden.
Nach diesem kleinen Ausflug in die 3D-Welt soll sich nun mit der Spieleprogrammierung in der 2DWelt beschäftigt werden.
Christian Burmeister
Anhang 13
5.2D Spieleprogrammierung
Dieser Abschnitt beschäftigt sich nun mit der Entwicklung von einfachen 2D-Spielen. Im Abschnitt
5.1 soll zunächst anhand der Programme „Game_01_GameLoop“, „Game_02_WalkMario“,
„Game_03_WalkMarioTiles“ und „Game_04_WalkMarioTilesCollision“ schrittweise gezeigt werden,
wie man einfache 2D-Spiele selbst entwickeln kann. Im Abschnitt 5.2 soll danach das Programm
„Game_05_SuperMarioBros“ kurz vorgestellt werden, welches die zuvor gezeigten Techniken
innerhalb eines komplexeren Spieles umsetzt, aus Platzgründen kann dieses Programm aber
leider nicht ausführlich beschreiben werden. Eine kurze Anwenderbeschreibung der erwähnten
Programme ist auch im Abschnitt 8.3 zu finden.
Es sei noch erwähnt, dass die grundlegenden Ideen für die Algorithmen aus dem Buch „Mobile
Games“ von Thomas Lucka [LU08MGAME] übernommen wurden.
5.1Einführung in die Spieleprogrammierung
In den folgenden acht Abschnitten sollen nun schrittweise die Grundlagen der 2DSpieleprogrammierung erläutert werden. Begonnen wird dabei in Abschnitt 5.1.1 mit dem
Grundgerüst eines 2D-Spieles, danach wird in Abschnitt 5.1.2 und 5.1.3 beschrieben wie man eine
animierte Spielfigur, mithilfe der Tastatur, über den Bildschirm bewegen kann. Danach wird in den
Abschnitten 5.1.4, 5.1.5 und 5.1.6 erläutert, wie man ein Level erstellen, scrollen und zeichnen
kann. In den beiden letzen Abschnitten soll dann noch kurz auf die Kollisionserkennung
eingegangen werden.
5.1.1 Grundgerüst mit Spielschleife
Um ein 2D-Spiel für JavaME zu entwickeln, benötigt man, wie bei allen JavaME-Programmen, eine
Klasse die von MIDlet abgeleitet ist. In Abschnitt 3.3 wurde bereits der Aufbau einer solchen
Klasse am Beispiel der MyMIDlet-Klasse beschrieben, daher soll diese Klasse hier übernommen
werden und als Ausgangsbasis für unser Spiel dienen. Um kenntlich zu machen, dass es sich bei
unser Leinwand-Klasse um eine Spieleleinwand handelt, soll die Klasse MyCanvas aber in
GameCanvas umbenannt werden. Die neue Klasse GameCanvas wird dabei ebenfalls von der
abstrakten Klasse Canvas abgeleitet, und muss dadurch ebenfalls die Methode „paint(Graphics g)“
implementieren. Wie bereits beim „Hello World“-Programm erwähnt, wird diese paint-Methode aber
nur ein einziges Mal aufgerufen. Dies ist für Spiele nicht besonders zweckmäßig, da ähnlich wie
bei einem Film, die Bewegung durch die schnelle Abfolge von Einzelbildern (Frames) erzeugt wird.
Daher muss zunächst eine Schleife entwickelt werden, die es ermöglicht die paint-Methode öfter
aufzurufen. Diese Schleife wird meistens Game Loop oder Spielschleife genannt, da sie ein
zentraler Bestandteil des Spieles ist. Um den Eindruck einer flüssigen Bewegung zu erreichen,
sollte die Spielschleife ca. 25 – 30 mal pro Sekunde die paint-Methode aufrufen. Wenn die Anzahl
der Aufrufe von diesem Wert abweicht, wird das Spiel entsprechend langsamer oder schneller.
In Quelltext 5.1 ist ein Beispiel für eine solche Spielschleife gegeben. Um zu gewährleisten, dass
keine ungewollten Verzögerungen durch andere Methoden entstehen, wird die Spielschleife in
einem eigenen Thread realisiert. Dazu muss unsere Leinwand-Klasse das Interface „Runnable“
implementieren, welches die Implementierung der „run()“ Methode erzwingt. Da nur ein ThreadObjekt als Thread laufen kann, wird in Zeile 5 ein neues Objekt dieser Klasse erzeugt, als
Parameter für den Konstruktor wird unser GameCanvas-Objekt übergeben. Durch den Aufruf der
start-Methode wird nun die implementierte run-Methode durch den erzeugten Thread aufgerufen.
In der run-Methode befindet sich nun die erwähnt Schleife (Zeile 10 – 19). Um zu gewährleisten,
dass die paint-Methode nur höchstens 30-mal pro Sekunde aufgerufen wird, wird am Anfang der
Schleife (Zeile 11) die aktuelle Zeit gespeichert und am Ende der Schleife (Zeile 15) wird die
benötigte Ausführungszeit ermittelt. In Zeile 16 wird überprüft, ob die Ausführungszeit schneller als
die vorgegebene Ausführungszeit ist, wenn dies der Fall ist, wartet der Thread bis zum Erreichen
der vorgegebenen Ausführungszeit. Die Ausführungszeit kann dabei indirekt über die Konstante
„MAX_FRAMES_PER_SECOND“ vorgegeben werden, wobei der Thread sich in Zeile 8 aus dieser
Konstante die maximale Ausführungszeit pro Frame errechnet z. B. 1000 / 30 Frames per Secund
= 33,3 ms. Innerhalb der eigentlichen Schleife (Zeile 12 – 14) werden nun 3 Methoden aufgerufen.
Christian Burmeister
Anhang 14
Die erste Methode ist die repaint-Methode, die intern wiederum die paint-Methode mit einem neuen
Graphics-Objekt aufruft. Dabei kommt ein sogenannter "Double Buffer" zum Einsatz, welcher
verhindern soll, dass der Bildschirm anfängt zu flackern. Die serviceRepaints-Methode sorgt dafür,
dass die repaint-Methode auch wirklich sofort ausgeführt wird. Die letzte der drei Methoden
„Thread.yield()“ sorgt dafür, dass kurzzeitig ander Threads ausgeführt werden dürfen, die sonst
vielleicht nicht zum Zuge kommen würden.
Quelltext 5.4 (Programm: Game_01_GameLoop)
Mit dieser Spielschleife ist nun sichergestellt, dass die paint-Methode höchstens 30 mal pro
Sekunde aufgerufen wird. Zu beachten ist aber, dass die Leistungsfähigkeit einiger Endgeräte nicht
ausreichen könnte, um die paint-Methode 30 mal pro Sekunde aufrufen.
Innerhalb der paint-Methode muss jetzt aber zuerst die alte Leinwand „übermalt“ werden, bevor
neue Elemente gezeichnet werden können. Dies wird mittels der clearDisplay-Methode realisiert
die aus Platzgründen hier nicht abgebildet wurde. Innerhalb dieser Methode wird einfach ein
gefülltes Rechteck (fillRect()) über die komplette Leinwand gezeichnet
Der komplette Quelltext, zu diesem und allen folgenden Beispiel, ist jeweils auf der beiliegenden
CD unter „Beispiele/Game_<PROGRAMM>/src“ zu finden.
5.1.2Animation
Im Folgenden soll nun schrittweise am Beispiel des Programms „Game_02_WalkMario“ gezeigt
werden, wie man eine animierte Spielfigur mithilfe der Tastatur über den Bildschirm bewegen kann.
In diesem Abschnitt soll zunächst auf die Animation der Spielfigur eingegangen werden, im
Abschnitt 5.1.3 wird dann auf die Steuerung per Tastatur eingegangen.
Bei den meisten 2D-Spielen sind die Spielfiguren (sog. Sprites) nicht statisch, sondern verändern
ihr Haltung in Abhängigkeit von der momentanen Bewegungsrichtung, z. B. wenn eine Figur nach
links geht, schaut sie auch in diese Richtung und bewegt die Beine dabei entsprechend. Um
diesen Effekt in 2D-Spielen nachzuahmen, könnte man jeden einzelnen Frame in Echtzeit rendern
lassen, dies ist aber meist aufgrund der geringen Rechenleistung der Endgeräte nicht
Christian Burmeister
Anhang 15
wünschenswert. Deshalb werden im Vorhinein mehrere Frames erstellt, die die Spielfigur in
unterschiedlichen Haltungen darstellen. Um den Eindruck einer flüssigen Bewegung zu erreichen,
werden für eine Bewegungsrichtung meist mehre Frames erstellt, die dann schnell hintereinander
eingeblendet werden. Im der nachfolgenden Abbildung ist ein Beispiel für die Spielfigur „Mario“
gegeben. Die Abbildung besteht dabei aus 20 Frames, die jeweils eine Größe von 16 x 32 Pixel
besitzen.
Abbildung 5.4 Quelle: [MARIOSP] (Programm: Game_02_WalkMario)
Wie man in der Abbildung erkennen kann, werden mit den 20 Frames insgesamt vier
Bewegungsrichtungen realisiert. Es werden also immer 5 Frames zu einer Gruppe
zusammengefasst. Daher lassen sich die folgenden Gruppen von links nach rechts identifizieren:
RECHTS, OBEN, UNTEN und LINKS.
Alle 20 Frames werden dabei in einer einzelnen PNG-Datei gespeichert, dies spart nicht nur Platz
(nur ein Datei-Header), sonder auch Zeit beim Laden der Grafiken. PNG-Dateien werden bei der
Spieleprogrammierung bevorzugt eingesetzt, da sie nicht nur auf fast allen mobilen Endgeräten
unterstützt werden, sonder auch die Möglichkeit bieten Pixel transparent darzustellen. Die
Transparenz wird dabei über den sogenannten Alphakanal realisiert, der zusätzlich zu den drei
anderen Farbkanälen (rot, grün, blau) gespeichert wird. Da Grafiken immer rechteckig sind, ist es
nun möglich, den umgebenden Bereich, der nicht zum Sprite gehört, mit dem maximalen Alphawert
zu belegen, und dadurch mittels des Alpha Blendings den Hintergrund durchscheinen zu lassen.
Dieser Effekt wird auch bei der „Mario“-Spielfigur verwendet.
Nach diesem kleinen Abschweif, wollen wir uns damit beschäftigen, wie wir diese 20 Frames
passend zu der aktuellen Bewegungsrichtung anzeigen lassen können. Ziel soll es dabei sein,
dass z. B. wenn die Spielfigur nach oben geht, die Gruppe „OBEN“ ausgewählt wird und bei jedem
Aufruf der paint-Methode ein Frame aus der Gruppe ausgewählt und gezeichnet wird.
Um dieses Ziel zu erreichen, benötigen wir eine Technik, mit der es uns mögliche ist einen
einzelnen Frame aus dem Bildstreifen auf die Leinwand zu zeichnen. Die Technik um dieses zu
erreichen nennt sich Clipping. Das Graphics-Objekt welches der paint-Methode übergeben wird,
stellt dazu die Methode „setClip (int x, int y, int width, int height)“ zu Verfügung. Durch den Aufruf
dieser Methode wird festgelegt, in welchem Bereich gezeichnet werden darf. Die folgende
Abbildung soll dies veranschaulichen.
Abbildung 5.5
Die ersten beiden Parameter der setClip-Methode legen die X und Y-Position (xc,yc) des ClippingBereiches fest, die beiden Letzten legen die Breite und Höhe fest. In unserm Fall stellt der Punkt
(xc,yc) die Position da, an der die Spielfigur gezeichnet werden soll. Die Breite und Höhe des
Clipping-Bereiches ergibt sich aus den Abmessungen der Spielfigur (16 x 32 Pixel), daher würde
Christian Burmeister
Anhang 16
der Methodenaufruf in etwa wie folgt lauten „g.setClip(marioX,marioY,16,32);“. Damit haben wir
nun festgelegt, dass nur im Clipping-Bereich (in Abbildung 5.2 weiß dargestellt) gezeichnet werden
darf. Um die Figur nun zu zeichnen, wird der Bildstreifen so verschoben, dass der entsprechende
Frame sich genau über dem Clipping Bereich befindet. Die Y- Koordinate (y‘) des Bildstreifens
bleibt dabei unverändert, die X- Koordinate (x‘) wird nach der folgenden Formel errechnet:
xc -(FrameNummer * FrameBreite). In unserem Beispiel wäre dies „marioX - (7 * 16)“. Nach dem
Zeichen muss der Clipping-Bereich natürlich wieder zurückgesetzt werden, indem die komplette
Leinwand als Clipping-Bereich definiert wird, also xc = x0 = 0, yc = y0 = 0 und die Länge und Breite
der Leinwand.
Im Quelltext 5.2 ist die Methode abgebildet, die die beschriebenen Aktionen durchführt. Zeile 3
definiert dabei zuerst den Clipping-Bereich an der die Spielfigur gezeichnet werden soll, danach
wird das Bild in Zeile 4 versetzt gezeichnet und zum Schluss wird der Clipping-Bereich in Zeile 5
wieder zurückgesetzt.
Quelltext 5.5 (Programm: Game_02_WalkMario)
Den ersten Teil unseres Ziels haben wir bereits erreicht, wir wissen, wie man einen einzelnen
Frame auf der Leinwand zeichnet. Der zweite Teil unseres Zieles besteht darin eine Methode zu
entwickeln, die in Abhängigkeit von der momentanen Bewegungsrichtung, eine passende
Framenummer zurückliefert, die dann der drawFrame-Methode übergeben werden kann.
Wenn wir beim Beispiel bleiben, dass unser Mario nach oben geht, dann wäre es wünschenswert,
wenn wir die Framenummernfolge von 5,6,7,8,9,5,6,7,8,9,5,6,7,8,9,usw. erzeugen könnten, um
den Eindruck einer Gehbewegung zu erzielen. Es ist aber nicht ratsam die Framenummer mit
jedem Aufruf der paint-Methode hochzuzählen, da so unsere Spielfigur 30 Schritte pro Sekunde
zurücklegen würde. Deshalb müssen wir eine kleine Verzögerung einbauen, die es ermöglicht z. B.
nur alle drei Aufrufe weiterzuschalten. Ein Beispiel für die Framenummernfolge wäre etwa
5,5,5,6,6,6,7,7,7,8,8,8,9,9,9,5,5,5,usw. Um dies zu erreichen wurde die Methode „getFrame()“
entwickelt die in Quelltext 5.3 Zeile 1 – 9 abgebildet ist.
Quelltext 5.6 (Programm: Game_02_WalkMario)
Mit dem Parameter „frame“ wir die Framenummer der Spielfigur übergeben, mit der zuletzt
gezeichnet wurde. Mit „min“ und „max“ legt man den minimalen und maximalen Frame der Gruppe
fest und „step“ legt fest wie oft der aktuelle Frame wiederholt werden soll bis eine Umschaltung auf
den nächsten Frame erfolgt. In Zeile 3 wird zuerst überprüft, ob der aktuelle Frame sich innerhalb
der ausgewählten Gruppe befindet, wenn nicht wird der Frame auf den kleinsten Frame der
Gruppe gesetzt. In Zeile 4 wird mithilfe des Modulo-Operators die Verzögerung erzeugt,
Christian Burmeister
Anhang 17
„timerFrame“ ist dabei eine einfache Zählvariable, die mit jedem „increaseFrameTimer() „Aufruf
inkrementiert wird (Zeile 10 - 14). Die Auslagerung der Inkrementierung ist nötig, da in einem Spiel
meist mehrere Figuren innerhalb eines paint-Methode-Zykluses bewegt werden müssen. Der
Ausdruck „timerFrame % step == 0“ wird damit z.B. nur alle 3 paint-Zyklen zu „true“ ausgewertet
(wenn step = 3) und inkrementiert damit die Framenummer (Zeile 5). In Zeile 6 wird noch
überprüft, ob der maximale Frame der Gruppe überschritten wurde , wenn dies der Fall ist, wird
wieder auf den minimalen Frame der Gruppe gewechselt. Zurückgegeben wird die Framenummer,
die als nächstes gezeichnet werden soll. Bei unserm Beispiel, würde der Aufruf dann wie folgt
lauten: getFrame(X, 5, 9, 3), „X“ ist dabei der Frame der zuletzt gezeichnet wurde.
Um unser Spielfigur zu animieren müssen die drei Methoden noch an der richtigen Stelle im
Quelltext platziert werden. In Quelltext 5.4 ist ein Ausschnitt aus dem Programm
„Game_02_WalkMario“ gegeben, anhand dem man erkennen kann, wie die einzelnen Aufrufe
platziert werden müssen.
Quelltext 5.4 (Programm: Game_02_WalkMario)
In der paint-Methode wird zunächst in Zeile 7 der FrameTimer mit der Methode
„increaseFrameTimer()“ erhöht, danach wird die Leinwand geleert. In Zeile 8 wird die Spielfigur
zuerst mittels der moveFigur-Methode bewegt und anschließend mit der drawFigur-Methode
gezeichnet.
In der moveFigure-Methode (Zeile 11 – 21) wird die Spielfigur bewegt. Dies geschieht anhand der
boolschen-Variablen „down“, „up“ , „left“ und „right“, wobei die beiden letzteren in Quelltext 5.4 aus
Platzgründen weggelassen wurden. Die Variablen können entweder durch eine Tasteneingabe
gesetzt werden (Abschnitt 5.1.3) oder auch durch ein passenden Algorithmus.
Wenn z. B. die Variable „up“ den Wert „true“ besitzt, bewegt die Spielfigur sich nach oben. Um dies
zu erreichen, wird zunächst in Zeile 17 die Y-Position entsprechend der Geschwindigkeit der
Spielfigur verringert und in Zeile 18, mit der bereits besprochenen getFrame-Methode, ein
passender Frame aus der Gruppe „OBEN“ (min = 5, max = 9) der Variable „figureFrame“
zugewiesen. Beim Setzen der andern boolschen-Variablen läuft dies vergleichbar ab. Zu beachten
ist, dass je nur eine der Variablen auf „true“ gesetzt sein sollte.
In der drawFigure-Methode wird die Spielfigur nun auf die Leinwand gezeichnet.
Christian Burmeister
Anhang 18
Hierbei kommt die bereits besprochene Methode „drawFrame()“ zum Einsatz, die die zuvor
zugewiesene Framenummer (figureFrame) an die Position (figureX, figureY) zeichnet.
In unserm Beispiel ist die Bewegungsart noch relativ einfach, da die X und Y-Positionen nur
entsprechend der Geschwindigkeit der Spielfigur geändert wird. In manchen Spielen ist es aber
nötig, dass die Spielfigur springt und fällt. Um dies zu realisieren, bedarf es etwas mehr Aufwand.
Aus Platzgründen soll hier auf eine Erläuterung verzichtet werden, wer aber dennoch Interesse hat,
kann im Beispielprogramm „Game_05_SuperMarioBros“ (Klasse Mario, Methode „move()“)
nachsehen.
5.1.3Tastensteuerung
Die Behandlung von Benutzerinteraktionen ist ein sehr wichtiges Thema bei der
Spieleprogrammierung, da fast jedes Spiel auf Interaktionen des Spielers reagieren soll. Dabei
beschränken sich die Benutzerinteraktionen, bei Mobiltelefonen, meist auf die Zifferntasten,
Funktionstasten und ein Steuerkreuz mit Auswahltaste.
Um innerhalb unseres Spieles abzufragen, ob eine Taste gedrückt oder losgelassen wurde, stellt
die Klasse „Canvas“ zwei Methoden bereit. Die erste der beiden Methode heißt „keyPressed(int
key)“, sie wird jedes mal aufgerufen, sobald eine Taste gedrückt wird, die gedrückte Taste wird
dabei als Parameter (key) übergeben. Die zweite Methode heißt „keyReleased(int key)“ und wird
aufgerufen, sobald eine Taste wieder losgelassen wird.
Die Auswertung des key-Parameters ist leider nicht einheitlich umgesetzt. Um zum Beispiel die
Zifferntasten auszuwerten, stellt die Canvas-Klasse mehrere Klassenvariablen zur Verfügung, die
direkt mit dem key-Paramter verglichen werden müssen.
KEY_NUM0 - KEY_NUM9 steht dabei für die Zifferntasten 1 bis 9, KEY_STAR für die „*“-Taste und
KEY_POUND für die „#“-Taste.
Um das Steuerkreuz abzufragen muss dagegen auf die Funktion „getGameAction(int key)“
zurückgegriffen werden, die ebenfalls von der Canvas-Klasse zu Verfügung gestellt wird. Die
Methode liefert dabei anhand des übergebenen key-Parameters einen Wert zurück, der mit den
folgenden Klassenkonstanten verglichen werden kann: UP, DOWN, RIGHT, LEFT, FIRE,
GAME_A, GAME_B, GAME_C und GAME_D. Die ersten vier Konstanten stehen dabei für die
Richtungen des Steuerkreuzes und „FIRE“ für die Auswahltaste des Steuerkreuzes. Die GAMETasten werden vom Hersteller des Gerätes zugeordnet und können daher vom Endgerät zu
Endgerät auf unterschiedlichen Tasten platziert sein, meisten aber Zifferntasten (1,3,7,9)
Im Nachfolgenden ist ein Auszug aus dem WalkMario-Programm gegeben, das die Variablen „up“ ,
die bereits im vorhergehenden Abschnitt erwähnt wurden, entsprechend setzt. Das Setzen der
Variablen „down“, „left“ und „right“ erfolgt dabei entsprechend. Dabei ist es egal, ob das
Steuerkreuz (Zeile 4, 13 )oder die Zifferntasten 2 (Zeile 7, 16 ) zur Steuerung verwendet werden.
Quelltext 5.5 (Programm: Game_02_WalkMario)
Christian Burmeister
Anhang 19
Wie man im Quelltext erkennen kann, wird auch in Zeile 8 die „*“-Taste abgefragt um das
Programm ordnungsgemäß beenden zu können.
Zu beachten ist allerdings, dass die meisten mobilen Endgeräte das gleichzeitige Drücken
mehrerer Tasten nicht unterstützt. Der JavaME-Emulator vom Sun unterstützt dies allerdings,
daher wurde zum besseren Testen, dies in Zeile 2 künstlich deaktiviert, indem einfach alle Tasten
auf „false“ gesetzt werden. Wenn Tasten nicht gleichzeitig gedrückt werden können, hat dies in
machen Situationen unschöne Auswirkungen, z.B. wenn man gleichzeitig nach rechts laufen und
dabei springen will geht dies nicht. Dieser Umstand muss bei der Entwicklung von Spielen beachtet
werden. Um dieses Problem dennoch zu lösen, könnte man für die Aktion „rechts laufen und dabei
springen“ die Taste 3 (KEY_NUM3) belegen.
5.1.4Erstellung eines Levels
In diesem Abschnitt wollen wir uns nun mit der Erstellung eines Levels beschäftigen. Dabei
bezieht sich das Beispiele auf das Programm „Game_02_WalkMarioTiles“.
Ähnlich wie bei älteren Computerspielen, ist auch bei der 2D-Spieleentwicklung auf mobilen
Endgeräten das Verfahren der kachelbasierten Levelerstellung (tile-based design) verbreitet. Dabei
werden kleine Bildchen, die sogenannten Kacheln (engl. Tiles), mosaikartig zu einem Level
zusammengesetzt. Der Vorteil dieses Verfahrens besteht darin, dass sehr wenig Arbeitsspeicher
benötigt wird, welcher bei mobilen Endgeräten meist nicht sehr üppig ausfällt. Die Kachelgröße
wird meist einheitlich für ein Spiel festgelegt, daher ist es wieder, möglich alle Kacheln in einer
einzigen PNG-Datei zu speichern. In Abbildung 5.3 ist ein Beispiel für zwei 16 x 16 Pixel Kacheln
gegen, die aus dem Spiel „Game_02_WalkMarioTiles“ übernommen wurde.
Abbildung 5.6 (Programm: Game_02_WalkMarioTiles)
Mit den beiden abgebildeten Kacheln kann nun mithilfe eines Tile-Editors ein Level erstellt werden.
Sehr gut geeignet ist hierfür das Tile Studio [TILESTUDIO]. An dieser Stelle soll aber nicht näher
auf dieses Programm eingegangen werden, im Abschnitt 8.2 befindet sich aber eine ausführliche
Anleitung zum Erstellen und Exportieren eines Levels mithilfe des Tile Studios.
Nach Erstellung der Karte erhält man ein Array aus Zahlenwerten, dass in Abbildung 5.4 zu sehen
ist. Das abgebildete Array ist dabei zweidimensional und besitzt eine Größe von 20 x 28 Kachel.
Gespeichert werden dabei nur die Zahlenwerte „0“ und „1“, dies kommt daher, da in Abbildung 5.3
nur zwei Kacheln abgebildet sind. Demnach steht der Zahlwert „0“ für die Boden-Kachel und „1“ für
die Wand-Kachel.
Abbildung 5.7 (Programm: Game_02_WalkMarioTiles)
Christian Burmeister
Anhang 20
Diese Art der Speicherung bietet einige Vorteile, zum einen benötigt es sehr viel weniger
Speicherplatz, im Vergleich zur Speicherung der Karte als vollständiges Bild. Zum anderen ist es
sehr viel flexibler, da z.B. Zahlenwerte innerhalb des Arrays zur Laufzeit verändert werden können.
5.1.5Scrolling des Levels
Da unser eben erstelltes Level eine Abmessung von 20 x 28 Kacheln hat, also 320 x 448 Pixel, ist
es für die meisten mobilen Endgeräte viel zu groß, um vollständig auf dem Display angezeigt zu
werden. Daher muss die Karte in Abhängigkeit von der Position der Spielfigur verschoben werden,
so das die Spielfigur immer innerhalb des sichtbaren Bildschirmausschnitts (Viewport) ist.
Die einfachste Art dies zu realisieren, ist eine Translation auf dem Viewport durchzuführen, denn
so müssen nicht alle andern Koordinaten, z. B. der Spielfigur und Gegner, angepasst werden. Um
dies innerhalb unseres Spieles zu realisieren stellt das Graphics-Objekt der paint-Methode die
Methode „translate(int x, int y)“ zur Verfügung. Die übergebenen Werte sorgen dafür, dass der
momentane Koordinatenursprung (linke obere Ecke) an eine neue Position verschoben wird.
Das nachfolgende Bild soll dies Veranschaulichen.
Abbildung 5.8 (Bild 1 vor Translation, Bild 2 nach Translation)
In Bild 1 der Abbildung 5.5 wurde noch keine Translation durchgeführt, daher ist die obere linke
Ecke von Karte und Viewports (Bildschirm) deckungsgleich. Die translate-Funktion wird nun mit
den neuen Werten (xt, yt) aufgerufen, die Werte befinden sich dabei im negativen Bereich.
Dadurch wird der Koordinatenursprung (x0, y0) an die Stelle (xt, yt) verschoben, dies ist im Bild 2
zu sehen. Durch die Translation des Koordinatenursprung änderst sich auch die Koordinate der
obere linke Ecke des Viewports (-xt, -yt), obwohl die Position eigentlich nicht verändert wurde.
Nach der Translation ist auch unser Spielfigur wieder im Viewport zu sehen, obwohl sie immer
noch die gleiche Koordinate wie vor der Translation besitzt. Den Viewport kann man sich demach
als Bilderrahmen vorstellen und die Karte als Bild. Der Bilderrahmen bleibt immer an der gleichen
Position nur das sich dahinter befindliche Bild wird verschoben.
Um die Translation durchzuführen, wurde die Methode „scrollMap()“ entwickelt, innerhalb dieser
die Translation durchgeführt wird. Wie man in Quelltext 5.6 in Zeile 3 erkennen kann, wird zuerst
die Figur bewegt und erst danach die Karte verschoben, dies ist notwendig, da die TranslationsWerte anhand der X und Y- Koordinate der Spielfigur bestimmt werden. Gezeichnet werden die
Karte und die Spielfigur aber erst nach der Verschiebung des Koordinatenursprungs. Die
Reihenfolge der Aufrufe ist hier sehr wichtig, da sonst die Koordinaten von Spielfigur und Karte
nicht zusammen passen würden.
Christian Burmeister
Anhang 21
Quelltext 5.6 (Programm: Game_02_WalkMarioTiles)
Die eigentliche srollMap-Methode sieht nun wie folgt aus:
Quelltext 5.7 (Programm: Game_02_WalkMarioTiles)
In Zeile 2 bis 7 wird der xt-Wert bestimmt, dabei wird Zeile 4 ausgeführt, wenn die Spielfigur nach
unter läuft und Zeile 6 wenn die Spielfigur wieder nach oben läuft. Eine Änderung des xt-Wertes
geschieht nur, wenn sich die Spielfigur in der mittleren Breite des Viewports befindet (canvasWith /
2). In Zeile 8 bis 13 wird der yt-Wert bestimmt, das Vorgehen ist dabei ähnlich.
In Zeile 14 wird nun die eigentliche Translation durchgeführt.
Dadurch, dass sich der Koordinatenursprung immer an der linken oberen Ecke der Karte befindet,
hat die Translation keine Auswirkungen auf die X und Y-Koordinaten der Spielfigur oder anderer
Objekte. Eine Ausnahme gibt es allerdings, und zwar, wenn Spielinformationen am oberen Rand
des Viewports eingeblendet werden sollen. Um dieses Problem zu umgehen kann eine zweite
Translation durchgeführt werden, die in Quelltext 5.6 in Zeile 7 abgebildet ist. Damit verschiebt
man den Koordinatenursprung an die linke obere Ecke des Viewports, danach kann dann wie
gewohnt an Stelle (0,0) gezeichnet werden. Beachten sollte man dabei, dass sich innerhalb eines
paint-Zyklus die Translationen kumulativ auswirken aber in jedem neuen paint-Zykus der
Urzustand wiederhergestellt ist. Dies ist so, weil immer ein neues Graphics-Objekt der paintMethode übergeben wird.
5.1.6Zeichnen des Levels
Wir wissen jetzt wie man eine Karte erstellt und wie man eine Karte, in Abhängigkeit von der
Position der Spielfigur, verschieben kann. Was wir aber noch nicht wissen ist, wie wir die Karte
zeichnen können. In Quelltext 5.6 war bereits der Aufruf der drawMap-Methode zu sehen, diese
soll nun im Nachfolgenden vorgestellt werden.
Christian Burmeister
Anhang 22
Quelltext 5.8 (Programm: Game_02_WalkMarioTiles)
Wie man in Zeile 2 und 3 erkennen kann, werden zwei ineinander geschachtelte For-Schleifen
durchlaufen. Weil wir nicht die komplette Karte zeichnen wollen, sondern nur den sichtbaren
Bereich, also den Viewport, wird ab den Punkt (-xt, -yt) begonnen. Durchlaufen wird dabei die
komplette Breite und Höhe des Viewports. Da wir Kacheln (Tiles) zeichnen wollen, die eine Größe
von 16 Pixeln haben, wird bei jedem Durchlauf der x und y-Wert um 16 Pixel inkrementiert
(TILESSIZE). In Zeile 4 und 5 wird der x und y-Wert auf die Kachelgröße geeicht, damit ist
sichergestellt, dass sie immer auf die linke ober Ecke der Kachel verweisen. In Zeile 6 und 7 wird
überprüft ob der x und y Wert innerhalb des gültigen Bereiches liegt, der in der Karte gespeichert
ist. In Zeile 8 wird nun die Kachelnummer gespeichert, die sich an der aktuellen Position befindet.
Zum Schluss wird die Kachel dann mit der bereits bekannten Methode „drawFrame()“ an die
aktuelle Position gezeichnet.
5.1.7Kollisionserkennung im Level
Wenn man das Programm „Game_02_WalkMarioTiles“ ausführt, merkt man schnell, dass sich die
Spielfigur nach Belieben auf der Karte bewegen kann. Dies kommt daher, weil noch nicht
festgelegt wurde, dass Wand-Kacheln ein Hindernis darstellen sollen. Um dies zu realisieren,
benötigen wir eine Technik zur Kollisionserkennung, die es uns ermöglicht, festzustellen ob unsere
Spielfigur mit einer Wand-Kachel kollidiert. Es müssen dabei nicht alle Kacheln auf eine Kollision
hin überprüft werden, es reicht aus, wenn sechs Kacheln überprüft werden, da sich die Spielfigur
gleichzeitig maximal auf sechs Kacheln befinden kann.
Abbildung 5.9 (Programm: Game_04_WalkMarioTilesCollison)
Wie man in der Abbildung erkennen kann, sind die sechs umgebenden Kacheln durch Boxen
hervorgehoben. Dabei sind diese Boxen normalerweise nicht sichtbar, sie dienen hier lediglich zur
besseren Anschaulichkeit.
Christian Burmeister
Anhang 23
Im Programm „Game_04_WalkMarioTilesCollison“ wurden die Boxen zu Demonstrationszwecken
ebenfalls implementiert, wenn das Programm läuft kann man sie über die Taste „0“ ein und
ausschalten.
In der Abbildung 5.6 ist die untere rechte Box blau dargestellt, dies soll signalisieren, dass bei
dieser Kachel eine Kollision vorliegt, da sich der Fuß der Spielfigur auf der Wand-Kachel befindet.
Um diese Technik nun im Spiel verwenden zu können, wurde die „checkBorderTiles()“ Methode
entwickelt, die in Quelltext 5.9 abgebildet ist. Dabei werden zunächst in Zeile 2 bis 13 die linken
oberen Ecken der sechs Boxen ermittelt. Um nun zu überprüfen ob es sich bei den sechs Kacheln
um eine Wand-Kachel handelt, wird in Zeile 15 bis 26 die jeweils errechnete X und Y-Position, der
oberen linken Ecke, als Index in das Karten-Array eingesetzt. Wenn sich an dieser Position eine
Wand-Kachel befindet, bricht die Methode ab und liefert „true“ zurück, wenn die Figur keine WandKachel berührt wird „false“ zurückgegeben.
Quelltext 5.9 (Programm: Game_04_WalkMarioTilesCollision)
Diese Methode kann nun in der bereits bekannten moveFigure-Methode verwendet werden. Im
Quelltext 5.10 ist ein Ausschnitt aus dieser Methode abgebildet.
Um nun zu bestimmen, ob die Spielfigur gegen ein Hindernis stößt, wird zunächst die Position
entsprechende der Geschwindigkeit der Spielfigur geändert (Abbildung 5.10, Zeile 3). Danach wird
mittels der checkBorderTiles-Methode überprüft ob die Figur gegen eine Wandkachel gelaufen ist,
wenn dies der Fall ist, wird die davor gemachte Positionsänderung wieder rückgängig gemacht
(Zeile 5).
Christian Burmeister
Anhang 24
Quelltext 5.10 (Programm: Game_04_WalkMarioTilesCollision)
Damit hätten wir nun erreicht, dass die Spielfigur nicht mehr nach belieben durch Wände
hindurchgehen kann, sondern an diesen gestoppt wird.
5.1.8Kollisionserkennung bei Objekten
Um Kollisionen mit anderen Objekten zu erkennen wird eine ähnliche Technik verwendet. Diese
setzt sogenannte Bounding-Boxes ein. Eine Bounding-Box ist dabei eine rechteckige Box die
genau um das Objekt gezeichnet wird. Wenn sich zwei solcher Boxen überschneiden liegt eine
Kollision vor. Die folgende Abbildung soll dies veranschaulichen.
Abbildung 5.10 (Kollisionserkennung zwischen Spielfigur und Objekt)
Die Boxen sind normalerweise auch nicht zu sehen, sie wurden hier ebenfalls nur zur
Demonstrationszwecken eingezeichnet. Im Programm „Game_04_WalkMarioTilesCollision“ lassen
sich die Bounding-Boxen über die Taste „5“ ein und ausschalten.
Um diese Technik im Spiel nutzen zu können wurde die beiden folgenden Methoden entwickelt.
Christian Burmeister
Anhang 25
Quelltext 5.11 (Programm: Game_04_WalkMarioTilesCollision)
Der checkCollision-Methode , welche die eigentliche Kollisionserkennungsmethode ist, werden
zwei Rechteck übergeben, die jeweils durch zwei Punkte beschrieben werden. Wenn sich die
beiden Rechtecke überlagern liefert die Methode „true“ sonst den Wert „false“ zurück.
In der checkCollisionFigureRubin-Methode wird zunächst die ceckCollison-Methode aufgerufen.
Dabei werden als Parameter die Eckpunkte der Spielfigur und des Objektes (hier ein Rubin)
übergeben. Wenn die beiden Bounding-Boxen sich überschneiden wird in Zeile 7 der Punktestand
erhöht und die Variable „rubinLocated“ auf „true“ gesetzt. Diese Variable wird in der nicht
abgebildeten Methode „drawRubin()“ abgefragt, und entscheidet darüber ob der Rubin gezeichnet
werden soll.
5.2Beispielprogramme
Im Rahmen dieser Ausarbeitung sind insgesamt sechs JavaME-Programme entstanden, von
denen jeweils ausgewählte Ausschnitte in den vorigen Abschnitten beschrieben wurden. Da diese
Ausarbeitung auf 25 Seiten begrenzt ist, kann auch leider nicht näher auf diese Programme
eingegangen werden. Im Anhang 8.3 befindet sich aber zu jedem Programm eine kurze
Anwenderbeschreibung, die auf die Funktion des Programms und die Eingabemöglichkeiten
eingeht. Weiterhin befindet sich auf der beilegenden CD im Ordner „Beispiele“ das komplette
Projekt-Verzeichnis zu den jeweiligen Programmen.
An dieser Stelle soll noch kurz auf das Programm „Game_05_SuperMarioBros“ eingegangen
werden, welches eigentlich in Rahmen dieser Ausarbeitung besprochen werden sollte. Dies war
aber auf Grund der Komplexität des Programmes leider nicht mit der Beschränkung der
Ausarbeitung auf 25 Seiten vereinbar. Aus diesem Grunde soll hier nur ein kleiner Überblick über
das Programm gegeben werden, um es dem interessierten Leser zu erleichtern sich selbst in den
Quellcode einzuarbeiten.
Als Vorlage für das Spiel dient das Jump ‘n‘ Run Spiel „Super Mario Bros“ der Firma Nintendo,
welches, mit Hilfe der im Abschnitt 5.1 kennengelernten Techniken, versucht wurde nachzubauen.
Um einen ersten Eindruck vom Spiel gewinnen zu können, empfiehlt es sich den Abschnitt 8.3.6 zu
lesen. Dort werden zum einen drei Screenshorts des Spieles gezeigt und zum anderen die
Eingabemöglichkeiten und das Ziel des Spieles erklärt.
In diesem Spiel wird nicht nur eine Spielfigur animiert, sondern mehrere. Dazu gehört zum einen
die Hauptspielfigur „Mario“ die einmal „groß“ und einmal „klein“ sein kann und zum anderen
mehrere Gegner, ein Pilz, der die Hauptspielfigur „groß“ machen kann, und ein animiertes
Geldstück das immer erscheint, wenn „Mario“ von unten gegen eine Fragezeichenbox hüpft.
Um dies zu realisieren werden mehrere Klassen benötigt, die in Abbildung 5.8 in einem
Klassendiagramm dargestellt sind.
Christian Burmeister
Anhang 26
Abbildung 5.11 (Programm: Game_05_SuperMarioBros)
Die bereits aus Abschnitt 3.3 bekannte Klasse „myMIDlet“ dient wieder als Einstiegspunkt in das
Spiel. Sie erzeugt eine neue Instanz der Klasse „GameCanvas“ und startet damit das Spiel. In der
Klasse GameCanvas befindet sich unter anderem die Spielschleife und die Behandlung der
Tastendrücke. In der Spielschleife wird durch die Klasse „Game“ das Spiel gezeichnet. Dabei stellt
die Klasse „Game“ den zentralen Bestandteil des Spieles da, in ihr werden alle benötigten
Spieleobjekte erzeugt und der Ablauf des Spieles durch Verwendung von Zuständen gesteuert.
Das Spiel befindet sich dabei immer in einem der folgenden fünf Zustände:
-
PLAY: wird ausgeführt, wenn normal gespielt wird.
-
INTRO: wird ausgeführt, wenn das Spiel neu startet
-
MARIO_HIT: wird ausgeführt, wenn die Spielfigur durch einen Gegner oder einen
Wassergraben ein Leben verloren hat.
-
GAME_OVER: wird ausgeführt, wenn die Spielfigur alle drei Leben verbraucht hat
-
FINISHED: wird ausgeführt, wenn das Ziel (Fahnenmast) des Spiels erreicht ist.
Weiterhin ist sie für das Scrolling der Karte zuständig und für die Kollisionserkennung zwischen
den einzelnen Sprites.
Die Klasse „Level“ ist für die Erzeugung und Zeichnen der Karte zuständig, und stellt weiterhin
Methoden bereit um abzufragen auf welcher Kachel sich eine Spielfigur befindet (z.B. für
Kollisionserkennung).
Die Klasse „Sprite“ ist eine abstrakte Klasse, die allgemeine Funktionen der Spielfiguren
zusammenfasst, von ihr werden die vier Klassen „Enemy“, „Money“, „Mushroom“ und „Mario“
abgeleitet. In diesen vier Klassen wird das Verhalten und Erscheinungsbild der einzelnen
Spielfiguren festgelegt.
Die Klasse „Toolbox“ ist eine statische Klasse, die allgemeine Funktionen bereitstellt, die von
mehren Klassen benötigt werden.
Christian Burmeister
Anhang 27
6.Abschluss
6.1Anmerkungen zur Ausarbeitung
Während der Erstellung dieser Ausarbeitung sind eigentlich keine größeren Problem aufgetreten.
Sehr schwer ist es mir jedoch gefallen, mich an die vorgegebene Beschränkung von 25 Seiten zu
halten. Denn dadurch war es mir leider nicht möglich auf mein eigentliches Programm
„Game_05_SuperMarioBros“ genauer einzugehen. Daher musste ich mich im Rahmen dieser
Ausarbeitung nur auf die Grundlagen der 2D-Spieleprogrammierung beschränkt, die anhand von
einfachen Beispielen demonstriert wurden.
Weiterhin wollte ich auch noch kurz auf die seit MIDP 2.0 verfügbare JavaME Game-API eingehen.
Diese API stellt im Namensraum javax.microedition.lcdui.game insgesamt fünf Klassen
bereit, die ein Teil der in dieser Ausarbeitung erwähnten Funktionalitäten zur Verfügung stellen. Ich
habe aber bewusst auf den Einsatz dieser API verzichtet, da sie zum einen nur im MIDP 2.0 zur
Verfügung steht und damit weder im MIDP 1.0 noch in der normalen Java-Edition verwendet
werden dann. Und zum anderen ein großer Teil der Flexibilität verloren geht, den man durch den
Einsatz von eigenen Methoden erlangt. Es währe aber dennoch interessant gewesen, diese API
einmal genau zu betrachten. Dem interessierten Leser sei daher die Webseite [SUNGAME]
empfohlen.
6.2Schlusswort
Ich hoffe, dass ich mit dieser Ausarbeitung, zumindestens einen kleinen Einblick, in die
behandelten Themengebiete geben könnte. Obwohl die 2D-Spieleprogrammierung nicht meine
erste Wahl war, hat es mir dennoch viel Spaß gemacht dieses Thema zu bearbeiten. Mich hat
dabei positiv Überrascht, dass die Entwicklung einfacher 2D-Spiele mit relativ wenig
Programmieraufwand zu bewerkstelligen ist. Dies lag mit Sicherheit auch an der JavaME-Edition
die den Umstieg von JavaSE nicht sehr schwer machte. Denn obwohl die JavaME-Edition stark
eingeschränkt ist, bietet sie dennoch fast alles was man von JavaSE-Edition gewohnt ist.
Christian Burmeister
Anhang 28
7.Literatur und Verzeichnisse
7.1Literaturverzeichnis
[BR06JAVAME]JavaME, Anwendunsentwicklung für Handys, PDA und Co.
Ulrich Breymann und Heiko Mosemann, ISBN: 3-446-22997-3
[LU08MGAME] Mobile Games, Spieleprogrammierung für Handys in Java ME
Thomas Lucka, ISBN: 978-3-446-41197-5
[PF07JAVAME]Java Micro Edition, Mobile Anwendungen mit der MIDP 2.0 entwickeln
Michael Pfeifer, ISBN: 3-89842-505-3
7.2Internetquellen
-
Die Internetquellen wurden am 06.01.2009 auf ihre Erreichbarkeit überprüft.
-
Alle Internetquellen, außer [KARBACHER] und [NOKIASDK] befinden sich auf der
beiliegenden CD im Ordner Internetquellen
[ECLIPSEME] Eclipse Plug-In für JavaME
http://eclipseme.org/
[ECLIPSE]
Integrierte Entwicklungsumgebung: Eclipse
http://www.eclipse.org/downloads/
[IBMM3G]
M3G Tutorial vom IBM
http://www.ibm.com/developerworks/java/library/wi-mobile1/
http://www.ibm.com/developerworks/wireless/library/wi-mobile2/
[JSR30]
Connected Limited Device Configuration 1.0
www.jcp.org/en/jsr/detail?id=30
[JSR37]
Mobile Information Device Profile 1.0
www.jcp.org/en/jsr/detail?id=37
[JSR118]
Mobile Information Device Profile 2.0
www.jcp.org/en/jsr/detail?id=118
[JSR139]
Connected Limited Device Configuration 1.1
www.jcp.org/en/jsr/detail?id=139
[JSR184]
M3G Version 1.0, 1.1
http://jcp.org/en/jsr/detail?id=184
http://jcp.org/aboutJava/communityprocess/mrel/jsr184/index.html
[JSR297]
M3G Version 2.0
http://jcp.org/en/jsr/detail?id=297
[KARBACHER]Diplomarbeit zu JavaME
http://www.karbacher.org/java-j2me/midlets-midletsuite/
Christian Burmeister
Anhang 29
[MARIOSP]
Mario Sprite http://www.gsarchives.net/index2.php?
category=all&system=gameboyadvance&game=mario_and_luigi_superstar_saga&
type=sprites&level0=non-animated&level1=mario
[NETBEANS]
Integrierte Entwicklungsumgebung: Netbeans
http://www.netbeans.org/downloads/index.html
[NOKIASDK]
SKD für JavaME von der Firma Nokia
http://www.forum.nokia.com/Resources_and_Information/Explore/Runtime_Platfor
ms/Java.xhtml
[PAINTNET]
Bildbearbeitungsprogramm Paint.NET
http://www.getpaint.net/download.html
[SMBMAP]
Vorlage für das erste Level im Spiel Game_05_SuperMarioBros
http://ian-albert.com/misc/smb.php
[SMBSPRITE] Sprites für das Spiel Game_05_SuperMarioBros
http://www.mariomayhem.com/downloads/sprites/super_mario_bros_sprites.php
http://www.videogamesprites.net/SuperMarioBros/
[SUN1]
Übersicht über die Java ME Plattform
http://java.sun.com/javame/technology/index.jsp
[SUN2]
Connected Limited Device Configuration Übersicht
http://java.sun.com/products/cldc/overview.html
[SUNGAME]
Java Game API
http://developers.sun.com/mobility/midp/articles/gameapi/
[SUNJDK]
Java SE Development Kit (JDK) 6
http://java.sun.com/javase/downloads/index.jsp
[SUNM3G]
Getting Started With the Mobile 3D Graphics API for J2ME
http://developers.sun.com/mobility/apis/articles/3dgraphics/
[SUNWTK]
Sun Java Wireless Toolkit for CLDC
http://java.sun.com/products/sjwtoolkit/download.html
[TILESTUDIO] Tile Studio
http://tilestudio.sourceforge.net/
[WERM3G]
Ausarbeitungen von Herr Jeronimo Werder

Mobile 3D Grahics (Ausarbeitung im Rahmen des berufspraktischen
Semesters)

Präsentation zu Mobile 3D Grahics am 21.11.08 im Fachbereich AI, FHFulda

Diplomarbeit: „Realisierung von 3D-Grafiken für mobile Endgeräte unter
Betrachtung geeigneter Grafikbibliotheken (OpenGL|ES, M3G) und
Fenstersystemen“
Zu finden auf der beiliegenden CD im Ordner „Internetquellen\WERM3G“ oder auf
Nachfrage auch bei Prof. Dr. Werner Heinzel, FH-Fulda
Christian Burmeister
7.3Abkürzungsverzeichnis
AMS
Aplication Managment Software
API
Application Programming Interface
CDC
Connected Device Configuration
CLDC
Connected Limited Device Configuration
IDE
Integrated Development Environment
J2ME
Java 2 Micro Edition -> heute: Java Micro Edition
JavaEE
Java Enterprise Edition
JavaME
Java Micro Edition
JavaSE
Java Standard Edition
JDK
Java Development Kit
JSR
Java Specification Request
JVM
Java Virtual Machine
KVM
K(ilobyte) Virtual Machine
MIDP
Mobile Information Device Profile
PDA
Personal Digital Assistant
PNG
Portable Network Graphics
SDK
Software Development Kit
WTK
Wirless Toolkit
Anhang 30
Christian Burmeister
Anhang 31
8.Anhang
8.1Einrichten von Eclipse
In diesem Abschnitt soll nun beschrieben werden, wie man ein JavaME Programm mithilfe von
Eclipse erstellen und ausführen kann. Dies soll nun im Folgenden schrittweise gezeigt werden.
8.1.1Installation des Java SE Development Kit
Um Eclipse installieren zu können, müssen wir zunächst das Java SE Development Kit (JDK)
installieren. Heruntergeladen kann man es kostenlos von der Webseite der Firma Sun [SUNJDK].
Nachdem man die Installationsdatei ausgeführt hat, wird man nach dem Installationsverzeichnis
gefragt, dabei sollte das vorgegebene Verzeichnis „C:\Programme\Java\jre6“ übernommen
werden. Am Ende der Installation muss man noch auf „Finish“ klicken um die Installation zu
beenden. Damit wäre die Installation des JDK beendet.
8.1.2Installation des Sun Java Wireless Toolkit for CLDC
Das Wireless Toolkit (WTK) stellt die Grundlage für JavaME da. Es installiert zum einen die
JavaME API und zum anderen mehre Emulatoren für JavaME. Das WTK kann dabei ebenfalls
kostenlos von der Webseite der Firma Sun heruntergeladen werden [SUNWTK].
Bei der Installation wird man als erstes nach dem Verzeichnis des Java SE Development Kit (JDK)
gefragt. Hier kann der Vorschlag übernommen werden, da das Verzeichnis
„C:\Programme\Java\jre6“ bereits ausgewählt ist. Als Installationsverzeichnis für das WTK wird „C:\
WTK2.5.2_01“ vorgeschlagen, soweit nichts dagegen spricht sollte dieses Verzeichnis
übernommen werden. Um die Installation zu beenden, muss man ebenfalls wieder auf „Finish“
klicken.
8.1.3Installation von Eclipse
Eclipse muss zunächst von der Webseite [ECLIPSE] heruntergeladen werden. Nach dem
Herunterladen muss man einfach die ZIP-Datei entpacken und das enthaltene Verzeichnis
„eclipse“ nach „C:\Programme“ kopieren.
Jetzt kann man Eclipse durch anklicken der „eclipse.exe“-Datei, die sich unter
„C:\Programme\eclipse“ befinden sollte, starten. Hier erscheint zunächst ein Fenster, welches nach
dem Speicherort für den Arbeitsordner fragt, hier kann einfach der Vorgabewert übernommen
werden. Damit wäre auch Eclipse installiert.
8.1.4Installation von EclipseME
Um das WTK mit Eclipse nutzen zu können, wird der Plugin EclipseME benötigt. Zu beziehen ist er
von [ECLIPSEME]. Die Installation ist wieder relativ einfach, da die ZIP-Datei nur entpackt werden
muss und die beiden Ordner „features“ und „plugins“ in das Verzeichnis „C:\Programme\eclipse“
kopiert werden müssen.
8.1.5EclipseME einrichten
Um EclipseME verwenden zu können, sind noch ein paar Einstellungen nötig. Dafür muss
zunächst Eclipse gestartet werden und der Menüpunkt „Window -> Preferences“ ausgewählt
werden. Daraufhin sollte sich folgendes Fenster öffnen.
Christian Burmeister
Anhang 32
Abbildung 8.12 (Programm: Eclipse)
Jetzt muss in den Menüzweig „J2ME -> Device Management“ gewechselt werden. In dem sich jetzt
öffnenden linken Fenster muss auf den Knopf „Import …“ geklickt werden. Daraufhin öffnet sich
folgendes Fenster.
Abbildung 8.13 (Programm: Eclipse)
Christian Burmeister
Anhang 33
In diesem Fenster muss unter dem Eingabefeld „Specify search directory“ das
Installationsverzeichnis des WTK ausgewählt werden, also „C:\WTK2.5.2_01“. Danach klickt man
auf „Refresh“, damit startet man die Suche nach den installierten JavaME-Emulatioren. Es sollten
dabei vier Emulatoren gefunden werden, diese sind auch in Abbildung 6.2 abgebildet. Danach
bestätigt man mit einem klick auf „Finish“. Jetzt sollte folgendes Fenster wieder sichtbar sein.
Abbildung 8.14 (Programm: Eclipse)
Die vier Emulatioren sind nun importiert. Das „DefaultColorPhone“ sollte als „Default“ ausgewählt
werden. Danach mit einem klick auf „Apply“ die Eingabe bestätigen.
Nun muss noch die Debug-Einstellungen angepasst werden. Dazu wechselt man im Menüzweig
auf „Java -> Debug“, in dem sich nun links öffnenden Fenster (Abbildung 8.4) müssen die
folgenden Optionen deaktiviert werden.
-
Suspend execution on uncaught exceptions
Suspend execution on compilation errors
Weiterhin muss unter dem Punkte „Debugger timeout (ms)“ der Wert auf 15000 erhöht werden. Um
die Eingabe abzuschließen klickt man zuerst auf „Apply“ und dann auf „OK“. Damit wäre nun auch
der EclipseME Plugin erfolgreich eingerichtet.
Christian Burmeister
Anhang 34
Abbildung 8.15 (Programm: Eclipse)
8.1.6Anlegen eines JavaME-Projekes in Eclipse
Nachdem nun alle erforderlichen Komponenten installiert und eingerichtet sind, kann man nun ein
Java-ME Projekt anlegen. Dazu wählt man in der Menüzeile von Eclipse „File -> New -> Project…“
aus. Daraufhin erscheint folgendes Fenster
Abbildung 8.16 (Programm: Eclipse)
Christian Burmeister
Anhang 35
Hier wählt man „J2ME -> J2ME Midlet Suite“ aus. Danach klickt man auf „Next“.
Abbildung 8.17 (Programm: Eclipse)
In dem sich jetzt öffnenden Fenster kann man dem Projekt einen Namen geben, in unserem Fall
„Hello World“. Danach wieder auf „Next“ klicken. In dem sich jetzt öffnenden Fenster einfach auf
„Finish“ klicken. Daraufhin gelangt man wieder ins Hauptfenster, auf der linken Seite ist jetzt das
eben erstellt Projekt zu sehen.
Abbildung 8.18 (Programm: Eclipse)
Christian Burmeister
Anhang 36
Innerhalb des „src“-Ordners müssen nun über den Menüpunkt „File -> New -> Class“ die beiden
Klassen „MyMIDlet“ und „MyCanvas“ erstellt werden. Der Inhalt der beiden Klassen kann dabei aus
Abbildung 3.1 bzw 3.2 übernommen werden. Danach muss man auf die Datei „HelloWorld.jad“
klicken, die sich innerhalb des Projektzweiges befindet.
Abbildung 8.19 (Programm: Eclipse)
Daraufhin öffnet sich der „Application Descriptior Editor“ der die bereits erwähnte JAD-Datei
erstellt. Hier muss man auf den Reiter „Midlets“ wechsel , der sich am unteren Rand befindet.
Danach muss man über den „Add“ Knopf einen neuen Eintrag für das JavaME Programm
erzeugen. Dabei sollte als Name „HelloWorld“ und als „Class“ die von MIDlet abgeleitete Klasse
gewählt werden. Danach speichert man die getätigten Änderungen.
Um das Programm nun innerhalb des Emulators auszuführen muss man noch einige Einstellungen
machen. Über dem Menüpunkt „Run -> Run Configurations … “ gelangt man in folgendes Fenster.
Abbildung 8.20 (Programm: Eclipse)
Christian Burmeister
Anhang 37
Hier klickt man auf den Punkt „Wirless Toolkit Emulator“ daraufhin erstellt sich ein neuer Eintrag
unterhalt von „Wirless Toolkit Emulator“ und auf der rechten Seite öffnet sich ein neues Fenster
(Abbildung 8.9). Hier vergibt man den Namen „HelloWorld“ und im Eingabefeld „Projekt“ wählt man
das Projekt „HelloWorld“ aus und zuletzt im Eingabefeld „Midlet“ die Klasse, die von MIDlet
abgeleitet ist. Danach bestätigt man mit einem klick auf „Apply“. Um das Programm nun
auszuführen drückt man auf „Run“. Damit sollt sich nun der JavaME-Emulator öffnen.
Abbildung 8.21 (Programm: WTK)
Über den Menüpunkt „Run -> Run History“ kann der Emulator in Zukunft einfacher ausgeführt
werden.
Christian Burmeister
Anhang 38
8.2Erstellen einer Karte mit Tile Studio
Wie bereits im Abschnitt 5.1.4 erwähnt, werden Level in 2D Spielen meist mittels Kacheln (engl.
Tiles) realisiert. Alle Kacheln besitzen dabei stets die gleichen Abmessungen z.B. 16 x16 oder 32 x
32 Pixel. Da es meist nicht bei ein oder zwei Kacheln bleibt, speichert man alle Kacheln zusammen
in eine einzigen Datei ab, dadurch ist die Handhabung um einiges einfach.
Da wir bereits in Abschnitt 5.1.4 eine einfache Karte erstellt haben, soll hier auf eine etwas
komplexere Karte eingegangen werden. Das Beispiel stammt dabei aus dem Programm
„Game_05_SuperMarioBros“.
Um eine Karte zu erstellen benötigt man zuerst die erwähnten Kacheln. Um diese zu erstellen
bietet sich das kostenlose Bildbearbeitungsprogramm „Paint.NET“ an, das unter der Adresse
[PAINTNET] heruntergeladen werden kann. Nachdem man die einzelnen Kacheln erstellt hat, legt
man eine neue PNG-Datei an. Die Höhe und Breite ist dabei von der Kachelgröße abhängig. Das
in Abbildung 5.1 gezeigt Bild hat zum Beispiel eine Höhe von 16 Pixeln und eine Breite von 544
Pixeln. Da die einzelnen Kacheln eine Größe von 16 x 16 Pixel besitzen, können so genau 34
Kacheln (544 / 16 = 34) in der Datei gespeichert werden. Die Zahlen unter den einzelne Kacheln,
sind nicht Bestandteil des Bildes, sie dienen hier lediglich als Hilfsmittel zur Orientierung.
Abbildung 8.22 (Programm: Game_05_SuperMarioBros)
Nachdem man die einzelnen Kacheln erstellt und in einer PNG-Datei gespeichert hat, kann man
mit der Erstellung der Karte beginnen. Zu diesem Zweck installiert man sich das Programm „Tile
Studio“ das ebenfalls kostenlos unter der Adresse [TILESTUDIO] heruntergeladen werden kann.
Die Installation des Programmes besteht lediglich darin, eine ZIP-Datei herunterzuladen und zu
entpacken. Danach startet man einfach die „ts.exe“-Datei. Jetzt sollte das Programm starten und
das folgende Fenster erscheinen.
Abbildung 8.23 (Programm: Tile Studio)
Christian Burmeister
Anhang 39
Zum importieren der PNG-Datei mit den einzeln Kacheln muss der Punkt „File->Import Tiles…“
ausgewählt werden. Jetzt erscheint ein Fenster in dem die PNG-Datei selektiert werden muss.
Wenn dies erfolgreich absolviert wurde, sollte folgendes Fenster erscheinen.
Abbildung 8.24 (Programm: Tile Studio)
Sehr wichtig beim Importieren ist, das die „Tile Width:“ und „Tile Height:“ auf die Größe einer
Kacheln eingestellt wird, in unserm Beispiel also 16 x 16 Pixel.
Um Transparenz nutzen zu können, muss mit der Maus auf das Feld „Transparent color(s):“
geklickt werden und dann auf die entsprechende Farbe im Bild, die später transparent erscheinen
soll, in unserm Fall ist dies Weiß. Nachdem die Einstellungen alle gesetzt wurden, klickt man auf
„Import“. Jetzt sollte das Hauptfenster in etwa wie folgt aussehen.
Abbildung 8.25 (Programm: Tile Studio)
Christian Burmeister
Anhang 40
Im untern linken Teil des Fensters sind nun die importierten Kacheln zu erkennen. Um mit diesen
jetzt eine Karte erstellen zu können, muss zuerst eine neue Karte angelegt werden. Dafür klickt
man auf „File->New Map…“, daraufhin öffnet sich folgendes Fenster.
Abbildung 8.26 (Programm: Tile Studio)
In diesem Fenster legt man die Höhe und Breite der Karte fest, diesmal aber nicht in Pixeln,
sondern in Anzahl der Kachel. Für unser Beispiel benötigen wir eine Größe von 212 x 18 Kacheln,
dies entspricht einer Auflösung von 3392 x 288 Pixeln.
Nach dem Anlegen der Karte sollte das Hauptfenster in etwa wie folgt aussehen.
Abbildung 8.27 (Programm: Tile Studio)
Der obere dunkel-graue Bereich stellt die Fläche da, in der die Karte erstellt wird. Um die einzelnen
Kacheln jetzt in der Karte zu platzieren gibt es 2 Modi. Der erste der beiden ist ein Modus, in dem
man direkt zeichnen kann, ausgewählt wird er über das Zeichenstift-Symbol (vgl. Abbildung 8.17)
an linken Fensterrand. Um nun eine Kachel auf der Karte zu platzieren, wählt man eine beliebige
Kachel im untern Fensterbereich aus und platziert sie dann, mit gedrückter linker Maustaste, nach
Belieben auf der Karte.
Mit dem zweiten Modus kann man Bereiche festlegen, auf den sich dann die nachfolgende
Operation bezieht. Um ihn auszuwählen, wählst man das gestrichelte Rechteck-Symbol auf der
linken Seite des Fensters (vgl. Abbildung 8.17).
Christian Burmeister
Anhang 41
Abbildung 8.28 (Programm: Tile Studio)
Jetzt kann man mit gedrückter linken Maustaste einen Bereich festlegen. Wenn man dies getan
hat, kann man auf eine beliebige Kachel klicken um damit den Bereich mit der gewählten Kachel
zu füllen. Es ist aber auch möglich auf den gewählten Bereich die Operationen „Ausschneiden“,
„Kopieren“, „Einfügen“ oder „Löschen“ auszuführen, dafür wählt man die entsprechenden Symbole
in der Menüleiste.
Wenn man sich mit Hilfe der beiden Modi eine Karte zusammengestellt hat, könnte sie in etwa wie
folgt aussehen.
Abbildung 8.29 (Programm: Tile Studio)
Wie man vielleicht in der Abbildung erkennen kann weichen die Kacheln 30 und 33 von den in
Abbildung 8.1 gezeigten Kacheln ab, Kachel 30 wird hier als X dargestellt und die Kachel 33 als
Fragezeichen. Dies dient aber nur als Hilfestellung, da diese Kacheln später im Spiel als
vollständig transparent dargestellt werden. Es ist prinzipiell auch egal wie die Kacheln im Tile
Studio aussehen, da nur die Kachelnummern (vgl. Abbildung 8.1 , 8.2, 8.4) in der Karte
gespeichert werden und nicht die Kacheln selbst.
Um die Karte nun zu exportieren gibt es mehre Vorlagen, da aber leider keine passende
vorhanden war, musste selbst eine Vorlage erstellt werden.
Um selbst eine Export-Vorlage zu erstellen muss man sich an die „Tile Studio Definiton“ (TSD)
halten die unter http://tilestudio.sourceforge.net/tutor.html erläutert wird. Dies ist eine Art
Beschreibungssprache mit der man festlegt, wie man die Karte exportieren kann.
Eine sehr einfachst Export-Vorlage ist in Quelltext 8.1 abgebildet.
Dabei wird in Zeile 1 festgelegt in welche Datei die Karte gespeichert werden soll, hier also
„level.dat“. In Zeile 4 wird die Anzahl der Kacheln in der Höhe und Breite gespeichert. Mit den
Zeilen 4, 6 und 7 wird jetzt jede einzelne Kachelnummer hintereinander, durch Komma getrennt,
gespeichert. Dabei wird mit der Kachel oben links begonnen und dann Zeilenweise bis zur unteren
rechten Kachel vorgegangen.
Christian Burmeister
Anhang 42
Quelltext 8.7 (Datei: format.tsd)
Der Inhalt der „level.dat“ würde dann in etwa wie folgt aussehen. Dabei würde die Ausgabe der
Kachelnummern etwas gekürzt, da 3816 einzelne Kachelnummern (212 * 18 = 3816)
abgespeichert werden müssen.
Quelltext 8.8 (Datei: level.dat)
Diese Export-Vorlage eignet sich gut, wenn man Level aus einer Datei einlesen will. Da bei dem
Programme „Game_03_WalkMarioTiles“ und „Game_03_SuperMarioBros“ aber jeweils nur ein
einziges Level vorhanden ist, eignet sich die nachfolgende Export-Vorlage besser, da sie die
Kachelnummern gleich in Form eines zweidimensionalen Arrays speichert.
Quelltext 8.9 (Datei: format2.tsd)
Wie man in Zeile 2 erkennen kann, wird die Karte jetzt in die Datei „format2.dat“ exportiert. In Zeile
4 und 5 werden noch Zusatzinformationen, wie Datum und Uhrzeit, abgespeichert. In Zeile 7 und 8
wird die Anzahl der Kacheln in der Höhe und Breite gespeichert. Zeile 11, 12 und 13 dienen dazu
die Karte in einem zweidimensionalen Array zu speichen.
Der Inhalt der „format2.dat“-Datei sieht dann in etwa wie im Quelltext 8.4 aus. Der Vorteil dieser
Export-Vorlage ist, dass der Inhalt der „format2.dat“-Datei einfach in das JavaME-Projekt kopiert
werden kann, ohne Änderungen zu mache.
Christian Burmeister
Anhang 43
Quelltext 8.10 (Datei: format2.dat)
Um die beiden Export-Vorlagen nun in das Tile Studio einzubinden müssen die beiden Dateien
einfach in das Programmverzeichnis kopiert werden. Danach muss man im Programm auf „Code->
Code Generation Settings…“ klicken, daraufhin sollte dann folgendes Fenster aufgehen.
Abbildung 8.30 (Programm: Tile Studio)
Christian Burmeister
Anhang 44
Wie man in der Abbildung erkennen kann, kann man die gewünschte Export-Vorlage nun
auswählen. Nach dem man die gewünschte Export-Vorlage ausgewählt hat, bestätigt man mit
einem klick auf „OK“. Um die Karte zu exportieren muss man dann nur noch im
Hauptprogrammfenster die Taste „F10“ auf der Tastatur drücken, damit wird die Karte in die
angegebene Datei exportiert wird. Wenn der Export-Vorgang erfolgreich war, erscheint folgendes
Fenster.
Abbildung 8.31 (Programm: Tile Studio)
Damit hätte man den Export der Karte abgeschlossen.
Christian Burmeister
Anhang 45
8.3Beispielprogramme (Anwenderdokumentation)
Im nachfolgenden sollen die im Rahmen dieser Ausarbeitung erstellten Programm kurz vorgestellt
werden.
8.3.1JavaME_01_HelloWorld
Speicherorte:
-
Quelltext: Auf der beiliegenden CD im Ordner „Beispiele/JavaME_01_HelloWorld/src“
-
Installationsdateien: Die JAD und JAR-Datei befinden sich auf der beiliegenden CD im
Ordner „Beispiele/JavaME_01_HelloWorld/.eclipseme.tmp/emulation“
Bestandteile:
-
MyMIDlet.java: eine von MIDlet abgeleitete Klasse, die zum Anzeigen der Leinwand dient.
-
MyCanvas.java: eine von Canvas abgeleitete Klasse, die den Text „Hello World“ auf die
Leinwand zeichnet.
Screenshot:
Abbildung 8.32
Beschreibung:
-
Dieses Programm dient lediglich dazu, zu zeigen, wie ein einfaches JavaME-Programm
erstellt wird. Auf dem Bildschirm wird der Text „Hello World!“ dazu ausgegeben.
Besprochen in:
-
Abschnitt 3.3, Abschnitt 8.1.6
Eingabemöglichkeiten:
-
„*“ Taste: beendet das Programm
Christian Burmeister
Anhang 46
8.3.2Game_01_GameLoop
Speicherorte:
-
Quelltext: Auf der beiliegenden CD im Ordner „Beispiele/Game_01_GameLoop/src“
-
Installationsdateien: Die JAD und JAR-Datei befinden sich auf der beiliegenden CD im
Ordner „Beispiele/Game_01_GameLoop/.eclipseme.tmp/emulation“
Erweiterung von:
-
JavaME_01_HelloWorld
Bestandteile:
-
MyMIDlet.java: eine von MIDlet abgeleitete Klasse, die zum Anzeigen der Leinwand dient.
-
GameCanvas.java: eine von Canvas abgeleitete Klasse, die innerhalb einer Schleife die
paint-Methode aufruft
Screenshot:
Abbildung 8.33
Beschreibung:
-
Dieses Programm dient lediglich dazu, zu zeigen, wie man innerhalb einer Canvas-Klasse
eine Spielschleife realisiert. Eine Spielschleife ist dabei nichts Anderes als eine Schleife,
die es ermöglicht die paint-Methode eine bestimmte Anzahl mal pro Sekunde aufzurufen.
Zu Demonstrationszwecken wird auf dem Bildschirm eine Zahl hochgezählt
Besprochen in:
-
Abschnitt 5.1.1
Eingabemöglichkeiten:
-
„*“ Taste: beendet das Programm
Christian Burmeister
Anhang 47
8.3.3Game_02_WalkMario
Speicherorte:
-
Quelltext: Auf der beiliegenden CD im Ordner „Beispiele/Game_02_WalkMario/src“
-
Installationsdateien: Die JAD und JAR-Datei befinden sich auf der beiliegenden CD im
Ordner „Beispiele/ Game_02_WalkMario/.eclipseme.tmp/emulation“
Erweiterung von:
-
Game_01_GameLoop
Bestandteile:
-
MyMIDlet.java: eine von MIDlet abgeleitete Klasse, die zum Anzeigen der Leinwand dient.
-
GameCanvas.java: eine von Canvas abgeleitete Klasse, die die Animierung und
Steuerung der Spielfigur übernimmt.
-
mario.png: Bild im dem die einzelnen Frames für die Spielfigur gespeichert sind
Screenshot:
Abbildung 8.34
Beschreibung:
-
Dieses Programm dient dazu, zu veranschaulichen, wie man eine Spielfigur animieren
kann und sie dann mittels Tastatur über den Bildschirm steuern kann. Zu steuern ist die
Spielfigur über die unten aufgeführten Eingabemöglichkeiten. Es ist allerdings noch
möglich über die Bildschirmgrenzen hinaus zu laufen.
Besprochen in:
-
Abschnitt 5.1.2, Abschnitt 5.1.2
Eingabemöglichkeiten:
-
„*“ Taste: beendet das Programm
-
„→“ oder „6“ Taste:
Spielfigur läuft nach rechts
-
„←“ oder „4“ Taste:
Spielfigur läuft nach links
-
„↑“ oder „2“ Taste:
Spielfigur läuft nach oben
-
„↓“ oder „8“ Taste:
Spielfigur läuft nach unten
Christian Burmeister
Anhang 48
8.3.4Game_03_WalkMarioTiles
Speicherorte:
-
Quelltext: Auf der beiliegenden CD im Ordner „Beispiele/Game_03_WalkMarioTiles/src“
-
Installationsdateien: Die JAD und JAR-Datei befinden sich auf der beiliegenden CD im
Ordner „Beispiele/Game_03_WalkMarioTiles/.eclipseme.tmp/emulation“
Erweiterung von:
-
Game_02_WalkMario
Bestandteile:
-
MyMIDlet.java: eine von MIDlet abgeleitete Klasse, die zum Anzeigen der Leinwand dient.
-
GameCanvas.java: eine von Canvas abgeleitete Klasse, die zum einen die Animierung
und Steuerung der Spielfigur übernimmt und zum andern das zeichnen und Scrollen der
Karte.
-
mario.png: Bild im dem die einzelnen Frames für die Spielfigur gespeichert sind
-
tiles.png: Bild im dem die einzelnen Kacheln für die Karte gespeichert sind
Screenshot:
Abbildung 8.35
Beschreibung:
-
Dieses Programm dient dazu, zu veranschaulichen, wie man ein einfaches Level erstellen,
zeichnen und scrollen kann. Dabei ist das Scrolling der Karte jeweils von der Position der
Spielfigur abhängig, dadurch ist gewährleistet, dass die Spielfigur immer innerhalb des
Bildschirms zu sehen ist , auch wenn die Karte um einiges größer ist wie der Bildschirm
selbst. Es ist allerdings noch möglich die Spielfigur, mittels der unten aufgeführten
Eingabemöglichkeiten, über Hindernisse hinweg zu bewegen (z.B. Mauer, Kartenrand). In
der oberen linken Ecke wird als Information der Punkt angegeben, der als
Koordinatenursprung definiert wurde.
Besprochen in:
-
Abschnitt 5.1.4 bis Abschnitt 5.1.6
Eingabemöglichkeiten:
-
„*“ Taste: beendet das Programm
-
„→“ oder „6“ Taste:
Spielfigur läuft nach rechts
Christian Burmeister
Anhang 49
-
„←“ oder „4“ Taste:
Spielfigur läuft nach links
-
„↑“ oder „2“ Taste:
Spielfigur läuft nach oben
-
„↓“ oder „8“ Taste:
Spielfigur läuft nach unten
8.3.5Game_04_WalkMarioTilesCollision
Speicherorte:
-
Quelltext: Auf der beiliegenden CD im Ordner
„Beispiele/Game_04_WalkMarioTilesCollision/src“
-
Installationsdateien: Die JAD und JAR-Datei befinden sich auf der beiliegenden CD im
Ordner „Beispiele/Game_04_WalkMarioTilesCollision/.eclipseme.tmp/emulation“
Erweiterung von:
-
Game_02_WalkMarioTiles
Bestandteile:
-
MyMIDlet.java: eine von MIDlet abgeleitete Klasse, die zum Anzeigen der Leinwand dient.
-
GameCanvas.java: eine von Canvas abgeleitete Klasse, die zumeinen die Animierung
und Steuerung der Spielfigur übernimmt und zum anderen das Zeichnen und Scrollen der
Karte. Zusätzlich wurde eine Kollisionserkennung eingeführt.
-
mario.png: Bild im dem die einzelnen Frames für die Spielfigur gespeichert sind
-
tiles.png: Bild im dem die einzelnen Kacheln für die Karte gespeichert sind
-
rubin.png: Bild für das Objekt (Rubin)
-
BoundingBox16x16.png: Bild für BoundingBox 16x16 Pixel
-
BoundingBox16x32.png: Bild für BoundingBox 16x32 Pixel
Screenshot:
Abbildung 8.36
Beschreibung:
-
Dieses Programm dient dazu, zu veranschaulichen, wie man eine Kollisionserkennung
implementieren kann. Zunächst wurde die Kollisionserkennung zwischen Spielfigur und
Karte implementiert, dadurch ist es der Spielfigur nicht mehr möglich durch Wände zu
gehen. Um die Art der Implementierung zu demonstrieren, kann man die Taste „0“
drücken. Dadurch werden um die Figur 6 Rechtecke gezeichnet, diese dienen als
Christian Burmeister
Anhang 50
„Kollisionserkenner“, sobald sich eines dieser Rechtecke auf einer Wand-Kachel befindet,
wird das Rechteck in blauer Farbe gezeichnet. Dies kann nun innerhalb des Programmes
dazu benutzt werden, dass sich die Spielfigur nicht weiter in diese Richtung bewegen
kann, im Demonstrationsmodus wurde dies aber bewusst deaktiviert.
Die zweite Art der Kollisionserkennung ist die Erkennung vom Kollisionen zwischen der
Spielfigur und einem Objekt (im Programm ein Rubin). Zu dieser Erkennungsart wurde
ebenfalls ein Demonstrationsmodus implementiert, der über die Taste „5“ aktiviert werden
kann. Hier werden ebenfalls Rechtecke um Spielfigur und Objekt gezeichnet, diesmal aber
nur je eines. Wenn sich zwei dieser Rechtecke (Bounding-Boxes) überschneiden liegt eine
Kollision vor und das Rechteck verfährt sich blau.
Besprochen in:
-
Abschnitt 5.1.7, Abschnitt 5.1.8
Eingabemöglichkeiten:
-
„*“ Taste: beendet das Programm
-
„→“ oder „6“ Taste:
Spielfigur läuft nach rechts
-
„←“ oder „4“ Taste:
Spielfigur läuft nach links
-
„↑“ oder „2“ Taste:
Spielfigur läuft nach oben
-
„↓“ oder „8“ Taste:
Spielfigur läuft nach unten
-
„0“ Taste: Demo-Kollisionserkennung für Kacheln und Spielfigur ein/ausschalten
-
„5“ Taste: Bounding-Box für Spielfigur und Rubin ein/ausschalten (Kollisonserkennung)
8.3.6Game_05_SuperMarioBros
Speicherorte:
-
Quelltext: Auf der beiliegenden CD im Ordner „Beispiele/ Game_05_SuperMarioBros/src“
-
Installationsdateien: Die JAD und JAR-Datei befinden sich auf der beiliegenden CD im
Ordner „Beispiele/ Game_05_SuperMarioBros/.eclipseme.tmp/emulation“
Bestandteile:
-
MyMIDlet.java: eine von MIDlet abgeleitete Klasse, die zum Anzeigen der Leinwand dient.
-
GameCanvas.java: Leinwand, auf der das Spiel gezeichnet wird
-
Game.java: Diese Klasse koordiniert den Ablauf des Spiels
-
Level.java: Diese Klasse realisiert die Karte des Spiels
-
ToolBox.java: Diese Klasse stellt unterschiedliche Methoden bereit
-
Sprite.java: Abstrakte Klasse die eine Spielfigur realisiert
-
Mario.java: von Spirte, abgeleitete Klasse, die die Spielfigur realisiert
-
Enemy.java: von Spirte, abgeleitete Klasse, die einen Gegner realisiert
-
Money.java: von Spirte, abgeleitete Klasse, die springendes Geld realisiert
-
Mushroom.java: von Spirte, abgeleitete Klasse, die Pilz realisiert
-
Enemies.png: Bild für den Pilz
-
Items.png: Bild das einige Gegenstände enhält
-
MapTiles.png: Bild enthält die Kacheln für die Karte
-
MarioSmall.png: Bild enthält die einzelnen Sprites für die Spielfigur (klein)
Christian Burmeister
-
Anhang 51
MarioTall.png: Bild enthält die einzelnen Sprites für die Spielfigur (gross)
Screenshot:
Abbildung 8.37
Beschreibung:
-
Ziel des Spieles ist es, bis ans Ende der Karte (Fahnenstange) zu gelangen. Auf dem Weg
dorthin begegnen der Spielfigur einige Gegner (unzerstörbar) und drei Wassergräben,
durch die die Spielfigur ein Leben verlieren kann. Die Spielfigur besitzt insgesamt drei
Leben, wenn diese aufgebraucht sind ist das Spiel verloren. Auf dem Weg zum Ziel
begegnen der Spielfigur aber nicht nur Gegner und Wassergärten, sondern auch
Fragezeichenboxen, öffnen kann man diese, indem man von unten dagegenhüpft. In einer
Fragezeichenbox kann entweder Geld (100 Punkte) oder ein Pilz versteckt sein. Wenn die
Spielfigur einen Pilz berührt, wird sie „Groß“ und ist dadurch in der Lage eine Mauer zu
zerstören, wenn sie von unten dagegenhüpft. Wenn die Spielfigur im großen Zustand
einen Gegner berührt wird sie wieder klein, aber verliert kein Leben dadurch. Als
besondere Herausforderung sind innerhalb des Spieles zwei versteckte
Fragezeichenboxen platziert, die 1000 Punkte erbringen.
-
Zu beachten ist, dass die Karte immer dann gescrollt wird, wenn sich die Spielfigur in etwa
der Mitte der Karte befindet. Damit wird der sichtbare Bildschirmausschnitt automatisch
weiter nach rechts bewegt. Danach ist es nicht mehr möglich in den nun verdeckten linken
Bereich der Karte zu gelange.
-
In der oberen linken Ecke werden zur Information der Punktestand und die Anzahl der
verbleibenden Leben angezeigt.
Besprochen in:
-
Abschnitt 5.2 und 8.2
Eingabemöglichkeiten:
-
„*“ Taste: beendet das Programm
-
„→“ oder „6“ Taste:
Spielfigur läuft nach rechts
-
„←“ oder „4“ Taste:
Spielfigur läuft nach links
-
„↑“ oder „2“ Taste:
Spielfigur springt nach oben
-
„1“ Taste:
Spielfigur springt nach links
-
„3“ Taste:
Spielfigur springt nach rechts
Christian Burmeister
Anhang 52
8.4Zeitaufwand
In diesem Abschnitt soll noch kurz auf die benötigte Zeit für die Erstellung dieser Ausarbeitung
eingegangen werden.
Tätigkeit
Benötigte Zeit
Informationsbeschaffung
30 Std.
Programmierung der Beispiele
50 Std.
Erstellung der Ausarbeitung
77 Std.
Erstellung der Präsentation
8 Std.
Gesamt
165 Std.
Christian Burmeister
Anhang 53
8.5Inhalt der CD-Rom
An dieser Stelle soll noch kurz der Inhalt der beilegenden CD erläutert werden. Auf der CD
befinden sich dabei die drei folgenden Ordner:
(fettgedrückte Worte stellen jeweils Ordner/Dateien da)
-
-
-
Ausarbeitung
o
In diesem Ordner befindet sich zum einen die Ausarbeitung und zum anderen die
Präsentation.
o
Formate:

PDF-Datei
-> Adobe Reader (AdbeRdr90_de_DE.exe)

DOC-Datei
-> Microsoft Word 2007 (WordViewer.exe)

PPT-Datei
-> Microsoft PowerPoint 2007 (PowerPointViewer.exe)
o
AusarbeitungChristianBurmeister.pdf
o
AusarbeitungChristianBurmeister.doc
o
PräsentationChristianBurmeister.pdf
o
PräsentationChristianBurmeister.ppt
o
Viewer

Enthält Betrachtungsprogramme zum anzeigen der Ausarbeitung.

PowerPointViewer.exe

WordViewer.exe

AdbeRdr90_de_DE.exe
Beispiele
o
In diesem Ordner liegen die im Rahmen dieser Ausarbeitung erstellten
Beispielprogramme. Dabei enthalten die Unterordner jeweils das komplette
Eclipse-Projektverzeichnis.
Im Ordner „Export-Vorlagen für TileStudio“ wurden die Export-Vorlagen
abgespeichert die in Abschnitt 8.2 erwähnt wurden
o
JavaME_01_HelloWorld
(Beschreibung in Abschnitt 8.3.1)
o
Game_01_GameLoop
(Beschreibung in Abschnitt 8.3.2)
o
Game_02_WalkMario
(Beschreibung in Abschnitt 8.3.3)
o
Game_03_WalkMarioTiles
(Beschreibung in Abschnitt 8.3.4)
o
Game_04_WalkMarioTilesCollision
(Beschreibung in Abschnitt 8.3.5)
o
Game_05_SuperMarioBros
(Beschreibung in Abschnitt 8.3.6)
o
Export-Vorlagen für TileStudio

format.tsd
(Beschreibung in Abschnitt 8.2)

format2.tsd
(Beschreibung in Abschnitt 8.2)
Internetquellen
Christian Burmeister
o
Anhang 54
Dieser Ordner enthält die unter Abschnitt 7.2 aufgeführten Internetquellen in
abgespeicherter Form. Die beiden Quellen [KARBACHER] und [NOKIASDK]
befinden sich dabei nicht im diesen Ordner, weil der Umfang dieser Seiten zu groß
waren.