Jan 162013
 

Jetzt werden wir einige Konzepte anwenden, welche in den vorhergehenden Lektionen behandelt wurden, um unser Spiel mit einem scrollbaren Hintergrund auszustatten. Des Weiteren werden wir die Bewegung unserer Spielfigur noch ein wenig bearbeiten. Ziel ist es, das Ducken zu erlernen und das Hüpfen vorzubereiten.

Stunde #2-13: Bewegter Hintergrund Teil 1

Hierzu erstellen wir eine neue Klasse und nennen diese Background.

1

Innerhalb dieser neuen Klasse werden wir:

1. Variablen erstellen, die uns erlauben, den Hintergrund zu manipulieren.

2. Wir definieren einen Konstrukteur (constructor), welcher uns erlaubt, ein Objekt mit der Background Klasse zu erstellen. Erinnert euch daran, dass Klassen ein Entwurf bzw. Plan für Objekte sind. Wir verweisen auf ein Objekt, welches mithilfe einer Klasse erstellt wird und mit deren Eigenschaften ausgestattet ist.

3. Wir erstellen eine update()-Methode, die uns den Hintergrund bewegen lässt.

4. Es werden Getters und Setters hinzugefügt, welche mit den Variablen in Punkt 1 zu tun haben. Erinnert euch an Lektion 4 – Getters und Setters sind Hilfsmethoden, die es uns ermöglichen, private (klasseninterne) Variablen abzurufen und zu verändern.

I. Erstellen von Variablen

Wir werden bgX, bgY und speedX erstellen. bgX und bgY geben uns die Koordinaten von der linken oberen Ecke des Hintergrunds an. Um diese nun hinzuzufügen, müssen wir nur Folgendes in unsere Klasse einfügen:

II . Definition des Konstrukteurs

Als wir unseren Roboter erschufen, brachten wir alle Dinge, die damit zu tun haben, in der Robot Klasse unter. Genau dies tun wir nun auch mit unserem Hintergrund.

Um den Hintergrund zu erzeugen, benötigen wir einen Konstrukteur. Diesen erstellen wir gleich nach der Variablendeklaration. Jetzt überlegen wir uns, welche Variablen wir brauchen könnten, um ein Hintergrundobjekt zu erzeugen. Falls wir neue Hintergrundobjekte erzeugen, machen wir das wahrscheinlich an einer konkreten Position, welche wir bestimmen. Daher fügen wir zwei Parameter hinzu – einen für die X- und einen für die Y-Koordinate:

Die drei von uns erzeugten Variablen haben zu Beginn alle den Wert 0. Der Hintergrund soll am Anfang oben links in der Ecke beginnen und sich nicht bewegen, da sich der Roboter erst bewegen muss, um die Hintergrundbewegung zu rechtfertigen. Die StartingClass wird dann neue Werte liefern.

III. update()-Methode

Mit jedem Durchlauf unserer Spielschleife, alle 17 Millisekunden, müssen wir etwas mit unserem Hintergrund anstellen. In unserem Spiel soll der Hintergrund sich erst dann bewegen, wenn unser Roboter sich nach rechts bewegt. Also müssen wir eine update()-Methode erstellen, welche die benötigten Änderungen zu unserem Hintergrund übernimmt.

In dieser Lektion werden wir einen unendlichen Hintergrund erstellen, welcher sich aus zwei langen Bildern ergibt und immer wieder in einer Schleife ausgeführt wird: 1, 2, 1, 2, 1, 2, 1, …

Was benötigt nun unsere update()-Methode:

1. Sie sollte die Position immer aktuell halten.

2. Wenn unser Hintergrundbild nicht mehr angezeigt werden kann, sollte die Methode aufhören zu arbeiten (um Speicher zu sparen) oder das Hintergrundbild erneut anzeigen.

Momentan werden wir ein Hintergrundbild mit den Abmessungen von 2160 x 480 verwenden.

