Kapitel 2 Lektion 8 – Animationen
Heute werden wir uns mit Animationen beschäftigen, was viel neuen Code bedeutet. Theoretisch sind Animationen recht einfach. Alles was ihr dazu benötigt, ist eine Folge von Bildern, welche wir künftig als Frames bezeichnen, und die Dauer bzw. Zeitspanne, wie lange jedes dieser Bilder angezeigt wird. Als nächstes müssen wir nur noch den aktuellen Frame der Sequenz für die gewünschte Zeitspanne anzeigen.
In Wirklichkeit bedeutet dies leider etwas mehr Arbeit, also lasst uns damit beginnen.
Stunde #2-24: Erstellen der Animation-Klasse
Wie immer werden wir einen Entwurf bzw. Plan für alle Animationen erstellen, die wir entwickeln werden. Diese Klasse wird aber etwas anders als die, die wir bisher kennen (ihr werdet eine verschachtelte Klasse kennen lernen).
Tipp: Die Animation-Klasse kann immer und immer wieder verwendet werden (mit bestimmten Modifikationen). Darum nennen wir dies auch Framework (Rahmen oder Gerüst), weil es sich im Wesentlichen um wiederverwendbaren Code handelt, der uns auch bei künftigen Projekten nützlich sein kann.
I. Erstellen eines Pakets und der Animation-Klasse
Als erstes erstellen wir ein neues Paket, dies hilft uns dabei, ein wenig Ordnung zu halten.
1. Rechtsklick auf src, danach New > Package auswählen.
2. Wir nennen es basteldroid.framework
3. Rechtsklickt auf basteldroid.framework und erstellt eine neue Klasse namens Animation.
Was benötigen wir alles in dieser Klasse?
1. Wir benötigen Variablen für Folgendes: Frames, aktueller Frame, Animationszeit und komplette Zeit.
2. Wir müssen einen Konstrukteur erstellen.
3. Eine Methode die
- einen Frame zur neuen Animation hinzufügt
- den aktuellen Frame mit dem richtigen Bild aktualisiert
- den richtigen Frame ausgibt, so dass wir diesen in der StartingClass ausgeben können
- den richtigen Frame Index ausgibt
4. Wir erstellen eine Klasse in der Klasse namens AnimFrame, welches dazu benutzt wird, Objekte zu erzeugen, welche das aktuelle Bild und dessen Anzeigedauer beinhalten.
Wir werden jedes Einzelne genauer beleuchten, wenn wir dies implementieren.
II. Definieren der Animationsklasse
Momentan solltet ihr nur eine leere Klasse haben:
[crayon-628a8f2487ebe843508370/]
1. Variablen
Nun werden wir die folgenden Variablen hinzufügen und die entsprechenden Pakete importieren:
[crayon-628a8f2487ecc751690960/]
- ArrayList frames werden die AnimFrame, welche wir später erstellen, mit folgenden Werten beinhalten: Bild und Anzeigedauer
- currentFrame beinhaltet den Index unserer ArrayList, den Platz in der Liste, welche mit 0 beginnt
- animTime controlliert, wie lange das aktuelle Bild angezeigt wurde und sobald eine gewisse Zeit erreicht ist, wird ein neues Bild angezeigt
- totalDuration bezieht sich auf die Zeit, die jedes Bild angezeigt wird
Beispiel:
Stellen wir uns vor, wir haben eine ArrayList namens frames und diese beinhaltet das Folgende:
AnimFrame(Bild1, 100);
AnimFrame(Bild2, 200);
AnimFrame(Bild3, 400);
AnimFrame(Bild2, 200);
AnimFrame(Bild1, 100);
- Diese Gruppe von AnimFrame Objekten bezeichnen wir als frame ArrayList.
- currentFrame: nehmen wir an, Bild3 wird gerade angezeigt, dies bedeutet, dass wir bei Index 2 sind, die Liste beginnt bei 0
- animTime: wird nun überprüfen, wie lange das Bild schon angezeigt wird
- totalDuration: in diesem Fall ist die Anzeigedauer 400
2. Der Konstrukteur
Dieser wird sehr einfach, er ruft einfach die vier erzeugten Variablen auf.
[crayon-628a8f2487ed2886685324/]
Von diesem Code ist uns bisher nur synchronized neu, dies bedeutet Synchronisieren. Um es etwas verständlicher zu machen, müssen wir über Threads reden. Falls ihr nicht wisst, was das ist, schaut in Kapitel 1 Lektion 11 nach.
Wenn wir mehrere Threads haben, laufen diese technisch gesehen nicht immer simultan. Sie springen nur zwischen einander hin und her, wie bei einem Schalter.
Wenn wir nun synchronized benutzen, wird animTime und currentFrame immer zusammen aufgerufen. Falls wir dies nicht tun, könnte erst das eine, dann ein komplett anderer Thread und dann das andere aufgerufen werden. Das klingt jetzt vielleicht etwas verwirrend, aber wahrscheinlich erkennt ihr die Bedeutung dessen erst später. Zurzeit sollten wir es einfach so betrachten, dass es uns künftig das Programmieren erleichtert..
3. Methoden
Wir werden nun vier Methoden zu unserem Code hinzufügen.
- addFrame()-Methode: Diese Methode nimmt ein AnimFrame und hängt es an die ArrayList namens frames. Auch hier werden wir synchronized nutzen.
[crayon-628a8f2487ed8275408781/]
- update()-Methode: Was wir mit dieser Methode vor haben, sollte jedem klar sein. elapsedTime ist die Zeit, welche seit dem letzten Durchlaufen der Methode vergangen ist.
[crayon-628a8f2487edd950186290/]
- getImage()-Methode: Diese Methode gibt das Bild aus, welches zu currentFrame gehört. In dieser Methode benutzen wir Image anstelle von Void. Dies bedeutet, dass diese Methode einen Wert an die Methode zurück gibt, welche sie aufgerufen hat.
[crayon-628a8f2487ee2228907593/]
- getFrame()-Methode: Hier lassen wir uns den aktuellen Frame ausgeben.
[crayon-628a8f2487ee6645383350/]
4. Die Nested (geschachtelte) AnimFrame Klasse
Wir haben nun schon einige Male über AnimFrame Objekte gesprochen, aber wir haben noch keine Klasse angelegt, um diese zu erzeugen. Wir könnten nun eine neue Klasse erstellen und diese in der Animation-Klasse aufrufen. Einfacher ist es jedoch, diese direkt in der Animation-Klasse zu platzieren und genau das bedeutet nesting (eine Klasse in einer anderen Klasse schreiben).
Nun werden wir AnimFrame bearbeiten und alles Nötige mit STRG + Shift + O importieren:
[crayon-628a8f2487eeb043537453/]
Nun sollten wir alle den selben Stand haben:
[crayon-628a8f2487eef865794075/]
Stunde #2-25: Animieren unserer Spielfiguren
Ladet die folgenden Bilder herunter und speichert sie in eurem Data Ordner:
Bitte überschreibt die Dateien heliboy.png und background.png mit den beiden Bildern. Ich hatte in der vorherigen Lektion eine falsche Datei eingefügt. Das neue Hintergrundbild ist für das Auge.
Wenn wir das getan haben, gehen wir auf Project > Clean > OK.
Nun haben wir unser Projekt etwas aufräumen lassen und gehen in die StartingClass. Um unsere neue Animationsklasse verwenden zu können, müssen wir diese erst importieren:
[crayon-628a8f2487ef7658630527/]
Das ist einer der Momente, wo alles plötzlich einen Sinn ergibt. Ihr habt schon eine Menge importiert, ohne zu wissen, wozu das eigentlich nötig ist, aber jetzt habt ihr zum ersten Mal eure eigene Klasse importiert. Nun solltet ihr verstehen, wie es wirklich funktioniert.
1. Bilder Variablen anpassen
Wir haben neue Bilder in unseren data Ordner kopiert. Um diese auch nutzen zu können, müssen wir sie als Variable deklarieren:
[crayon-628a8f2487efc976246447/]
2. Animationsobjekte erstellen
Um unseren Roboter zu animieren, benutzen wir anim und um den Heliboy zu animieren, benutzen wir hanim.
[crayon-628a8f2487f01327349203/]
3. Bildeinstellungen
Nun müssen wir die von uns neu hinzugefügten Bilder initialisieren. Dazu werden wir Änderungen an der init()-Methode vornehmen. Wir werden die neuen Bilder ergänzen und anim und hanim, welche die Frames erstellen mit den jeweiligen Bildern und der Anzeigedauer.
[crayon-628a8f2487f06872057205/]
4. Aufrufen unserer Bilder
Um unsere neu erzeugten Animationen aufzurufen, müssen wir diese in der run()-Methode auch ändern. Wenn ihr vergleicht, was wir ändern und hinzufügen, sollte es sich selbst erklären.
[crayon-628a8f2487f0c722017591/]
5. Animation
Wir erstellen eine animate()-Methode. Mit den Parametern, welche wir darin bestimmen, können wir leichter ändern, wie schnell unsere Figuren animiert werden. Je höher der Wert, desto schneller die Animation, passt diesen Wert je nach Belieben an. Schreibt diese Methode nach der run()-Methode.
[crayon-628a8f2487f11131377547/]
6. Bildschirmausgabe
Um unsere neuen Animationen auch auf dem Bildschirm zu sehen, müssen wir die paint()-Methode entsprechend ändern. Dazu werden wir nur unsere beiden Heliboys in dieser Methode ändern, den Roboter haben wir schon in der run()-Methode bearbeitet.
[crayon-628a8f2487f16549080334/]
Damit sind wir eigentlich am Ende dieser Lektion, ich muss aber noch einen Fehler aus der Lektion 5 klar stellen. Natürlich kann unser Roboter auch springen, dazu braucht ihr einfach nur die Leertaste zu betätigen. Ich bin mir nicht ganz sicher, was mich dabei geritten hat, dass zu schreiben.
Heute haben wir es geschafft, dass sich die Rotorblätter unserer Helikopter drehen und unser Roboter blinzelt. Ich denke, das ist sehr gut für eine Lektion. Falls es noch etwas gibt, wo ihr nicht genau wisst, wie es funktioniert wie beispielsweise die Abfolge der Bilder, dann spielt einfach ein wenig mit dem Code oder stellt mir Fragen.
In der nächsten Lektion werden wir uns mit 2D-Feldern beschäftigen. Damit bereiten wir uns darauf vor, unsere eigenen Level zu erstellen. Wir werden dies in den nächsten beiden Lektionen lernen und schließen damit Kapitel 2 ab. Da ich in den nächsten Tagen im Ski-Urlaub bin, werden frühestens nächste Woche neue Lektionen veröffentlicht.
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.
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
Hallo,
möchte hier an der Stelle ein großes Lob ausprechen! Die Seite ist echt super gemacht und schön geordnet. Arbeite mich hier schon den ganzen Tag durch und es war wirklich eine große Hilfe für mich.
Danke dir!
Hallo,
mir ist da ein kleiner Fehler aufgefallen. Wenn wir die Heliboys runterladen, werden diese automatisch als „heliboy21“, „heliboy31“, usw. bezeichnet.
Unter der Bildeinstellung bezeichnest du sie allerdings nur als „heliboy2“ etc.:
z.B.: heliboy2 = getImage(base, „data/heliboy2.png“); // das zweite „heliboy2“ ist gemeint
Das hat zur Folge, dass die Animation nicht richtig ausgeführt wird.
Aber super Arbeit, die du hier machst. Ich freue mich schon auf die nächsten Lektionen 🙂
Hallo
Danke für den Hinweis, habe es angepasst und sollte nun wieder alles funktionieren.
Grüße
Hallo,
im Listing zu Punkt 4, „Die Nested AnimFrame Klasse“ ist ein Fehler. Der hat mich persönlich erstmal an den Rand der Verzweiflung gebracht hat (hatte beim Abtippen auch mal mein Gehirn kurz ausgeschaltet), da die IDE erstmal mit massenweisen Fehlern um sich geschmissen hat.
Die Klasse hast du mit „private AnimFrame getFrame(int i) {“ erstellt.
Richtig wäre wohl „private class AnimFrame {„, wie es auch in der anschliessenden Zusammenfassung steht.
Weiterhin ist in der „Stunde 2-25“ ist die Nummerierung nicht durchgängig. Nach Punkt 3 kommt Punkt 5.
Und noch eine letzte Anmerkung:
Ich weiss nicht, ob es an meinem PC/Browser liegt, oder ob dies Absicht ist (das unterstelle ich jetzt mal ^^). Im ersten Teil der heutigen Lektion sind neue Programmteile in rot unterlegt. Im zweiten Teil sind aber alle Listings nur schwarz. Da aber gerade im zweiten Teil sehr viel mal „mittenrein“ ergänzt wird, wäre gerade hier eine farbige Unterlegung der neuen Teile von Vorteil.
Ansonsten ist das Tutorial verständlich und es macht Spass, mal „hinter die Kulissen“ beim Programmieren von Spielen zu schauen.
Hallo
Danke dir für deine Hilfe, deine ersten beiden Punkte waren Fehler von meiner Seite, welche ich nun ausgebessert habe.
Das mit dem Rot ist so eine Sache, eigentlich soll das immer angezeigt werden. Habe es nun nochmals überarbeitet und ausgebessert.
Freut mich das es dir viel Spaß bereitet und ich hoffe doch, dass wir alle dann eine Android App programmieren können.
Grüße
Hallo,
das war aber eine schnelle Reaktion.
Leider ist immer noch ein kleiner Fehler in der Definition der AnimFrame-Klasse (erster Teil, Punkt 4).
Du hast das „getFrame (int i)“ noch dringelassen, das müsste da wohl noch weg.
Dir noch einen schönen Tag.
Danke, habe es entfernt.
Ich bin gerade beim erstellen einer neuen Lektion, daher die schnelle Antwort.
Grüße