AS3-Tutorium: Flash: Butterfly 06 external code

aus GlossarWiki, der Glossar-Datenbank der Fachhochschule Augsburg

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

  1. Die Datei Butterfly05Flash.fla unter dem Namen Butterfly06Flash.fla speichern und mit dieser Datei weiterarbeiten.
  2. In der Bibliothek: Doppelklick auf das Icon vor dem Symbol ButterflyMovie → Die Definition des Symbols wird in der Bühne geöffnet.
  3. In der Bibliothek: Rechtsklick auf das Icon vor dem Symbol ButterflyMovieEigenschaftenErweitert aufklappen → Haken vor Export für ActionScript, Haken vor Export in Bild 1, Klasse: ButterflyMovieOKOK
  4. DateiNeuActionScript 3.0-Klasse (CS5) bzw. ActionScript-Datei (CS4 und früher) → OK
    Nur in CS5: -> Klassenname: ButterflyMovieOK
  5. DateiDatei speichern unterButterflyMovie.as (im selben Ordner wie die zugehörige fla-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

Verknüpfen einer Klasse mit einem Symbol

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 → EigenschaftenErweitert 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.

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:

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.

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:

Und in den Eigenschaftsfenstern der Butterfly-Symbole werden folgende Klassennamen eingetragen:

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

SVN-Repository-Verweise


Dieser Artikel ist GlossarWiki-konform.