Kurze Anmerkung:

Unerfahrene Programmierer fragen häufig, ob der Name einer Methode durch Java vordefiniert ist oder man diesen willkürlich wählen kann? In diesem Fall erstellen wir eine neue Methode mit dem Namen update, dies ist unsere freie Wahl. Aber wenn wir uns immer wieder auf die StartingClass beziehen, können sich die Namen nicht ändern. Das ergibt sich daraus, dass wir die Methoden von Superklassen und Interfaces ausleihen. Wenn @Override vor einer Methode steht, bedeutet dies, benutze die neue Definition, nicht die aus der Superklasse. Beim Importieren von Methoden nutzt die Hilfe von Eclipse, dort lassen sich viele nützliche Informationen finden.

Kurze Anmerkung 2:

Denkt nach über das, was ihr programmiert. Nehmt nicht einfach alles so hin, was ich schreibe. Ihr müsst die Zusammenhänge verstehen, wie alles mit einander arbeitet. Je mehr ihr dies versteht, desto eher könnt ihr eure eigenen Programme entwickeln. Also falls ihr Fragen habt, stellt diese auch, ich versuche jedem zu helfen und freue mich auch darüber.

Nachdem jeder sich ein Bild von der update()-Methode gemacht hat, lasst uns mal einen Blick darauf werfen, was wir hier gemacht haben.

Mit bgX += speedX ändern wir die Geschwindigkeit unserer Bewegung, was Sinn macht. Je weiter sich nun der Roboter nach rechts bewegt, desto weiter rutscht die obere linke Ecke unseres Hintergrundbildes nach links, dass bedeutet, sie wandert aus dem Bildschirm raus und wird negativ.

Wenn nun die X-Koordinate bei -2160 angelangt ist oder darunter (damit wäre das Bild auf der rechten Seite nicht mehr komplett im Bildschirm), schieben wir diese um 4320 Pixel nach rechts. Wenn wir den Code dann durchlaufen lassen, macht alles einen Sinn.

Warum schreiben wir nun aber bgX <= -2160 nicht bgX == -2160?

Dies ist sehr wichtig, dass wir das wissen. Was wäre, wenn die Geschwindigkeit unseres Hintergrundes kein Faktor von 2160 ist? Welcher ist der kleinste Wert, der unsere X-Position ändert? Kann sich bgX von 2161 auf 2159 ändern? Ist unser Code dann noch richtig?

IV. Getters und Setters

Das ist einfach, da Eclipse uns hier die komplette Arbeit abnimmt. Dazu machen wir einen Rechtsklick irgendwo in den Weißraum  neben dem Code unserer Background Klasse und wählen Source > Generate Getters and Setters…
Danach Select All und unter Sort by: First getters, then setters.

2

Nun haben wir folgenden Stand:

Stunde #2-14: Bewegter Hintergrund Teil 2

Nun haben wir unsere Background Klasse fertig erstellt und werden nun unsere zwei Hintergrundbilder hinzufügen. In dieser Stunde werden wir mit der StartingClass arbeiten, also öffnen wir diese.

Regel:

Immer wenn wir ein neues Objekt zu unserem Spiel hinzufügen, müssen wir Folgendes machen:

0. Wir erstellen eine neue Klasse dafür, welche wir als Vorlage für weitere Objekte nutzen können (wir taten das für die Background Klasse).

1. In der StartingClass müssen wir Objekte erstellen, welche auf unsere neue Klasse zugreifen. Als Erstes müssen wir sie als Variablen am Anfang der Klasse erstellen und als Zweites müssen wir in der start()-Methode darauf zurückgreifen.

2. In der run()-Methode müssen wir die update()-Methode aufrufen.

3. Wir müssen unser neues Objekt in der paint()-Methode darstellen lassen.

Da wir Punkt 0 schon im ersten Teil erstellt haben, werden wir uns nun Punkt 1 widmen.

