AS3-Tutorium: Flash: Butterfly 06 external code
Dieser Artikel ist veraltet und wird künftig evtl. entfernt.
Dieser Artikel erfüllt die GlossarWiki-Qualitätsanforderungen nur teilweise:
Korrektheit: 4 (großteils überprüft) |
Umfang: 3 (einige wichtige Fakten fehlen) |
Quellenangaben: 5 (vollständig vorhanden) |
Quellenarten: 5 (ausgezeichnet) |
Konformität: 4 (sehr gut) |
AS3-Tutorium: Butterfly: Flash | Flex
Flash: Übersicht | Teil 1 | Teil 2 | Teil 3 | Teil 4 | Teil 5 | Teil 6 | Teil 7a | Teil 7b | Teil 7c | Teil 8 | Teil 9 | Teil 10
Verbesserung der fünften Version des Schmetterling-Movies
In AS3-Tutorium: Flash: Butterfly 05 external code wurde der Code aus der Hauptzeitleiste in eine Klasse ausgelagert. Nun soll auch noch der Code vom Schmetterlings-Movie so weit wie möglich ausgelagert werden (ohne das Verhalten des Filmes zu ändern.)
<swf width="367" height="267">http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs5/butterfly/butterfly_06_external_code/Butterfly06Flash11.swf</swf>
Musterlösung (Flash CS5)
(SVN-Repository)
Musterlösung (Flash CS4) (SVN-Repository)
Der Code des Schmetterlingsmovies wird ausgelagert
- Die Datei
Butterfly05Flash.fla
unter dem NamenButterfly06Flash.fla
speichern und mit dieser Datei weiterarbeiten. - In der Bibliothek: Doppelklick auf das Icon vor dem Symbol
ButterflyMovie
→ Die Definition des Symbols wird in der Bühne geöffnet. - In der Bibliothek: Rechtsklick auf das Icon vor dem Symbol
ButterflyMovie
→Eigenschaften
→Erweitert
aufklappen → Haken vorExport für ActionScript
, Haken vorExport in Bild 1
, Klasse:ButterflyMovie
→OK
→OK
Datei
→Neu
→ActionScript 3.0-Klasse
(CS5) bzw.ActionScript-Datei
(CS4 und früher) →OK
Nur in CS5: -> Klassenname:ButterflyMovie
→OK
Datei
→Datei speichern unter
→ButterflyMovie.as
(im selben Ordner wie die zugehörigefla
-Datei.)
Achtung: Die scripts
-Ebene des Butterfly-Movies wird — im Gegensatz zur scripts
-Ebene des Main-Movies — nicht gelöscht.
Der ActionScript-Code wird allerdings deutlich vereinfacht: In einem Frame steht zum Schluss höchstens ein Methodenaufruf (siehe weiter unten).
In die Datei ButterflyMovie.as
wird folgender Code eingefügt:
package
{
import flash.display.MovieClip;
public class ButterflyMovie extends MovieClip
{
/////////////////////////////////////////////////////////////////////////////
// Attributes
/////////////////////////////////////////////////////////////////////////////
public var roundsToFly: int = 0;
/////////////////////////////////////////////////////////////////////////////
// Constructor
/////////////////////////////////////////////////////////////////////////////
public function ButterflyMovie()
{
stop();
}
/////////////////////////////////////////////////////////////////////////////
// Methods called from within the timeline
/////////////////////////////////////////////////////////////////////////////
public function testNumberOfRounds(): void
{
if (roundsToFly == 0)
gotoAndPlay("lb_end");
}
public function decrementNumberOfRounds(): void
{
roundsToFly--;
// if (roundsToFly > 0)
gotoAndPlay("lb_start");
}
/////////////////////////////////////////////////////////////////////////////
// End of class
/////////////////////////////////////////////////////////////////////////////
}
}
Die öffentlich zugängliche Zustandasvariable roundsToFly
wurde in die Klasse verlagert. Außerdem wurden zwei Methoden definiert, die den
Test-Code aus der Zeitleiste des Butterfly-Movies enthalten (wobei die zweite
If-Bedingung überflüssig ist und daher auskommentiert wurde).
Der stop
-Befehle aus dem ersten Frame wurde in den Konstruktor ausgelagert.
Damit kann der Code in der Zeitleiste auf drei simple Methodenaufrufe reduziert werden:
- Frame 1
- kein Code mehr
- Frame 2
testNumberOfRounds();
- Frame 150
decrementNumberOfRounds();
- Frame 220
stop();
Vergessen Sie nicht, bei den obigen Frames Schlüsselbilder in der Ebene scripts
zu erzeugen (sofern diese noch nicht vorhanden sind).
Sonst können Sie den entsprechenden Frames keinen Code zuweisen.
Die Label lbStart
und lbEnd
werden in der Zeitleiste in lb_start
und lb_end
umbenannt. Damit wird ausgedrückt,
dass auf diese Labels nur noch inter, d.h. von der dem MovieClip zugeordneten Klasse aus, auf diese Labels zugegriffen wird.
Export in Bild 1
Wie oben gezeigt wurde, kann eine Klasse mit einem Symbol ganz einfach werknüpft werden:
- In der Bibliothek: Rechtsklick auf das Icon vor dem gewünscheten Symbol →
Eigenschaften
→Erweitert
aufklappen.
Daraufhin erscheint das rechts abgebildete Menü.
Der Menü-Punkt Export in Bild 1
sollte immer dann gewählt werden, wenn die Chance besteht,
dass keine zugehörigen Objekte direkt auf der Bühne abgelegt werden, sondern nur zur Laufzeit mit Hilfe
von new ButterflyMovie
erzeugt werden sollen.
Der Grund ist, dass der ActionScript-Compiler bestrebt ist, möglichst kleine SWF-Dateien zu erzeugen. Er analisiert dazu, welche Objekte (direkt oder innerhalb anderer Movie Clips) auf der Bühne liegen und fügt nur den Code für diejenigen Symbole ein, die auf der Bühne auch tatsächlich verwendet werden.
Wenn nun für ein Symbol keine Objekte auf der Bühne liegen, wird der zugehörige Code auch nicht in die
SWF-Datei eingefügt. Das heißt, wenn dann später mit Hilfe von new
ein Objekt für dieses
Symbol erstellt werden soll, stürtzt die SWF-Datei mit einer Fehlermeldung ab.
Dieses Problem kann man beheben, indem man einfach ein unsichtbares Objekt für dieses Symbol
auf die Bühne legt, bevor der Compiler eine SWF-Datei erzeugt. Genau diese Arbeit nimmt einen
Flash ab, wenn man einen Haken vor die Option Export in Bild 1
aktiviert.
Sie sollten allerdings darauf achten, dass die Bibliothek keine Symbole enthält, bei denen diese Option aktiviert ist, die aber gar nicht in Ihrem Movie verwendet werden. Dies hätte nämlich zur Folge, dass sich die SWF-Datei unnötig aufbläht, weil der Code für alle diese Symbole mit eingebunden wird.
Mehrere Movie-Clips mit der Klasse ButterflyMovie
verknüpfen
<swf width="367" height="267">http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs5/butterfly/butterfly_06_external_code_multi/Butterfly06MultiFlash11.swf</swf> Erweiterte Musterlösung (Flash CS5) (SVN-Repository)
Erweiterte Musterlösung (Flash CS4) (SVN-Repository)
Wenn man so vorgeht, wie oben beschrieben, kann man nicht mehrere Movie Clips mit der Klasse ButterflyMovie
verknüpfen.
Sollte man dies vorhaben (weil man z.B. wie in der erweiterten Musterlösung zwei verschiedene Schmetterlinge gleichzeitig Runden drehen lassen will), muss man ButterflyMovie
als Basisklasse definieren. Dies wird im Folgenden etwas genauer beschrieben.
-
Vorgabe von Flash
-
Ergebnis, wenn man die Flash-Vorgabe übernimmt und nachträglich die Klasse
Butterfly
explizit definiert -
Definition von
ButterflyMovie
als Basisklasse -
Definition von
ButterflyMovie
als Basisklasse
Bild 1 zeigt die Vorgabe von Flash: Der Name ButterflyMovie
des ausgewählten Symbols wird als Klasse vorgeschlagen und flash.display.MovieClip
als Basisklasse. Dies ist ein guter Defaultwert, wenn die Klasse ButterflyMovie
gar nicht explizit definiert werden soll. Flash erzeugt dann selbstständig eine neue Klasse ButterflyMovie
, die alle
Eigenschaften von flash.display.MovieClip
erbt, aber keine weiteren Eigenschaften hat.
Im obigen Tutorium wurde diese Voreinstellung gewählt. Wenn man anschließend das Eigenschafts-Fenster des Symbols ButterflyMovie
wieder öffnet, ist die Basisklasse entfernt worden (siehe 2. Bild). Flash hat erkannt,
dass die Klasse ButterflyMovie
in der Datei ButterflyMovie.as
als Subklasse von
flash.display.MovieClip
definiert wurde. Flash braucht also nicht selbstständig eine Klasse aus
einer vorgegebenen Basisklasse abzuleiten. Daher wird der Eintrag der Basisklasse automatisch gelöscht.
Eine existierende Klasse nicht als Basisklasse, sondern wie oben beschrieben direkt als Klasse einzutragen, hat allerdings einen
gravierenden Nachteil. Es darf keine zwei Symbole geben, denen dieselbe Klasse zugeordnet ist. Der Grund ist dafür,
dass man für ein Symbol auch mit Hilfe des new
-Operators Objekte zur Laufzeit erzeugen kann:
var v_butterfly_movie: ButterflyMovie = new ButterflyMovie();
Wäre zwei Symbolen diese Klasse zugeordnet, wüsste Flash bei obigem Befehl nicht, für welches dieser beiden Symbole ein zugehöriges Objekt erzeugt werden soll.
Abhilfe bringt hier, ButterflyMovie
als Basisklasse aller Schmetterlings-Movies einzutragen und
den Symbolen jeweils einen eindeutigen Klassennamen zuzuordnen (Bilder 3 und 4). Für die eigentlichen Klassennamen
(hier ButterflyMovieBlue
und ButterflyMovieRed
)
gibt man dann keine Definitionen mehr an. Flash leitet diese Klassen automatisch aus der Basisklasse ab.
Allerdings geschieht dies nicht ohne einen Warnhinweis. Hier kann, ja muss man OK klicken:
-
Warnung, wenn die angegebene Klasse nicht existiert
Nun ist es möglich, für jedes Symbol beliebig viele Schmetterlinge auch dynamisch zur Laufzeit zu erzeugen:
var v_butterfly_movie_blue: ButterflyMovie = new ButterflyMovieBlue(); // Man beachte: Beiden Variablen wurde
var v_butterfly_movie_red: ButterflyMovie = new ButterflyMovieRed(); // die Basisklasse als Typ zugordent!
Eine Kleinigkeit gilt es noch zu beachten. Man kann nur existierende Klassen als Basisklassen eintragen. Wenn man eine Klasse einträgt, die noch nicht definiert wurde, erhält man folgende Fehlermeldung.
-
Fehlermeldung, wenn die angegebene Basisklasse nicht existiert
Prinzipiell gilt also: Eine existierende Klasse sollte immer als Basisklasse eingetragen werden (Default: flash.display.MovieClip
).
Als Klassennamen werden danach eindeutige Klassen-Bezeichner vergeben. Diese Klassen werden jedoch nicht definiert.
Eine kleine Unsauberkeit ist in dem obigen Beispiel noch enthalten. Um nicht den Überblick aufgrund zahlreicher Klassen im Hauptordner zu verlieren und um Namenskonflikte zu vermeiden, sollte man jede Klasse grundsätzlich in ein geeignetes Paket stecken.
Zum Beispiel könnte man das Paket hsa.tutorial.butterfly
definieren. Dazu legt man den Orner hsa
in dem Ordner an, in dem sich die fla
-Datei des Schmetterling-Movies befinden. Im Ordner hsa
definiert man einen Unterordner tutorial
und darin den Unterordner butterfly
. In diesem letzen Ordner fügt man die Dateien Main.as
und ButterflyMovie.as
ein.
Als nächstes ersetzt man in beiden Dateien in der ersten Zeile package
durch package hsa.tutorial.butterfly
.
Zu guter Letzt muss man noch die Klassenzuordnungn in Flash anpassen. Im Eigenschaftsfenster des Haupt-Movies wird der Klassenname
Main
durch hsa.tutorial.butterfly.Main
ersetzt:
-
Klasse
Main
mit Paketnamenpfadhsa.tutorial.butterfly
Und in den Eigenschaftsfenstern der Butterfly-Symbole werden folgende Klassennamen eingetragen:
-
Erweiterung des Klassennamens um den Paketnamen
hsa.tutorial.butterfly
-
Erweiterung des Klassennamens um den Paketnamen
hsa.tutorial.butterfly
Die erweiterte Musterlösung wurde gegenüber der einfachen Musterlösung auf genau diese Weise modifiziert.
Probleme der Implementierung
Die im vierten und fünften Teil des Flash-Tutoriums genannte Problem wurden behoben:
- Der Code kann jetzt gelesen werden, ohne sich durch Zeitleisten zu wühlen.
- Die Klasse
ButterflyMovie
kann (als Basisklasse!) beliebig vielen Symbolen zugeordnet werden.
Allerdings wurden bislang weder für den Schmetterlings-Movie noch für die Anwendung selbst saubere Schnittstellen definiert. Außerdem wurden die Aufgaben der Anwendung noch nicht sauber getrennt (vgl. Programmierprinzipien, insbesondere Separation of Concerns).
Quellen
- Kowarschick, W.: Multimedia-Programmierung
- Musterlösung (Flash CS5)
- Musterlösung (Flash CS4)
- Erweiterte Musterlösung (Flash CS4)
- Erweiterte Musterlösung (Flash CS5)
SVN-Repository-Verweise
- Musterlösung (Flash CS5)
- Musterlösung (Flash CS4)
- Erweiterte Musterlösung (Flash CS4)
- Erweiterte Musterlösung (Flash CS5)