10223-0 Spieleprogrammierung mit dem Arduino_03.indd 1 14.09.2016 08:37:45 10223-0 Spieleprogrammierung mit dem Arduino_03.indd 2 14.09.2016 08:37:53 INHALT 1 Einführung ............................................................................................................................... 4 1.1 Das Display-Shield .................................................................................................... 4 1.2 Das Joypad-Shield .................................................................................................... 5 1.3 Montage ....................................................................................................................... 6 1.4 Die Dokumentation ................................................................................................... 6 1.5 Die Community........................................................................................................... 6 1.6 Die Entwicklungsumgebung (IDE) ...........................................................................7 1.7 Hardwaretestt .............................................................................................................. 8 2 Ball – Einstieg in die Spieleprogrammierung..............................................................................10 3 Pong – mal anders ................................................................................................................14 4 Snail – Bitmaps einbinden ..................................................................................................18 5 Flappy Bird – Spielspaß mit Game Engine 1..................................................................... 22 6 Anhang ................................................................................................................................... 23 10223-0 Spieleprogrammierung mit dem Arduino_03.indd 3 14.09.2016 08:37:54 4 1 EINFÜHRUNG Vor Ihnen liegen die Bauteile für das Spielepaket. Neben der Schnellstartanleitung finden Sie vor sich das LCD-Display-Shield und das JoypadShield. Beide Platinen wurden speziell für den Arduino Uno entwickelt und passgenau abgestimmt. Sie ermöglichen Ihnen, die vorgestellten Beispiele auszuprobieren oder eigene Spiele zu entwickeln. Schauen Sie sich die beiden Shields einmal genauer an. Es gibt viel zu entdecken. 1.1 | Das Display-Shield Das Display-Shield Bei dem Display-Shield handelt es sich um eine Platine, die das LCD-Display 12864 LCD ST7565 zusammen mit zwei Hardwarebuttons Arduinokompatibel macht. Das Display hat eine Auflösung von 128 x 64 px und wird über SPI (Serial Peripheral Interface) angesteuert. Zu den technischen Daten: Display-Shield Arduino-Uno-kompatibles Shield Display DXDCG12864-4330 Displaycontroller ST7565 Auflösung 128 x 64 px Betriebsspannung 3,3 V Peripherie 10223-0 Spieleprogrammierung mit dem Arduino_03.indd 4 2 Onboard-Taster (an A4 und A5) 14.09.2016 08:37:54 5 Displaygröße 38 x 20 mm Sonstiges verkürzte Bauform – 14 freie I/O-Ports am Arduino Sie müssen sich allerdings nicht allzu sehr in die Details der Displayansteuerung einarbeiten, denn eine Library nimmt Ihnen den Großteil der Arbeit ab, sodass Sie sich voll auf die Programmierung von Spielen konzentrieren können. Wenn Sie Interesse an detaillierteren Informationen rund um die Ansteuerung des Displays und dessen Eigenschaften haben, empfehle ich Ihnen das Lernpaket „Franzis Maker Kit Grafikdisplays programmieren“. 1.2 | Das Joypad-Shield Das Joypad-Shield Das Joypad-Shield wurde speziell für dieses Projekt entwickelt, und es ermöglicht Ihnen, Spiele praktisch und intuitiv zu bedienen. Es befinden sich sechs Buttons auf dem Shield. Vier davon sind zu einem Steuerkreuz angeordnet, sodass Richtungen intuitiv eingegeben werden können. Zwei weitere Buttons werden individuell dem Spiel entsprechend mit Funktionen belegt. Insgesamt haben Sie also acht Buttons zur Verfügung, mit denen sich eine ganze Menge Spiele und Funktionen realisieren lassen. Neben den Buttons ist auch noch ein kleiner Piezo-Schallwandler als Lautsprecher auf der Platine verbaut. Sie können also nicht nur über das Display Informationen übermitteln, sondern auch akustisch Feedbacks geben. Zu den technischen Daten: Joypad-Shield Arduino-Uno-kompatibles Shield Eingabe 6 Kurzhubtaster (Steuerkreuz + 2 Aktionstasten) Soundausgabe integrierter Lautsprecher TMB12A05 10223-0 Spieleprogrammierung mit dem Arduino_03.indd 5 14.09.2016 08:37:54 6 1 | Einführung 1.3 | Montage Wie eingangs erwähnt, passen beide Shields optimal auf einen Arduino Uno. Dabei sollten Sie darauf achten, dass das Display-Shield mit den oberen Steckplätzen des Arduino Uno exakt abschließt. Das Joypad-Shield passt dann genau auf die unteren Steckleisten, wie in der Abbildung zu sehen ist. In dieser Konstellation haben Sie die beste Handhabung und können den Arduino auch zusammen mit dem Shield in die Hand nehmen und bedienen. 1.4 | Die Dokumentation Diese Schnellstartanleitung liefert Ihnen erste Informationen und einfache Beispiel für einen gelungenen Einstieg in die Spieleprogrammierung. Den Hauptteil der Informationen finden Sie in dem online verfügbaren Handbuch zur Spieleprogrammierung. Sie können das vollständige PDF herunterladen unter: http://www.buch.cd. Der dazugehörige Code lautet 10223-0. Zusätzlich zu dem Handbuch finden Sie dort auch die benötigte Library und die vorgestellten Beispiele. 1.5 | Die Community Als Erweiterung zu dem Projekt finden Sie zusätzliche Informationen auch auf dieser Webseite: http://tiny.systems/spielekonsole 10223-0 Spieleprogrammierung mit dem Arduino_03.indd 6 14.09.2016 08:37:55 1 | Einführung 7 Hier können Sie nicht nur auf zukünftige Updates zur Library oder den Programmen zugreifen, sondern auch auf einige weiterführende Projekte und Informationen der beiden Autoren. Darüber hinaus werden hier wichtige Onlinetools bereitgestellt, die Sie für die Bearbeitung Ihrer eigenen und der Beispielprojekte benötigen. 1.6 | Die Entwicklungsumgebung (IDE) Damit Sie überhaupt etwas entwickeln können, benötigen Sie zunächst eine möglichst einfach zu handhabende Entwicklungsumgebung (kurz: IDE) sowie einige Tools. Als IDE wird hier die bekannte und oft genutzte Arduino-IDE verwendet. Sie finden die aktuellste Version für Ihr Betriebssystem auf der Seite: www.Arduino.cc/Downloads Wir haben in unseren Projekten mit der Version 1.6.7 gearbeitet, aber die Anleitungen in diesem Buch sollten auch mit neueren Versionen funktionieren. Nach dem Download und der Installation der Umgebung wählen Sie noch das richtige Board und den richtigen Port unter Einstellungen aus, und schon können Sie Ihren Arduino bzw. Ihre Spielkonsole programmieren. Neben Arduino werden noch ein paar andere Tools genutzt, unter anderem eine Software zum Erstellen und Bearbeiten von Grafiken. In diesem Buch wurden sowohl das Windows-Programm Paint als auch der Open-Source-Editor Gimp verwendet. Mit einem Onlinetool auf tiny.systems können Sie schließlich diese Grafiken in ein kompatibles Format umwandeln – doch dazu später mehr. Zunächst ist es noch wichtig, dass Sie die Library inklusive der Beispiele von der Seite http://www.buch.cd. Der dazugehörige Code lautet 10223-0. herunterladen und installieren. Zum Installieren der Library müssen Sie einfach die Zip-Datei über den Library-Manager einbinden. Klicken Sie dazu auf Sketch -> Bibliothek einbinden -> .Zip-Bibliothek hinzufügen und wählen Sie dort die eben heruntergeladene Library-Zip-Datei aus. Schon sollte unten eine Erfolgsmeldung erscheinen. 10223-0 Spieleprogrammierung mit dem Arduino_03.indd 7 14.09.2016 08:37:55 8 1 | Einführung 1.7 | Hardwaretest Die IDE und die Beispielprogramme sind nun eingerichtet – Zeit, das erste Programm auf den Arduino zu laden. Öffnen Sie dazu über Datei -> Beispiele -> GameEngine -> Starter das erste Programm und klicken Sie auf den Upload-Button. Nach kurzer Zeit sehen Sie eine Erfolgsmeldung unten im Debug-Fenster. Das Display sollte nun in etwa so aussehen wie auf der Abbildung unten. Ist das nicht der Fall, spielen Sie mit den beiden Buttons direkt unterhalb des Displays herum. Auf diese Weise stellen Sie den Kontrast des Displays ein und beheben damit die wahrscheinlichste Ursache dafür, dass Sie noch nichts sehen können. Sollte dennoch nichts auf dem Display zu erkennen sein, überprüfen Sie die Position der beiden Shields auf dem Arduino. Stellen Sie nun den für Sie optimalen Kontrastwert ein und merken Sie sich diesen Wert. In den folgenden Projekten müssen Sie ihn in das Programm eintragen, damit das Display auch immer gut lesbare Anzeigen liefert. 10223-0 Spieleprogrammierung mit dem Arduino_03.indd 8 14.09.2016 08:37:55 1 | Einführung 9 In diesem Beispielprogramm können Sie außerdem die verschiedenen Funktionen der Shields testen. Drücken Sie beispielsweise einen Joypad-Button, wird dieser auf der Anzeige hervorgehoben. Auch den Sound können Sie testen. Sie sollten nun also die volle Funktionalität aller Komponenten überprüfen, bevor es richtig losgeht. 10223-0 Spieleprogrammierung mit dem Arduino_03.indd 9 14.09.2016 08:37:56 10 2 BALL – EINSTIEG IN DIE SPIELEPROGRAMMIERUNG Sie haben nun also alles eingerichtet und getestet – Zeit, sich der tatsächlichen Spieleentwicklung zu widmen. Öffnen Sie dazu das Beispielprogramm Ball über Datei -> Beispiele -> GameEngine -> Ball. In diesem ersten, einfachen Beispielprogramm geht es um das Zeichnen und Bewegen eines einfachen Objekts, eines Balls. Passen Sie zunächst den Kontrast in der Programmzeile 9 an. In dieser Zeile befindet sich innerhalb der Setup-Routine der Befehl engine.init(20). Die Zahl 20 in den Klammern können Sie durch Ihren individuellen Kontrastwert ersetzen. Dies wird auch in den folgenden Projekten nötig sein. Anschließend können Sie das Programm auf den Arduino laden. Nach erfolgreichem Upload sehen Sie ein einfaches Objekt in der Mitte des Displays. Doch wie wurde dies programmiertechnisch realisiert? 001 void drawBall() { 002 engine.drawPixel(ballX, ballY); 003 engine.drawPixel(ballX + 1, ballY); 004 engine.drawPixel(ballX - 1, ballY); 005 engine.drawPixel(ballX, ballY + 1); 006 engine.drawPixel(ballX, ballY - 1); 007 } Mit der Funktion, die den passenden Namen drawBall() trägt, wird der Ball auf das Display gebracht. Es sind nur ein paar einfache Zeilen notwendig, um die passenden Pixel auf dem Display zu aktivieren. Dies liegt vor allen daran, dass die meiste Arbeit im Hintergrund von der Game Engine übernommen wird. Die aktuelle Position des Balls ist über die Variablen ballX und ballY bekannt. Durch die drawPixel()-Funktionsaufrufe, die an der aktuellen Position des Balls und in seiner direkten Umgebung des Balls die Pixel aktivieren, wird der gesamte Ball gezeichnet. Sie können die Form des Balls auch anpassen, indem Sie variieren, welche Pixel 10223-0 Spieleprogrammierung mit dem Arduino_03.indd 10 14.09.2016 08:37:56 11 rund um die Ballposition ebenfalls aktiviert werden sollen. Beachten Sie, dass sich in der oberen linken Ecke das Pixel mit der Position 0,0 befindet. 001 void moveBall() { 002 ballX = ballX + 1; 003 ballX = ballX % 128; 004 ballY = ballY % 64; 005 } Mit der Funktion moveBall() wird schließlich Bewegung in den Ball gebracht. Jedes Mal, wenn diese Funktion aufgerufen wird, erhöht sich die x-Position des Balls um 1. Im Klartext bedeutet dies, dass sich der Ball auf dem Display nach rechts bewegt. Die beiden Zeilen darunter sorgen dafür, dass der Ball nicht die Dimensionen des Displays verlässt. Über die Modulo-Funktion ist gewährleistet, dass die x-Koordinate nie größer als 128 sein kann und die y-Koordinate nie größer als 64 – also genau entsprechend den 128 x 64 Pixeln, die Ihnen auf dem Display zur Verfügung stehen. 001 void controlBall() { 002 if(engine.joypad.isPressed(UP)){ 003 ballY = ballY - 1; 004 } 005 if(engine.joypad.isPressed(DOWN)){ 006 ballY = ballY + 1; 007 } 008 } 10223-0 Spieleprogrammierung mit dem Arduino_03.indd 11 14.09.2016 08:37:56 12 2 | Ball – Einstieg in die Spieleprogrammierung 2 Über die controlBall()-Funktion können Sie nun den Ball auch steuern. Die Tasten des Joypads werden dabei auf einfache Weise abgefragt. Die Funktion engine.joypad.isPressed(UP) gibt den Wert TRUE zurück, wenn die Taste gerade gedrückt ist. Dann wird die y-Position des Balls um ein Pixel verringert, was zur Folge hat, dass sich der Ball dem oberen Displayrand nähert. Analog dazu gibt es die Funktion engine.joypad.isPressed(DOWN). Sie können also über die Richtungstasten nach oben und unten die Höhe des Balls beeinflussen, während er sich auf dem Display nach rechts bewegt. Erreicht er das eine Ende des Displays, erscheint er wieder am anderen Ende. Damit diese drei Funktionen gut zusammenspielen, müssen sie an passender Stelle in der loop-Routine aufgerufen werden. 001 void loop(){ 002 if(engine.update()){ 003 controlBall(); 004 if(engine.isFrameCount(20)){ 005 moveBall(); 006 } 007 drawBall(); 008 } 009 } Dazu gibt es in Arduino die loop-Funktion, die dauerhaft durchläuft. Über die Funktion engine.update() wird sichergestellt, dass alle Engine-Funktionen, wie das Zeichnen des Balls und das Auswerten der Tasten, ausgeführt wurden, bevor der nächste Durchgang durchlaufen wird. Die Funktion moveBall() hat allerdings noch eine weitere Einschränkung – sie wird nur alle 20 Frames aufgerufen. Es wird also zunächst 20-mal der Inhalt des Displays aktualisiert, bevor sich die Position des Balls verändern darf. Der Grund dafür ist, dass sich der Ball sonst viel zu schnell bewegen würde. 10223-0 Spieleprogrammierung mit dem Arduino_03.indd 12 14.09.2016 08:37:56 2 | Ball – Einstieg in die Spieleprogrammierung 10223-0 Spieleprogrammierung mit dem Arduino_03.indd 13 13 14.09.2016 08:37:56 14 3 PONG – MAL ANDERS In dem nun folgenden Beispielprogramm geht es um das bekannte Spiel Pong, allerdings etwas anders, als Sie es vermutlich kennen. Anstatt einen der Schläger zu bedienen, beeinflussen Sie hier den Ball durch die Richtungstasten. Ganz nebenbei lernen Sie zudem neue Elemente der Spieleprogrammierung kennen. Pong wurde 1972 von Atari veröffentlicht und ist eines der bekanntesten Spiele überhaupt. Es ist angelehnt an das Spiel Ping Pong oder auch Tischtennis. In der klassischen Version spielen zwei Spieler gegeneinander. Auf den beiden gegenüberliegenden Seiten eines virtuellen Spielfelds gibt es je einen Schläger in Form eines Strichs. Ein Ball bewegt sich nun über den Bildschirm, und der Spieler muss versuchen, mit seinem Schläger den Ball abzuwehren und in Richtung des Gegners zurückzuspielen. Gelingt ihm das nicht, bekommt der Gegner einen Punkt. In dieser Version spielen Sie die Rolle des Balls, während die beiden Schläger vom Computer gesteuert werden. Sie müssen versuchen, den Ball möglichst lange im Spiel zu halten. Das Beispielprogramm öffnen Sie mit einem Klick auf: Datei -> Beispiele -> GameEngine -> GameEngine1 -> Pong Das Programm enthält viel bereits Bekanntes. Auch dieses Mal gibt es beispielsweise die Funktion drawBall(), die – abhängig von der aktuellen Position – einen Ball auf das Spielfeld malt. Analog dazu gibt es die Funktionen drawPlayer() und drawField(), die die beiden Schläger auf das Display zeichnen. Dabei gibt es bei drawField() noch eine neue Funk- 10223-0 Spieleprogrammierung mit dem Arduino_03.indd 14 14.09.2016 08:37:56 15 tion, nämlich drawValue(), die an der angegebenen Position das aktuelle Level bzw. den Punktestand zeichnet. Das aktuelle Level ändert sich immer dann, wenn der Ball erfolgreich abgewehrt wurde. Dies wird über die Funktion moveBall() überprüft. 001 void moveBall() { 002 if (ballX == 1 || ballX == 127) { 003 setup(); 004 } 005 if (ballY == 1 || ballY == 63) { 006 collisionY = collisionY * -1; 007 } 008 if (abs(ballX - player1X) <=2 && abs(ballY - player1Y) < 9) { 009 collisionX = collisionX * -1; 010 level++; 011 } 012 if (abs(ballX - player2X) <=2 && abs(ballY - player2Y) < 9) { 013 collisionX = collisionX * -1; 014 level++; 015 } 016 ballX = ballX + collisionX; 017 ballY = ballY + collisionY; 018 } Wie Sie sehen, gibt es verschiedene Abfragen über die Position des Balls. Befindet er sich an der x-Position bei 1 oder 127, bedeutet dies, dass er nicht erfolgreich abgewehrt wurde und am linken oder rechten Rand aus dem Spielfeld geflogen ist. In diesem Fall wird die Setup-Routine aufgerufen, und das Spiel kann von vorne beginnen. Befindet sich der Ball an der y-Position 1 oder 63, prallt der Ball an der oberen bzw. unteren Kante ab, indem die collisionY-Variable negiert und somit die Richtung der Ballbewegung umgekehrt wird. In den beiden Abfragen if (abs(ballX - player1X) <=2 && abs(ballY - player1Y) < 9) wird festgestellt, ob der Ball an einem Schläger reflektiert wird, indem überprüft wird, ob der Ball nah genug am Schläger ist und ob er auf den Schlägers trifft. Ist dies der Fall, wird die Bewegungsvariable in x-Richtung umgekehrt und das Level erhöht. 001 void movePlayer() { 002 if (player1Y < 7) { 10223-0 Spieleprogrammierung mit dem Arduino_03.indd 15 14.09.2016 08:37:57 16 3 | Pong – mal anders 3 003 004 005 006 007 008 009 010 011 012 013 014 015 016 } player1Y++; } if (player1Y > 55) { player1Y--; } player1Y = (player1Y -1 + random(3)); if (player2Y < 7) { player2Y++; } if (player2Y > 55) { player2Y--; } player2Y = (player2Y -1 + random(3)); Die Spielerbewegung (Schläger) hingegen wird zufällig festgelegt. Vorher wird nur überprüft, ob der Schläger zu nah an die obere oder untere Kante gerät. Eine Verschiebung nach oben oder unten wird durch Addieren einer Zufallszahl zwischen -1 und 1 erzeugt. Der Funktionsaufruf random(3) erzeugt Zufallszahlen zwischen 0 und 2. Dieser Wertebereich wird mit „-1“ auf den nötigen Wertebereich verschoben. 001 void controlBall() { 002 if(engine.joypad.isPressed(UP) && ballY > 2){ 003 ballY = ballY - 1; 004 } 005 if(engine.joypad.isPressed(DOWN) && ballY < 61){ 006 ballY = ballY + 1; 007 } 008 if(engine.joypad.isPressed(LEFT) && ballX > 13){ 009 ballX = ballX - 1; 010 } 011 if(engine.joypad.isPressed(RIGHT) && ballX < 115){ 012 ballX = ballX + 1; 013 } 014 } In der Funktion controllBall() werden nun die Buttons abgefragt, und die Position des Balls wird entsprechend der Eingabe verändert. Aber der „störrische Ball“ unterliegt natürlich den Gesetzen der Physik. Die natürliche Bewegung des Balls kann also nur beeinflusst werden. 10223-0 Spieleprogrammierung mit dem Arduino_03.indd 16 14.09.2016 08:37:57 3 | Pong – mal anders 17 001 void loop(){ 002 if(engine.update()){ 003 controlBall(); 004 if(engine.isFrameCount(10 - (level/10))) { 005 moveBall(); 006 } 007 if(engine.isFrameCount(25 - (level/4))) { 008 movePlayer(); 009 } 010 drawPlayer(); 011 drawBall(); 012 drawField(); 013 } 014 } Damit der zeitliche Ablauf aller Funktionen gut koordiniert ist, müssen sie in der loop-Routine nacheinander aufgerufen werden. Die Funktion isFrameCount() wird dazu verwendet, die Geschwindigkeit von Ereignissen zu steuern. Die Position des Balls wird alle 10 Bildaufbauten und die des Schlägers alle 25 Bildaufbauten verändert. Die Ballbewegung wird also häufiger aktualisiert. Zudem ist auch der Schwierigkeitsgrad hier eingebaut. Mit jedem Level wird das Updateintervall etwas kürzer und somit die Bewegung schneller. Das Spiel wird mit der Zeit daher immer schwieriger. 10223-0 Spieleprogrammierung mit dem Arduino_03.indd 17 14.09.2016 08:37:57 18 4 SNAIL – BITMAPS EINBINDEN In den vorangegangenen Beispielen wurden die Spielelemente vor allem durch Linien und Pixel dargestellt. In diesem Beispiel erfahren Sie nun, wie Sie auch komplexere Grafiken in ein Spiel integrieren. Dazu lernen Sie den Onlinekonverter auf Tiny.systems kennen. Auf der Internetseite http://tiny.systems/article/mosaic.html befindet sich ein Tool, mit dem Sie sehr einfach Zeichnungen erstellen können. Auf dieser Webseite finden Sie in der Mitte eine graue Fläche. Wenn Sie nun an eine beliebige Stelle in der Fläche klicken, aktivieren Sie damit ein Pixel. Klicken Sie auf dasselbe Pixel noch einmal, verschwindet es wieder. Klicken Sie und halten Sie die Maustaste gedrückt, während Sie den Mauszeiger über die Fläche bewegen. Wie Sie sehen, können Sie so auch ganze Zeichnungen erstellen. Die Zeichenfläche hat zunächst eine Größe von 16 x 16 px. Für größere Zeichnungen können Sie die Fläche durch einen Klick auf das rechte Symbol unter der Zeichenfläche vergrößern. Sollten Sie mit Ihrer Zeichnung unzufrieden sein, können Sie mit einem Klick auf das X die gesamte Fläche löschen. 10223-0 Spieleprogrammierung mit dem Arduino_03.indd 18 14.09.2016 08:37:57 19 Für den ersten Versuch können Sie eine Spielfigur der Größe 16 x 16 px erstellen. Wenn Sie fertig sind, klicken Sie auf den Haken unten links. Es erscheint ein recht langer Hex-Code, den Sie in das Snail-Programm kopieren müssen. Öffnen Sie dazu das Programm mit einem Klick auf Datei -> Beispiele -> GameEngine -> GameEngine1 -> Snail. In Zeile 10 des Programms finden Sie die Variable snail, die schon mit einer anderen Grafik gefüllt ist. Fügen Sie anstelle der vorhandenen Hex-Zahlen nun die neuen von der Mosaic-Seite generierten ein. Sie können das Programm anschließend hochladen und werden feststellen, dass die von Ihnen gezeichnete Grafik auf dem Display erscheint (vergessen Sie nicht, den Kontrastwert anzupassen). Mit den Richtungstasten können Sie die Grafik über den Bildschirm bewegen. Dafür ist eine neue Funktion der Library zuständig, die drawBitmap() heißt: engine.drawBitmap(snailX, snailY, 16, 16, snail); Die ersten beiden Parameter der Funktion bestimmen die Position der Grafik auf dem Display, während die folgenden beiden die Größe der Grafik angeben. An letzter Stelle in der Parameterliste steht die Variable selbst, in der Sie die Grafikdaten hinterlegt haben. So einfach kann das Darstellen von Grafiken auf dem Display sein. Es gibt aber noch eine zweite Möglichkeit, Arduino-kompatible Grafikdaten mit der Mosaic-Seite zu erstellen. Vielleicht ist Ihnen der Button, der mit Datei auswählen beschriftet ist, schon aufgefallen. Es ist nämlich möglich, Bitmap-Dateien auf die Seite hochzuladen und automatisch in Hex-Code formatieren zu lassen. Beachten Sie aber, dass sich nicht alle Bitmap-Dateien so einfach konvertieren lassen. Sie müssen darauf achten, dass es sich um ein monochromes (einfarbiges) Bitmap handelt. Am einfachsten ist es, sich selbst mit einem Malprogramm wie MS Paint ein solches Bitmap zu erstellen. Alternativ ist z. B. das Zeichenprogramm Gimp gut dafür geeignet. So Speichern Sie das Bild in Paint richtig. 10223-0 Spieleprogrammierung mit dem Arduino_03.indd 19 14.09.2016 08:37:57 20 4 | Snail – Bitmaps einbinden 4 Dem Beispielordner dieses Programms liegt bereits ein passend formatiertes Bild bei. Es trägt den Namen Snail.bmp. Diese Datei können Sie auf die Mosaic-Seite hochladen, und als Ausgabe bekommen Sie die Bildinformation in Form von Hex-Zahlen. Diese Hex-Zahlen kopieren Sie nun wieder in die snail-Variable, und schon erscheint eine Schnecke (engl. snail) auf dem Display, sobald Sie das Programm hochladen. 10223-0 Spieleprogrammierung mit dem Arduino_03.indd 20 14.09.2016 08:37:57 4 | Snail – Bitmaps einbinden 10223-0 Spieleprogrammierung mit dem Arduino_03.indd 21 21 14.09.2016 08:37:58 22 5 Flappy Birds auf dem Display FLAPPY BIRD – SPIELSPASS MIT GAME ENGINE 1 Dies ist das letzte Beispiel in dieser Schnellstartanleitung, und hier steht in erster Linie der Spaß im Vordergrund. Bei dem folgenden Programm handelt sich um ein kleines Geschicklichkeitsspiel, ursprünglich für Smartphones entwickelt, das sich vor allem am Anfang des Jahres 2014 großer Popularität erfreute. Der Entwickler Dong Nguyen entschied sich allerdings im Februar desselben Jahres, das Spiel aus den App-Stores zu nehmen. Dennoch gibt es aktuell etliche Klone, sodass das Spielprinzip bis heute populär ist. Das Programm öffnen Sie über Datei -> Beispiele -> GameEngine -> GameEngine1 -> FlappyBirdClone. Ziel des Spiels ist es, mit einem kleinen Vogel zwischen zwei Rohren hindurchzufliegen. Das Display ist bei diesem Spiel seitlich gedreht, sodass Sie die Länge des Displays ausnutzen können. Die Steuerung ist leicht zu merken, denn man benötigt nur den normalerweise nach links zeigenden Hardwarebutton, mit dem man dem Vogel einen kurzen Aufschwung geben kann. Dennoch ist eine Menge Geschicklichkeit gefragt, denn drückt man zu lange auf den Button, stößt der Vogel oben am Kanalrohr an, der Schwung reicht nicht aus, und der Vogel stürzt ab. Dazu erhöht sich der Schwierigkeitsgrad mit jedem Hindernis, da die Lücke zwischen den beiden Röhren immer kleiner wird. Wenn der Vogel scheitert, wird die Anzahl der überwundenen Hürden angezeigt. Mit erneutem Druck auf die Taste kann man von vorne starten. Das Programm ist ein nettes Geschicklichkeitsspiel für zwischendurch – und zugleich Anlass für eine Menge Frust. Es macht dennoch sehr viel Spaß, gegen Freunde im direkten Vergleich anzutreten. Damit Sie den Controller mit dem Display auch mobil nutzen können, gibt es die Möglichkeit, eine Batterie anzuschließen. Dabei sollten Sie allerdings immer darauf achten, die Stromversorgung nach dem Spielen wieder zu trennen, denn das Arduino-Board ist mit ca. 70 mA ein ziemlich energiehungriger Verbraucher. Der Quelltext des Projekts ist sehr umfangreich und wird an dieser Stelle nicht genauer erläutert. Es werden allerdings ausschließlich Funktionen aus der Ihnen nun bekannten Game Engine 1 verwendet. Sie sehen also, wie viel sich bereits mit diesen Mitteln realisieren lässt. Das eingangs erwähnte Onlinehandbuch taucht noch tiefer in die Spieleprogrammierung ein. Es stellt weitere Spiele vor, gibt Beispiele, und auch zusätzliche GameEngines werden vorgestellt; somit erweitern sich die Arten und Möglichkeiten der Spiele. Neben einem Super-Mario-Ableger und einem Point-nClick-Adventure lernen Sie auch die wichtigsten Spielelemente kennen und können zum Schluss Ihre ganz eigenen Spiele programmieren. 10223-0 Spieleprogrammierung mit dem Arduino_03.indd 22 14.09.2016 08:37:58 23 ANHANG Eine kurze Zusammenfassung der wichtigsten Befehle der Game Engine 1: init byte contrast (0–63) Initialisierung des Displays mit zu übergebendem Kontrastwert update - Update der Game Engine (Displayinhalte übertragen, Eingaben abfragen usw.) drawPixel byte x, byte y (x-,yPosition) zeichnet einen Punkt an der gegebenen Position drawLine byte x1, byte y1 (Punkt 1) byte x2, byte y2 (Punkt 2) zeichnet eine Linie zwischen den beiden Punkten (x1, y1) und (x2, y2) drawValue byte x, byte y (x-,yPosition), byte value zeichnet einen Punktestand an einer beliebigen Position (x, y) drawBitmap byte x, byte y, byte zeichnet eine Bitmap an Position x, y width, byte height, mit der Länge (width) und der Breite const byte bitmap[] (height) isFrameCount byte frame gibt TRUE zurück, wenn die in Klammern angegebene Anzahl an Bildern (Frames) gezeichnet wurde; Verwendung: zeitgesteuerte Abläufe joypad.isPressed byte button gibt TRUE zurück, wenn der Button gedrückt wird (RIGHT, LEFT, DOWN, UP, A, B) beep - erzeugt einen Beep (Ton) 10223-0 Spieleprogrammierung mit dem Arduino_03.indd 23 6 14.09.2016 08:37:58 Impressum © 2016 Franzis Verlag GmbH, 85540 Haar bei München www.elo-web.de Autor: Fabian Kainka und Thomas Baum Produktmanager: Dr. Markus Stäuble ISBN 978-3-645-10223-0 Produziert im Auftrag der Firma Conrad Electronic SE, Klaus-Conrad-Str. 1, 92240 Hirschau Alle Rechte vorbehalten, auch die der fotomechanischen Wiedergabe und der Speicherung in elektronischen Medien. Das Erstellen und Verbreiten von Kopien auf Papier, auf Datenträger oder im Internet, insbesondere als PDF, ist nur mit ausdrücklicher Genehmigung des Verlags gestattet und wird widrigenfalls strafrechtlich verfolgt. Die meisten Produktbezeichnungen von Hard- und Software sowie Firmennamen und Firmenlogos, die in diesem Werk genannt werden, sind in der Regel gleichzeitig auch eingetragene Warenzeichen und sollten als solche betrachtet werden. Der Verlag folgt bei den Produktbezeichnungen im Wesentlichen den Schreibweisen der Hersteller. Alle in diesem Buch vorgestellten Schaltungen und Programme wurden mit der größtmöglichen Sorgfalt entwickelt, geprüft und getestet. Trotzdem können Fehler im Buch und in der Software nicht vollständig ausgeschlossen werden. Verlag und Autor haften in Fällen des Vorsatzes oder der groben Fahrlässigkeit nach den gesetzlichen Bestimmungen. Im Übrigen haften Verlag und Autor nur nach dem Produkthaftungsgesetz wegen der Verletzung des Lebens, des Körpers oder der Gesundheit oder wegen der schuldhaften Verletzung wesentlicher Vertragspflichten. Der Schadensersatzanspruch für die Verletzung wesentlicher Vertragspflichten ist auf den vertragstypischen, vorhersehbaren Schaden begrenzt, soweit nicht ein Fall der zwingenden Haftung nach dem Produkthaftungsgesetz gegeben ist. Elektrische und elektronische Geräte dürfen nicht über den Hausmüll entsorgt werden! Entsorgen Sie das Produkt am Ende seiner Lebensdauer gemäß den geltenden gesetzlichen Vorschriften. Zur Rückgabe sind Sammelstellen eingerichtet worden, an denen Sie Elektrogeräte kostenlos abgeben können. Ihre Kommune informiert Sie, wo sich solche Sammelstellen befinden. Dieses Produkt ist konform zu den einschlägigen CE-Richtlinien, soweit Sie es gemäß der beiliegenden Anleitung verwenden. Die Beschreibung gehört zum Produkt und muss mitgegeben werden, wenn Sie es weitergeben. 10223-0 Spieleprogrammierung mit dem Arduino_03.indd 24 14.09.2016 08:37:58