I. Variablen erstellen und diese initialisieren

Dazu schreiben wir einfach unter die von uns bereits erstellten Variablen:

Wir machen diese erstmal statisch, dass wir Getters und Setters benutzen können.

Um diese Variablen nun zu Initialisieren, nehmen wir folgende Änderungen an der start()-Methode vor:

Dies erstelle 2 neue separate  Hintergrundobjekte, welche wir als bg1 und bg2 bezeichnen. Erinnert euch daran, wir benötigen 2 integere Werte für unseren Hintergrundkonstrukteur, X und Y Koordinaten.

II. update()-Methode

Wir wollen nun, dass unsere 2 Hintergründe bei jedem Durchlauf der Schleife aktualisiert werden. Dazu ändern wir die run()-Methode wir folgt:

 III. Den Hintergrund zeichnen

Nun wollen wir auch, dass unser Hintergrund angezeigt wird. Dazu ladet das Bild herunter und kopiert es in den data Ordner, wie in der vorherigen Lektion.

background

Als erstes müssen wir unsere Variablen bearbeiten:

In der init()-Methode, wo wir unsere Bildeinstellungen vorgenommen haben, müssen wir auch unseren Hintergrund definieren:

Nun wollen wir unseren Hintergrund auch zeichnen lassen, dazu ändern wir die paint()-Methode. Bilder werden immer in der Reihenfolge angezeigt, wie sie im Code erscheinen. Wenn ich also unseren Roboter über dem Hintergrund darstellen möchte, muss der Hintergrund als Erstes erscheinen.

Damit haben wir unseren Hintergrund in das Spiel eingefügt, noch passiert aber nichts damit. Daher müssen wir noch einige Änderungen an der StartingClass und der Robot Klasse vornehmen.

Stunde #2-15: Spielfigur bewegen

Momentan hält der Roboter an, sobald ich die rechts oder links Taste los lasse, auch wenn die andere betätigt ist. Dies macht die Bewegung sehr unkomfortabel und dadurch haben wir kein schönes Spiel.

Dieses Problem kann man aber einfach lösen. Wir werden nun einfach überprüfen, ob eine weitere Taste betätigt wurde, bevor unser Roboter anhält. Des Weiteren lassen wir unseren Roboter sich ducken, wobei er sich nicht bewegen kann.

Änderungen an der Robot Klasse

Wir werden nun einige Änderungen an der Robot Klasse vornehmen, daher werde ich hier den kompletten Code einfügen. Beim Durchgehen des Codes Zeile für Zeile, sollte sich eigentlich alles selbst erklären, falls jemand Fragen hat, bitte stellt diese auch. Ich habe die Getters und Setters auch an das Ende meines Codes verschoben, der Übersichtlichkeit Halber.

 Änderungen:

1. Wir haben bisher noch nicht über Konstanten gesprochen, also werden wir das mal nachholen. Konstanten sind eine Art von Variablen. Wie der Name schon sagt, ist der Wert immer gleich, also konstant.

Um zu sagen, was konstant ist, benutzen wir das Wort final (deshalb kann dieses Wort auch niemals für eine Variable genutzt werden), und da es unter Programmierern Brauch ist (kein Gesetz), schreiben wir Konstanten komplett in Großbuchstaben.

final int JUMPSPEED = -15;
final int MOVESPEED = 5;
final int GROUND = 382;

Diese drei Zeilen Code zeigen unsere Konstanten. Bisher haben wir bei jeder Bewegung immer wieder die Zahlen -15, 5 und 382 geschrieben, mit diesen Konstanten können wir die Zahlen vergessen und müssen nur die Konstanten schreiben.

2. System.out.println() hat uns angezeigt, dass der Hintergrund sich eigentlich bewegen sollte. Diese Platzhalter wurden nun entfernt und mit dem Code ersetzt, welcher wirklich den Hintergrund bewegt.

3. Die boolean Variablen sind dazu da, unsere Bewegung zu verfolgen. Jedesmal wenn wir uns nach links und nach rechts bewegen, speichern es diese Variablen.

Zum Beispiel: Wenn wir uns nach links bewegen und die linke Taste betätigen (movingLeft == true) und wir uns gleichzeitig nach rechts bewegen und die rechte Taste betätigen (movingRight == true) und nun eine der beiden Tasten losließen, würde unser Roboter anhalten. Jetzt, mit den Änderungen, wird erst überprüft, ob eine der Richtungen noch betätigt wird, damit stehen nun zwei Möglichkeiten zur Auswahl: 1. Falls die andere Taste nicht betätigt wird, stoppe den Roboter. 2. Falls die andere Taste betätigt wird, bewege dich in diese Richtung.

4. Wenn wir in unserer Robot Klasse Änderungen vornehmen, werden wir in der StartingClass Fehler erhalten. Diese werden wir noch beheben.

Änderungen an der StartingClass

Diese Änderungen werden nur in den keyPressed() und keyReleased() Methoden vorgenommen. Dies ist so, weil die Bewegung unserer Spielfigur nur hier behandelt wird. Ich habe hier den Code komplett rein kopiert.

Die Fehler, welche nun auftreten, werden wir nachfolgend alle abarbeiten.

Stunde #2-16: Bewegungen

Nun werden wir unseren Roboter springen und sich ducken lassen, dazu benötigen wir die beiden neuen Bilder. Ladet die Bilder herunter und kopiert diese dann in den data Ordner unseres Spiels.

down jumped

 

1. Nun müssen wir diese beiden Bilder als Variable erzeugen:

Wir haben nun characterDown zum Ducken und characterJumped zum Hüpfen als Variable eingefügt, aber was ist currentSprite? Momentan zeichnen wir Robot robot mit dem Bild character. Nun wollen wir aber currentSprite zeichnen lassen, dies kann dynamisch zwischen unseren drei Bildern wählen, je nachdem, was unser Roboter macht.

2. Nun müssen wir noch unter den Bildeinstellungen unsere neuen Bilder einfügen und auch currentSprite.

3. Anpassen der run()-Methode

Dieser Code wird immer wieder nach dem Status unseres Roboters schauen und currentSprite danach ausrichten, laufen, hüpfen oder ducken.

4. Nun müssen wir noch ändern, dass für unseren Roboter currentSprite angezeigt wird und nicht character.

5. Als Letztes gehen wir ans Ende der Klasse und fügen neue Getters und Setters hinzu. Diesmal aber nur Getters für bg1 und bg2.

Damit sind wir auch schon am Ende der Lektion angekommen. Unser Hintergrund bewegt sich und unser Roboter kann sich mittlerweile schon ducken. Das Springen werden wir zu einem späterem Zeitpunkt hinzufügen. In der nächsten Lektion werden wir ein paar Gegner hinzufügen.

Source Code

Für diejenigen unter euch, die hier einsteigen möchten, ohne den ganzen Code abtippen zu müssen, habe ich das Projekt exportiert. Mit der Importfunktion könnt ihr das Projekt bequem bei euch einfügen. Unter der Kategorie Eclipse und Java > Import und Export habe ich erklärt, was dafür zu tun ist.

Lektion 5

Falls ihr Fragen habt, immer raus damit, ich helfe euch sehr gerne. Hinterlasst bitte einfach einen Kommentar.

Teilt diese Seite mit euren Freunden und besucht uns mal auf Facebook und auf Google+, das würde dieser Seite wirklich weiterhelfen, danke sehr. Auch ein Klick auf die Werbung hilft dabei, diese Seite am Laufen zu halten.

 

Quelle: Original Anleitung auf englisch von Kilobolt Studios

Lektion 4 – Spielfigur einbinden Teil 2 Lektion 6 – Gegner