|
|
| (6 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) |
| Zeile 1: |
Zeile 1: |
| {{AS3-Tutorium:Flash:Butterfly:Menü}} | | {{AS3-Tutorium:Flash:Butterfly:Menü}} |
| {{In Bearbeitung}}
| |
|
| |
|
| =Weiterentwicklung der sechsten Version des Schmetterling-Movies= | | =Das Schmetterlingssymbol als Spielfigur mit weichen Übergängen: Vereinfachte Version= |
|
| |
|
| In [[AS3-Tutorium: Flash: Butterfly 06 external code]] wurde der Code aus den Zeitleisten des Hauptfilms sowie der Symbole weitestgehend in Klassen ausgelagert.
| | <swf width="367" height="267">http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs5/butterfly/butterfly_07c_character/Butterfly07cFlash11.swf</swf> |
| Allerdings wurde bei der Implementierung bislang nicht das Prinzip [[Separation of Concerns]] (siehe auch [[Programmierprinzipien]]) beachtet.
| | '''[http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs5/butterfly/butterfly_07c_character/ Musterlösung (Flash CS5)]''' |
| Um dies zu erreichen, werden in einem ersten Schritt
| | ([http://glossar.hs-augsburg.de/webdav/tutorium/flash_cs5/butterfly/butterfly_07c_character/ SVN-Repository]) |
| die Symbole <code>Butterfly</code> und <code>ButterflyMovie</code> in „[[Spielfigur]]en“ (characters) umgewandelt.
| |
|
| |
|
| Eine Spielfigur kann verschiedene Zustände einnehmen, wie z.B. „stehen“, „laufen nach links“, „laufen nach rechts“, „hüpfen“ etc.
| | '''[http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs4/butterfly/butterfly_07c_character/ Musterlösung (Flash CS4)]''' |
| Dabei sollte ein Figur-Objekt nicht selbst entscheiden, wann es in welchen Zustand übergeht. Die wird von außen (z.B.) über eine Logik-Komponente gesteuert.
| | ([http://glossar.hs-augsburg.de/webdav/tutorium/flash_cs4/butterfly/butterfly_07c_character/ SVN-Repository]) |
| Das heißt, eine Figur hat nur noch eine einzige Aufgabe: Den Zustand dieser Figur (der im Allgemeinen in einem Datenobjekt gespeichert wird) zu ''visualisieren''.
| |
| | |
| Im Folgenden wird zunächst das Symbol <code>Butterfly</code> in eine Spielfigur (im zuvor beschrieben Sinn) umgewandelt, um das Grundprinzip klar zu machen.
| |
| In zwei weiteren Schritten wird die Implementierung verbessert, so dass die Übergänge von einem Zustand in den anderen „weich“ erfolgen.
| |
| Auf die zur Verfügung gestellte Schnittstelle hat dies keine Auswirkungen.
| |
| | |
| Danach wird das Symbol <code>ButterflyMovie</code> in eine „Figur“ umgewandelt.
| |
| Hierbei wird insbesondere die Progammlogik (fliegen einer via <code>roundsToFly</code> vorgegebenen Anzahl von Runden)
| |
| aus der Klasse <code>ButterflyMovie</code> in die Hauptklasse <code>Main</code> verlagert.
| |
| <noinclude>
| |
| | |
| <swf width="367" height="267">http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs5/butterfly/butterfly_07_character/Butterfly07Flash11.swf</swf>
| |
| '''[http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs5/butterfly/butterfly_07_character/ Musterlösung (Flash CS5)]'''
| |
| ([http://glossar.hs-augsburg.de/webdav/tutorium/flash_cs5/butterfly/butterfly_07_character/ SVN-Repository])
| |
| | |
| '''[http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs4/butterfly/butterfly_07_character/ Musterlösung (Flash CS4)]''' | |
| ([http://glossar.hs-augsburg.de/webdav/tutorium/flash_cs4/butterfly/butterfly_07_character/ SVN-Repository]) | |
| </noinclude> | | </noinclude> |
|
| |
|
| ==Das Datenmodell==
| | Der Code, der im [[AS3-Tutorium: Flash: Butterfly 07b character|vorangegangenen Teil des Tutoriums]] erstellt wurde, |
| | ist ziemlich umfangreich und schwer zu verstehen. |
|
| |
|
| Bevor mit der Programmierung einer Anwendung begonnen wird, sollte zunächst ein [[Datenmodell]]
| | Wenn Spielfiguren komplexere Bewegungsabläufe als der Schmetterling aufweisen, ist es i. Allg. sogar noch schwieriger, |
| ([[Klassendiagramm (UML)|Klassendiagramm]], [[Zustandsdiagramm (UML)|Zustandsdiagramm]] etc.)
| | einen weichen Übergang von Zustand zu Zustand zu realisieren. Beispielsweise dreht sich daher eine Spielfigur eines |
| erstellt werden. Folgendes Klassendiagramm wird in diesem Teil des Tutorium realisiert:
| | Jump'n'Run-Spiels so gut wie immer schlagartig um 180 Grad, |
| | wenn der Benutzer die Bewegungsrichtung ändert. |
|
| |
|
| [[Medium:AS3-Tutorium Butterfly Flash 07 Class Diagram.jpg]]
| | Die Kompelxität der zuvor definierten <code>Butterfly</code>-Klasse ist vor allem der Tatsache geschuldet, |
| | dass für jeden Zustand eine eigener Frames-Block definiert wurde. Obwohl dies i. Allg. notwendig ist |
| | (und daher dieser allgemeine Fall auch im Tutorium demonstriert wurde), soll nicht verschwiegen werden, |
| | dass es für den Schmetterling eine wesentlich einfache Implementierung gibt, die genau dasselbe Verhalten wie |
| | zuvor realisiert. |
|
| |
|
| '''[http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs5/butterfly/butterfly_07_character/uml/ Ordner mit StarUML-Diagramm und von StarUML erzeugtem AS3-Code-Rahmen]'''
| | Im dritten Frame-Block sind alle gewünschten Zustände enthalten: |
| ([http://glossar.hs-augsburg.de/webdav/tutorium/flash_cs5/butterfly/butterfly_07_character/uml/ SVN-Repository])
| | Flügelschlagender Schmetterling, Schmetterling mit offenen Flügeln und Schmetterling mit geschlossenen Flügeln. |
| | Dehalb reicht es, den Flügelschlag im richtigen Moment anzuhalten bzw. zu starten, um zwischen den einzelen Zuständen zu wechseln. |
| | Ein Sprung über mehrer Frames hinweg ist (außer beim Rücksprung auf das erste Bild der Framesequenz) gar nicht notwendig. |
|
| |
|
| | ==Die Modifikationen== |
|
| |
|
| Es gibt zwei Klassen zur Visualisierung einer Spielfigur (so genannte [[Model-View-Controller-Paradigma|View]]-Klassen):
| | Folgende Vereinfachungen müssen zunächst am Schmetterling vorgenommen werden: |
|
| |
|
| * <code>Butterfly</code>, eine Spielfigur, die sich nicht selbstständig vom Platz bewegt, aber verschiedene Zustände annehmen kann.
| | # In der Zeitleiste des Symbols <code>Butterfly</code> werden die beiden zuvor eingeführten zusätzlichen Frame-Blöcke wieder entfernt: Die Frames 1 bis 39 in allen vier Ebenen gleichzeitig markieren → Rechtsklick in den markierten Bereich → <code>Bilder entfernen</code>. |
| * <code>ButterflyMovie</code>, eine animierte Spielfigur, die sich auf vordefinierten Bahnen bewegt und auch verschiedene Zustände annehmen kann.
| | # In der Zeitleiste, Ebene <code>labels</code>: Die Label <code>lb_butterfly_open</code> in <code>lb_start</code> umbenennen und Label <code>lb_butterfly_close</code> löschen. |
| | # In der Zeitleiste, Ebene <code>scripts</code>, Frame 20: <code>gotoAndPlay("lb_start");</code> an Stelle von <code>gotoAndPlay("lb_fluttering_open");</code> |
|
| |
|
| Beide Klassen sind, da sie [[Symbol (Flash)|Symbol]]en zugeordnet werden, Subklassen der ActionScript-Klasse <code>MovieClip</code>.
| | Den Code in der Datei <code>Butterfly.as</code> durch folgenden Code ersetzen: |
| | |
| Ein Schmetterling kann drei Zustände annehmen:
| |
| * Flügel offen (<code>OPEN</code>)
| |
| * Flügel geschlossen (<code>CLOSE</code>)
| |
| * flatternd (<code>FLUTTERING</code>)
| |
| | |
| Dieser Zustand kann über das Attribut <code>state</code> gelesen und modifiziert werden.
| |
| Mit Hilfe des Attributs <code>stateAnimation</code> kann erfragt werden, in welchem Zustand sich die
| |
| Animation gerade befindet (Flügel offen oder geschlossen). Dies ändert sich insbesondere während des Flatterns
| |
| ständig.
| |
| | |
| Der Schmetterling informiert mittels [[Signal]]en ([[Event]]s) interessierte [[Beobachter]] ([[Observers]], [[Event Listener]]s) sowohl
| |
| dann, wenn sich der Zustand (<code>state</code>) ändert, als auch dann, wenn sich der Zustand der Animation
| |
| (<code>stateAnimation</code>), d.h. der Flügel ändert. Dazu wird die Signal-Klasse <code>ButterflyEvent</code>
| |
| (eine Subklasse der ActionScript-Klasse <code>Event</code>) definiert, die zwei Konstanten zur Beschreibung dieser Ereignistypen bereithält.
| |
| | |
| Ein Schmetterlingsmovie kann vier Zustände annehmen:
| |
| * wartend (<code>WAITING</code>)
| |
| * herumfliegend (<code>FLYING_AROUND</code>)
| |
| * wegfliegend (<code>FLYING_AWAY</code>)
| |
| * von außerhalb zum Warteplatz fliegend (<code>FLYING_IN</code>)
| |
| | |
| Dieser Zustand kann über das Attribut <code>state</code> gelesen und modifiziert werden.
| |
| Mit Hilfe des Attributs <code>stateAnimation</code> kann erfragt werden, in welchem Zustand sich die
| |
| Animation gerade befindet. Dieses Attribut ändert sich jeweils zum Ende
| |
| einer Flugsequenz. Das heißt, das Attribut kann insgesamt sieben Werte annehmen:
| |
|
| |
|
| * wartend (<code>WAITING</code>)
| | <source lang="actionscript3"> |
| * herumfliegen wurde beendet (<code>END_FLYING_AROUND</code>)
| |
| * wegfliegen wurde beendet (<code>END_FLYING_AWAY</code>)
| |
| * zum Warteplatz fliegen wurde beendet (<code>END_FLYING_IN</code>)
| |
| | |
| Der Schmetterlingsmovie informiert ebenfalls mittels Signalen interessierte Beobachter sowohl
| |
| dann, wenn sich der Zustand (<code>state</code>) ändert, als auch dann, wenn sich der Zustand der Animation
| |
| (<code>stateAnimation</code>) ändert, d.h., wenn eine Flugsequenz beendet wird. Hierfür wird die Klasse
| |
| <code>ButterflyMovieEvent</code> verwendet.
| |
| | |
| Auf das Schmetterlingsobjekt, dass dem Schemtterlingsmovie zugeordnet ist, kann von außen nicht zugegriffen werden:
| |
| Die Beziehung wurde als <code>private</code> definiert.
| |
| Wäre ein Direktzugriff möglich, so könnte man z.B. das Flügelschlagen während des Rundfluges deaktivieren.
| |
| Außerdem würde der Direktzugriff Verletzungen des [[Gesetz von Demeter|Gesetzes von Demeter]] ermöglichen.
| |
| | |
| Als Ersatz für den fehlenden Direkzugriff werden zwei weitere Attribute angeboten:
| |
| | |
| * <code>butterflyState</code>: definiert den Fügelzustand für den wartenden Schmetterling (offen, geschlossen, flatternd); wenn er fliegt, flatter er immer
| |
| * <code>butterflyStateAnimation</code>: gibt den aktuellen Flügelzustand preis: offen oder geschlossen
| |
| | |
| Da auf das Schmetterlingsobjekt nicht direkt zugegriffen werden kann, signalisiert der Schmetterlingsmovie auch die
| |
| Zustandsänderungen des Schmetterlingsobjektes.
| |
| | |
| Hier sieht man ein Problem, das sich bei der Beachtung des Gesetzes von Demeter ergibt, sehr deutlich.
| |
| Ein Objekt, das keinen Direktzugriff auf ein ihm zugeordnetes Objekt ermöglicht, muss als [[Adapter]] ([[Wrapper]])
| |
| für dieses Objekt implementiert werden. Dies hat zur Folge, dass zusätzlicher Code geschrieben werden muss, der im
| |
| Wesentlichen nichts weiter macht, als [[Nachricht (OOP)|Nachricht]]en weiterzuleiten.
| |
| | |
| Hier hat diese Vorgehen allerdings einen entscheidenden Vorteil: Es ist dem Benutzer der Klasse <code>ButterflyMovie</code>
| |
| nicht möglich, das Verhalten des Schmetterling in einem unpassenden Augenblick (d.h. während des Fluges)
| |
| zu verändern.
| |
| | |
| Im Allgemeinen ist Code, der hilft, Programmierfehler zu vermeiden, Code vorzuziehen, der
| |
| aufgrund des geringeren Overheads etwas effizienter ist.
| |
| | |
| ==Das Schmetterlingssymbol als Spielfigur==
| |
| | |
| Die Grundidee ist folgende: Für jeden Zustand der Spielfigur wird im Movie Clip ein eigener Abschnitt (d.h. ein zusammenhängender Bereich von Frames) definiert.
| |
| | |
| Das erste Frame eines jeden Abschnittes wird mit einen Label versehen, dessen Name sich aus dem zugehörigen Zustand ableitet (z.B. <code>lb_</code>'''<code>x</code>''', wobei '''<code>x</code>''' durch den aktuellen Zustand ersetzt wird).
| |
| | |
| Das letzte Frame eines jeden Abschnittes wird mit einem ActionScript-Befehl versehen:
| |
| * <code>stop();</code>, falls die dem Zustand zugeordnete Animation nur einmal abgespielt werden soll
| |
| * <code>gotoAndPlay(lb_</code>'''<code>x</code>'''<code>);</code>, falls die dem Zustand zugeordnete Animation dauerhaft abgespielt werden soll
| |
| | |
| Zunächst wird das Schmetterlingssymbol auf diese Weise umgestaltet.
| |
| | |
| # In der Bibliothek: Das Symbol <code>Butterfly</code> mit einem Doppelklick öffnen.
| |
| # In der Zeitleiste: Zwei neue Ebenen (ganz oben) einfügen:
| |
| #* <code>scripts</code>
| |
| #* <code>labels</code>
| |
| # In der Zeitleiste: Alle Ebenen (und damit alle Frames) markieren und den Block mit allen Frames nach rechts verschieben, so dass das erste Schlüsselbild auf Frame 40 liegt.
| |
| # In der Zeitleiste, Ebene <code>body</code>: Klick auf das Schlüsselbild bei Frame 40 → <code>Alt</code>-Taste drücken und festhalten → Linke Maustaste über Schlüsselbild bei Frame 40 drücken, festhalten und nach links bis Frame 1 verschieben ⇒ Der Schmetterlingskörper ist ab Frame 1 vorhanden; eer entsprechende Bereich in der Zeitleiste hat sich grau eingefärbt.
| |
| # In der Zeitleiste, Ebene <code>body</code>: Das Schlüssenbild bei Frame 40 entfernen: Klick auf das Schlüsselbild → Rechtsklick auf das Schlüsselbild → <code>Schlüsselbild löschen</code>.
| |
| # In der Zeitleiste, Ebene <code>wings</code>: Klick auf Frame 20 → Rechtsklick auf Frame 20 → <code>Schlüsselbild einfügen</code>.
| |
| # In der Zeitleiste, Ebene <code>wings</code>: <code>Strg</code>/<code>Ctrl</code>-Taste drücken und festhalten → Klick auf das Schlüsselbild bei Frame 40 → Rechtsklick auf das Schlüsselbild → <code>Bilder kopieren</code>.
| |
| # In der Zeitleiste, Ebene <code>wings</code>: Klick auf Frame 1 → Rechtsklick auf Frame 1 → <code>Bilder einfügen</code> (nicht <code>Bild einfügen</code>!!).
| |
| # In der Zeitleiste, Ebene <code>wings</code>: <code>Strg</code>/<code>Ctrl</code>-Taste drücken und festhalten → Klick auf das Schlüsselbild bei Frame 50 → Rechtsklick auf das Schlüsselbild → <code>Bilder kopieren</code>.
| |
| # In der Zeitleiste, Ebene <code>wings</code>: Klick auf Frame 20 → Rechtsklick auf Frame 20 → <code>Bilder einfügen</code> (nicht <code>Bild einfügen</code>!!).
| |
| # In der Zeitleiste, Ebene <code>labels</code>: Klick auf Frame 1 → Eigenschaften-Fenster öffnen → Name: <code>lb_open</code>
| |
| # In der Zeitleiste, Ebene <code>labels</code>: Klick auf Frame 20 → Rechtsklick auf Frame 20 → <code>Schlüsselbild einfügen</code> → Eigenschaften-Fenster, Name: <code>lb_close</code>
| |
| # In der Zeitleiste, Ebene <code>labels</code>: Klick auf Frame 40 → Eigenschaften-Fenster, Name: <code>lb_fluttering</code>
| |
| # In der Zeitleiste, Ebene <code>scripts</code> folgenden Code eintragen (Schlüsselbilder nicht vergessen!):
| |
| #; Frame 10: <code>stop();</code>
| |
| #; Frame 39: <code>stop();</code>
| |
| #; Frame 59: <code>gotoAndPlay("lb_fluttering");</code>
| |
| | |
| Als nächstes wird der Code zur Steuerung des Zustandswechsels dem Schmetterlings-Symbol zugeordnet:
| |
| | |
| # Im Menü: <code>Datei</code> → <code>Neu</code> → <code>ActionScript 3.0-Klasse</code> (CS5) bzw. <code>ActionScript-Datei</code> (CS4 und früher) → <code>OK</code><br/> Nur in CS5: -> Klassenname: <code>Butterfly</code> → <code>OK</code>
| |
| # Im Menü: <code>Datei</code> → <code>Datei speichern unter</code> → Im Ordner der <code>fla</code>-Datei folgende Unterordner anlegen: <code>hsa/tutorial/butterfly/view</code> → Datei unter dem Namen <code>Butterfly.as</code> im zuvor angelegten Unterordner speichern.
| |
| # In der Bilbliothek: Rechtsklick auf das Symbol <code>Butterfly</code> → <code>Eigenschaften</code> → falls notwendig: Klick auf Dreieck hinter <code>Erweitert</code> → Häckchen vor <code>Export für ActionScript</code> → Klasse: <code>hsa.tutorial.butterfly.view.ButterflyBlue</code> (oder eine andere Farbe), Basisklasse <code>hsa.tutorial.butterfly.view.Butterfly</code> → <code>OK</code> → <code>OK</code>
| |
| | |
| Nun kann in die Datei <code>Butterfly.as</code> folgendener Code einfügt werden:
| |
| <source lang="actionscript"> | |
| package hsa.tutorial.butterfly.view | | package hsa.tutorial.butterfly.view |
| { | | { |
| import flash.display.MovieClip; | | import flash.display.MovieClip; |
| | import hsa.tutorial.butterfly.event.ButterflyEvent; |
| | | |
| public class Butterfly extends MovieClip | | public class Butterfly extends MovieClip |
| Zeile 159: |
Zeile 51: |
| // Constants | | // Constants |
| ///////////////////////////////////////////////////////////////////////////// | | ///////////////////////////////////////////////////////////////////////////// |
| | | |
| public static const OPEN: String = "open"; | | public static const OPEN: String = "open"; |
| public static const CLOSE: String = "close"; | | public static const CLOSE: String = "close"; |
| public static const FLUTTERING: String = "fluttering"; | | public static const FLUTTERING: String = "fluttering"; |
| | | |
| ///////////////////////////////////////////////////////////////////////////// | | ///////////////////////////////////////////////////////////////////////////// |
| // Instance variables | | // Instance variables |
| /////////////////////////////////////////////////////////////////////////////
| |
|
| |
| private var v_state: String;
| |
|
| |
| ////////////////////////////////////////////////////////////////////////////
| |
| // Attributes
| |
| ///////////////////////////////////////////////////////////////////////////// | | ///////////////////////////////////////////////////////////////////////////// |
| | | |
| public function get state(): String | | // Instance variables of the attributes |
| {
| | private var v_state: String; |
| return v_state;
| |
| }
| |
|
| |
| public function set state(p_state: String): void
| |
| {
| |
| if (p_state != v_state)
| |
| {
| |
| this.gotoAndPlay("lb_"+ p_state);
| |
| v_state = p_state;
| |
| };
| |
| }
| |
| | |
| /////////////////////////////////////////////////////////////////////////////
| |
| // Constructor
| |
| /////////////////////////////////////////////////////////////////////////////
| |
|
| |
| public function Butterfly(p_state: String = OPEN)
| |
| {
| |
| this.state = p_state;
| |
| }
| |
|
| |
| /////////////////////////////////////////////////////////////////////////////
| |
| // End of class
| |
| ///////////////////////////////////////////////////////////////////////////// | |
| }
| |
| }
| |
| </source>
| |
| | |
| ===Signale===
| |
| Bei jeder Zustandsänderung soll das Schmetterlings-Objekt laut Klassendiagramm
| |
| alle interessierten Objekte, d.h. alle [[Observer-Pattern|Observer]] (bzw. in ActionScript: Event Listener)
| |
| mit Hilfe eines [[Signal]]s (in ActionScript [[Event]] genannt)
| |
| über die erfolgte Zustandsänderung informieren. Dies wäre
| |
| mit Hilfe des Befehls
| |
| <source lang="actionscript">
| |
| this.dispatchEvent(new Event(Event.CHANGE));
| |
| </source>
| |
| problemlos möglich.
| |
| | |
| Allerdings ist es sauberer, eine eigene Klasse <code>ButterflyEvent</code>
| |
| als Subklasse von <code>Event</code> zu definieren und dort spezielle <code>ButterflyEvent</code>-Konstanten einzuführen.
| |
| | |
| Die zugehörige Datei <code>ButterflyEvent.as</code> muss, wenn als Package-Name ebenfalls <code>hsa.tutorial.butterfly.event</code>
| |
| angegeben wird, im Unterordner <code>hsa/tutorial/butterfly/event</code> gespeichert werden.
| |
| Der Inhalt dieser Datei könnte folgendermaßen aussehen:
| |
| | |
| <source lang="actionscript">
| |
| package hsa.tutorial.butterfly.event
| |
| {
| |
| import flash.events.Event;
| |
|
| |
| public class ButterflyEvent extends Event
| |
| {
| |
| /////////////////////////////////////////////////////////////////////////////
| |
| // Constants
| |
| /////////////////////////////////////////////////////////////////////////////
| |
|
| |
| public static const CHANGE_BUTTERFLY: String
| |
| = "change butterfly";
| |
| public static const CHANGE_BUTTERFLY_ANIMATION: String
| |
| = "change butterfly animation";
| |
|
| |
| /////////////////////////////////////////////////////////////////////////////
| |
| // Constructor
| |
| /////////////////////////////////////////////////////////////////////////////
| |
|
| |
| public function ButterflyEvent(type: String = CHANGE_BUTTERFLY)
| |
| {
| |
| super(type);
| |
| }
| |
|
| |
| /////////////////////////////////////////////////////////////////////////////
| |
| // End of class
| |
| /////////////////////////////////////////////////////////////////////////////
| |
| }
| |
| }
| |
| </source>
| |
| | |
| Sobald man diese Datei erstellt hat, kann man die Setter-Methode <code>set state</code>
| |
| in der Datei <code>Butterfly.as</code> erweitern:
| |
| | |
| <source lang="actionscript">
| |
| public function set state(p_state: String): void
| |
| {
| |
| if (p_state != v_state)
| |
| {
| |
| this.gotoAndPlay("lb_"+ p_state);
| |
| v_state = p_state;
| |
| this.dispatchEvent(new ButterflyEvent());
| |
| };
| |
| }
| |
| </source>
| |
| | |
| Damit jede Änderung der Flügelstellung ebenfalls mit Hilfe eines Signals (der Art <code>CHANGE_STATE_ANIMATION</code> ) angezeigt wird, ist
| |
| ein wenig mehr Aufwand notwendig. In der Zeitleiste des Symbols <code>Butterfly</code> müssen geeignete Methodenaufrufe eingefügt werden:
| |
| | |
| # In der Zeitleiste des Symbols <code>Butterfly</code>, Ebene <code>scripts</code> folgenden Code eintragen (Schlüsselbilder nicht vergessen!):
| |
| #; Frame 1: <code>m_new_wings_state(OPEN);</code>
| |
| #; Frame 20: <code>m_new_wings_state(CLOSE);</code>
| |
| #; Frame 40: <code>m_new_wings_state(OPEN);</code>
| |
| #; Frame 50: <code>m_new_wings_state(CLOSE);</code>
| |
| | |
| Nun müssen noch die Methode <code>m_new_wings_state</code> sowie
| |
| das [[Attribut]] <code>stateAnimation</code>
| |
| in die Klasse <code>Butterfly</code> eingefügt werden. Man beachte, dass es
| |
| keine Setter-Methode gibt. Das Attribut kann von außen nur gelesen werden.
| |
| | |
| <source lang="actionscript">
| |
| private var v_state_animation: String; | | private var v_state_animation: String; |
|
| |
| public function get stateAnimation(): String
| |
| {
| |
| return v_state_animation;
| |
| }
| |
|
| |
| // Should be private, but cannot as it is accessed from within the timeline!
| |
| public function m_new_wings_state(p_state: String): void
| |
| {
| |
| v_state_animation = p_state;
| |
| this.dispatchEvent
| |
| (new ButterflyEvent(ButterflyEvent.CHANGE_BUTTERFLY_ANIMATION));
| |
| }
| |
| </source>
| |
|
| |
| Insgesamt sieht der Inhalt der Datei <code>Butterfly.as</code> nun folgendermaßen aus:
| |
|
| |
| <source lang="actionscript">
| |
| package hsa.tutorial.butterfly.view
| |
| {
| |
| import flash.display.MovieClip;
| |
| import hsa.tutorial.butterfly.event.ButterflyEvent;
| |
|
| |
| public class Butterfly01 extends MovieClip
| |
| {
| |
| /////////////////////////////////////////////////////////////////////////////
| |
| // Constants
| |
| /////////////////////////////////////////////////////////////////////////////
| |
| | | |
| public static const OPEN: String = "open"; | | // Auxiliary variable (for being able to perform delayed state changes) |
| public static const CLOSE: String = "close";
| | private var v_stop_state: String = null; |
| public static const FLUTTERING: String = "fluttering"; | |
| | | |
| ///////////////////////////////////////////////////////////////////////////// | | ///////////////////////////////////////////////////////////////////////////// |
| // Instance variables | | // Private methods |
| /////////////////////////////////////////////////////////////////////////////
| |
|
| |
| private var v_state: String;
| |
| private var v_state_animation: String;
| |
| | |
| ////////////////////////////////////////////////////////////////////////////
| |
| // Methods to be accessed from within the timeline!
| |
| ///////////////////////////////////////////////////////////////////////////// | | ///////////////////////////////////////////////////////////////////////////// |
| | | |
| Zeile 332: |
Zeile 74: |
| public function m_new_wings_state(p_state: String): void | | public function m_new_wings_state(p_state: String): void |
| { | | { |
| if (p_state != v_state_animation)
| | if (p_state != v_state_animation) |
| { | | { |
| v_state_animation = p_state; | | v_state_animation = p_state; |
| | // The state of the wings has changed. Inform the observers! |
| this.dispatchEvent | | this.dispatchEvent |
| (new ButterflyEvent(ButterflyEvent.CHANGE_BUTTERFLY_ANIMATION)); | | (new ButterflyEvent(ButterflyEvent.CHANGE_BUTTERFLY_ANIMATION)); |
| }; | | }; |
| }
| |
|
| |
|
| ////////////////////////////////////////////////////////////////////////////
| | // If the wings are to be stoped, stop them. |
| // Attributes
| | if (v_stop_state == p_state) |
| /////////////////////////////////////////////////////////////////////////////
| |
|
| |
| public function get state(): String
| |
| {
| |
| return v_state;
| |
| }
| |
|
| |
| public function set state(p_state: String): void
| |
| {
| |
| if (p_state != v_state) | |
| { | | { |
| this.gotoAndPlay("lb_"+ p_state); | | this.stop(); |
| v_state = p_state; | | v_stop_state = null; |
| this.dispatchEvent(new ButterflyEvent()); | | m_set_state(p_state); // Do the state change now! |
| }; | | }; |
| } | | } |
|
| |
| public function get stateAnimation(): String
| |
| {
| |
| return v_state_animation;
| |
| }
| |
|
| |
| /////////////////////////////////////////////////////////////////////////////
| |
| // Constructor
| |
| /////////////////////////////////////////////////////////////////////////////
| |
|
| |
| public function Butterfly(p_state: String = OPEN)
| |
| {
| |
| this.state = p_state;
| |
| }
| |
|
| |
| /////////////////////////////////////////////////////////////////////////////
| |
| // End of class
| |
| /////////////////////////////////////////////////////////////////////////////
| |
| }
| |
| }
| |
| </source>
| |
|
| |
| Damit ist es z.B. möglich, einen Flügelschlag-Sound mit dem Movie zu synchronisieren.
| |
| Im nachfolgenden Beispiel wird der aktuelle Zustand des Flügels in einem zweiten Textfeld ausgegeben.
| |
| Ein drittes Textfeld simuliert den Flip-Flap-Sound (da mir derzeit leider kein echter Flügelschlag-Sound vorliegt).
| |
|
| |
| <swf width="183" height="133">http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs5/butterfly/butterfly_07_character/Butterfly07Butterfly01Flash11.swf</swf>
| |
|
| |
| Um diese Verhalten zu erreichen, wurde in der
| |
| Haupt-Timeline der zugehörigen <code>fla</code>-Datei folgender Code eingefügt
| |
| (da der Movie nur zum Testen der Klasse <code>Butterfly</code>
| |
| dient wurde der Code nicht ausgelagert):
| |
|
| |
| <source lang="actionscript">
| |
| import hsa.tutorial.butterfly.event.ButterflyEvent;
| |
| import hsa.tutorial.butterfly.view.Butterfly;
| |
| import fl.transitions.Tween;
| |
| import fl.transitions.easing.None;
| |
|
| |
| sp_butterfly.addEventListener(ButterflyEvent.CHANGE_BUTTERFLY, o_change);
| |
| sp_butterfly.addEventListener(ButterflyEvent.CHANGE_BUTTERFLY_ANIMATION, o_wings);
| |
|
| |
| function o_change(p_event: ButterflyEvent): void
| |
| {
| |
| sp_label_state.text = sp_butterfly.state;
| |
| }
| |
|
| |
| function o_wings(p_event: ButterflyEvent): void
| |
| {
| |
| sp_label_wings.text = sp_butterfly.stateAnimation;
| |
|
| |
| sp_label_flap.text = (sp_butterfly.stateAnimation == Butterfly.OPEN)
| |
| ? "flip"
| |
| : "flap";
| |
|
| |
| new Tween
| |
| (sp_label_flap, // object to be animated
| |
| "alpha", // animation attribute: "x", "y", "alpha", "rotation", ...
| |
| None.easeNone, // animation type
| |
| 1.0, 0.0, // start and end value (of alpha)
| |
| 15, // Dauer der Animation ...
| |
| false // duration in frames (not in seconds)
| |
| );
| |
| }
| |
| </source>
| |
|
| |
| ===Anmerkung 1===
| |
| Man beachte, dass im Gegensatz
| |
| zu den vorangegangen Tutorien die Labelbezeichnungen nicht
| |
| mehr <code>lbOpen</code>, <code>lbClose</code> und <code>lbFluttering</code>
| |
| lauten, sondern <code>lb_open</code>, <code>lb_close</code> und <code>lb_fluttering</code>.
| |
|
| |
| Gemäß den hier verwendeten [[Multimedia-Programmierung: Konventionen|Namenskonventionen]]
| |
| bedeutet dies, dass von außen nicht mehr direkt auf die Zeitleistenlabels zugegriffen werden soll.
| |
| Sie werden als <code>private</code> angesehen (auch wenn dies in Flash nicht realisierbar ist).
| |
| Das heißt, auf die Labels wird nur noch innerhalb der Klasse <code>Butterlfy</code> zugegrifen
| |
| (konkret: in der Setter-Methode <code>set state</code>).
| |
|
| |
| ===Anmerkung 2===
| |
| Für den Schmetterling wurde eine saubere Schnittstelle definiert (die [[Attribut]]e <code>state</code> und <code>stateAnimation</code>
| |
| sowie die Ereignisse (Events) die vom Schmetterling gemeldet werden).
| |
| Nur über diese Schnittstelle darf von außen auf ein Schmetterlings-Objekt zugegriffen werden.
| |
|
| |
| Wenn man einen Schmetterling
| |
| auf die Bühne legt und ihm den „Instanznamen“ <code>sp_butterfly</code> gibt,
| |
| kann man mit folgenden Befehlen dessen Zustand verändern:
| |
|
| |
| <source lang="actionscript">
| |
| import hsa.tutorial.butterfly.view.Butterfly;
| |
|
| |
| sp_butterfly.state=Butterfly.OPEN;
| |
| sp_butterfly.state=Butterfly.CLOSE;
| |
| sp_butterfly.state=Butterfly.FLUTTERING;
| |
| </source>
| |
|
| |
| Außerdem kann man den aktuellen Zustand des Schmetterling und auch seiner Flügel jederzeit lesen.
| |
| Und man kann sich jederzeit über Zustandsänderungen informieren lassen.
| |
|
| |
| ==Das Schmetterlingssymbol als Spielfigur mit weichen Übergängen==
| |
|
| |
| Einen Nachteil hat die vorangegangene Implementierung noch. Ein Übergang
| |
| von einem Zustand zu einem anderen erfolgt im Allgemeinen ruckartig.
| |
| Wenn man z.B. von CLOSE ind FLUTTERING wechselt, werden die Flügel
| |
| schlagartig geöffnet.
| |
|
| |
| Sowohl im ersten Beispielfilm, als auch im zweiten Beispielsfilm wird zunächst alle 30 Frames und danach kurzeitig viel häufiger der Zustand des Schmetterlings geändert. Man beachte den Unterschied.
| |
|
| |
| <swf width="183" height="133">http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs5/butterfly/butterfly_07_character/Butterfly07ButterflyRoughFlash11.swf</swf><swf width="183" height="133">http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs5/butterfly/butterfly_07_character/Butterfly07ButterflySmoothFlash11.swf</swf>
| |
|
| |
| Um das Problem mit den ruckartigen Zustandsübergängen zu beheben, muss der flatternde Schmetterling regelmäßig melden, wenn seine
| |
| Flügel ganz offen oder geschlossen sind. Außerdem muss es möglich sein, im „Fluttering-Movie“
| |
| sowohl zu dem Frame, an dem die Flügel ganz geöffnet sind, als auch zu dem Frame, an dem die Flügel ganz geschlossen sind, zu springen.
| |
| Dazu sind folgende Änderungen am Symbol <code>Butterfly</code> notwendig:
| |
|
| |
| # In der Zeitleiste, Ebene <code>labels</code>: Labelnamen von Frame 40 in <code>lb_fluttering_open</code> abändern.
| |
| # In der Zeitleiste, Ebene <code>labels</code>: Folgenden Labelnamen in Frame 50 einfügen <code>lb_fluttering_close</code>.
| |
| # In der Zeitleiste, Ebene <code>scripts</code>;
| |
| #; Frame 59: <code>gotoAndPlay("lb_fluttering_open");</code> // an Stelle von <code>gotoAndPlay("lb_fluttering");</code>
| |
|
| |
| Die Implementierung der Setter-Methode <code>set state</code> ist nun allerdings sehr viel aufwändiger.
| |
| Zunächst gibt es sechs Fälle, die berücksichtigt werden müssen. Den Fall dass sich alter
| |
| und neuer Zustand nicht unterscheiden, braucht man (zunächst!) nicht zu betrachten.
| |
|
| |
| Der einfachste Fall ist, dass der Schmetterling sich nicht bewegt und mit dem Flattern beginnen soll:
| |
|
| |
| {| class="toccolours" border="1" cellpadding="4" style="margin: 0 0 1em 1em; font-size: 95%; border-collapse: collapse;"
| |
| |-
| |
| ! Aktueller Zustand !! Neuer Zustand !! Aktion
| |
| |-
| |
| | <code>OPEN</code> || <code>FLUTTERING</code> || <code>gotoAndPlay("lb_fluttering_open")</code> ⇒ der neue Status wird sofort erreicht
| |
| |-
| |
| | <code>CLOSE</code> || <code>FLUTTERING</code> || <code>gotoAndPlay("lb_fluttering_close")</code> ⇒ der neue Status wird sofort erreicht
| |
| |}
| |
|
| |
| In den übrigen vier Fällen muss der Statuswechsel verzögert werden:
| |
|
| |
| {| class="toccolours" border="1" cellpadding="4" style="margin: 0 0 1em 1em; font-size: 95%; border-collapse: collapse;"
| |
| |-
| |
| ! Aktueller Zustand !! Neuer Zustand !! Aktion
| |
| |-
| |
| | <code>OPEN</code> || <code>CLOSE</code> || <code>gotoAndPlay("lb_fluttering_open")</code><br /> Aufruf von <code>m_new_wings_state(CLOSE)</code> ⇒ neuer Status ist erreicht
| |
| |-
| |
| | <code>CLOSE</code> || <code>OPEN</code> || <code>gotoAndPlay("lb_fluttering_close")</code><br /> Aufruf von <code>m_new_wings_state(OPEN)</code> ⇒ neuer Status ist erreicht
| |
| |-
| |
| | <code>FLUTTERING</code> || <code>CLOSE</code> || Aufruf von <code>m_new_wings_state(CLOSE)</code> ⇒ neuer Status ist erreicht
| |
| |-
| |
| | <code>FLUTTERING</code> || <code>OPEN</code> || Aufruf von <code>m_new_wings_state(OPEN)</code> ⇒ neuer Status ist erreicht
| |
| |}
| |
|
| |
| Leider reicht es nicht, diese sechs Fälle zu betrachten. Der Zustand des Schmetterlings kann ja erneut geändert werden,
| |
| während sich dieser bereits in einer verzögerten Zustandsänderung befindet und daher zurzeit flattert.
| |
| (Dies ist ein ganzt typisches Problem bei der Entwicklung von Multimedia-Anwendungen:
| |
| Der Benutzer oder andere Komponenten können zu jeder Zeit Zustandsänderungen veranlassen,
| |
| auch wenn die Anwendung eine andere Aufgabe noch nicht vollständig erledigt hat.)
| |
|
| |
| Folgende zusätzlichen Fälle müssen betrachtet werden:
| |
|
| |
| {| class="toccolours" border="1" cellpadding="4" style="margin: 0 0 1em 1em; font-size: 95%; border-collapse: collapse;"
| |
| |-
| |
| ! Aktueller Zustand !! Neuer Zustand !! Aktion
| |
| |-
| |
| | irgendein Zustand || <code>FLUTTERING</code> || Der Schmetterling hat den neuen Zustand bereits erreicht, da er bereits flattert.<br/> Die verzögerte Zustandsänderung muss(!) unterbrochen werden.
| |
| |-
| |
| | <code>OPEN</code> oder<br/><code>CLOSE</code> || <code>CLOSE</code> || Aufruf von <code>m_new_wings_state(CLOSE)</code> ⇒ neuer Status ist erreicht
| |
| |-
| |
| | <code>OPEN</code> oder<br/><code>CLOSE</code> || <code>OPEN</code> || Aufruf von <code>m_new_wings_state(OPEN)</code> ⇒ neuer Status ist erreicht
| |
| |}
| |
|
| |
| Wenn man die obigen Tabellen in Code umsetzt, ändert sich der Inhalt der
| |
| Datei <code>Butterfly.as</code> wie folgt:
| |
|
| |
| <source lang="actionscript">
| |
| /////////////////////////////////////////////////////////////////////////////////
| |
| // Copyright © 2010 W. Kowarschick
| |
| //
| |
| // Dieses Werk darf unter den Bedingungen der Creative Common Lizenz by-nc 3.0 de
| |
| // (http://creativecommons.org/licenses/by-nc/3.0/de/)
| |
| // vervielfaeltigt, verbreitet, publiziert und modifiziert werden.
| |
| /////////////////////////////////////////////////////////////////////////////////
| |
|
| |
| package hsa.tutorial.butterfly.hsa
| |
| {
| |
| import flash.display.MovieClip;
| |
| import hsa.tutorial.butterfly.event.ButterflyEvent;
| |
|
| |
| public class Butterfly extends MovieClip
| |
| {
| |
| /////////////////////////////////////////////////////////////////////////////
| |
| // Constants
| |
| /////////////////////////////////////////////////////////////////////////////
| |
|
| |
| public static const OPEN: String = "open";
| |
| public static const CLOSE: String = "close";
| |
| public static const FLUTTERING: String = "fluttering";
| |
|
| |
| private static const c_label_prefix: String = "lb_";
| |
| private static const c_label_prefix_fluttering: String = "lb_fluttering_";
| |
|
| |
| /////////////////////////////////////////////////////////////////////////////
| |
| // Instance variables
| |
| /////////////////////////////////////////////////////////////////////////////
| |
|
| |
| // Instance variables of the attributes
| |
| private var v_state: String;
| |
|
| |
| // Auxiliary variable (for being able to perform delayed state changes)
| |
| private var v_next_state: String = null;
| |
|
| |
| /////////////////////////////////////////////////////////////////////////////
| |
| // Private methods
| |
| /////////////////////////////////////////////////////////////////////////////
| |
| | | |
| private function m_set_state(p_state: String): void | | private function m_set_state(p_state: String): void |
| { | | { |
| | trace(v_state + " ===> " + p_state); |
| if (v_state != p_state) | | if (v_state != p_state) |
| { | | { |
| Zeile 582: |
Zeile 104: |
| // Attributes | | // Attributes |
| ///////////////////////////////////////////////////////////////////////////// | | ///////////////////////////////////////////////////////////////////////////// |
| | | |
| /** | | /** |
| * The current state of the butterfly: | | * The current state of the butterfly: |
| Zeile 593: |
Zeile 115: |
| | | |
| public function set state(p_state: String): void | | public function set state(p_state: String): void |
| {
| |
| if (p_state != OPEN && p_state != CLOSE && p_state != FLUTTERING)
| |
| throw (new Error("ButterflySmooth: State '" + p_state + "' is unknown!"));
| |
|
| |
| if (v_next_state == null) // Currently no delayed state change is performed!
| |
| {
| |
| if (p_state == FLUTTERING)
| |
| {
| |
| this.gotoAndPlay( c_label_prefix_fluttering
| |
| + ((v_state == null) ? OPEN : v_state)
| |
| );
| |
| m_set_state(p_state); // Do the state change now!
| |
| }
| |
| else // p_state == OPEN || CLOSE
| |
| {
| |
| if (v_state != FLUTTERING)
| |
| this.gotoAndPlay( c_label_prefix_fluttering
| |
| + ((v_state == null) ? OPEN : v_state)
| |
| );
| |
|
| |
| // Delay the stage change until the wings are in the correct position.
| |
| v_next_state = p_state;
| |
| };
| |
| }
| |
| else // Currently a delayed state change is performed!
| |
| {
| |
| if (p_state == FLUTTERING)
| |
| {
| |
| v_next_state = null; // Stop the delayed state change.
| |
| m_set_state(p_state); // Do the state change now!
| |
| }
| |
| else
| |
| v_next_state = p_state; // Update the delayed state change;
| |
| }
| |
| }
| |
|
| |
| /////////////////////////////////////////////////////////////////////////////
| |
| // Methods called from within the timline (should be private, but cannot)
| |
| /////////////////////////////////////////////////////////////////////////////
| |
|
| |
| public function m_new_wings_state(p_state: String): void
| |
| {
| |
| // If the wings are in the correct position,
| |
| // perform the delayed state change!
| |
| if (v_next_state == p_state)
| |
| {
| |
| this.gotoAndPlay(c_label_prefix + v_next_state);
| |
| m_set_state(v_next_state); // Make up for the state change now!
| |
| v_next_state = null;
| |
| };
| |
| }
| |
|
| |
| /////////////////////////////////////////////////////////////////////////////
| |
| // Constructor
| |
| /////////////////////////////////////////////////////////////////////////////
| |
|
| |
| public function Butterfly(p_state: String = OPEN)
| |
| {
| |
| this.state = p_state;
| |
| }
| |
|
| |
| /////////////////////////////////////////////////////////////////////////////
| |
| // End of class
| |
| /////////////////////////////////////////////////////////////////////////////
| |
| }
| |
| }
| |
| </source>
| |
|
| |
| ===Anmerkung 1===
| |
| Man beachte, dass hier nur eine verbesserte, wenn auch viel aufwändigere Implementierung des Symbols <code>Butterfly</code>
| |
| angegeben wurde. An der zuvor definierten Schnittstellte ändert sich nichts.
| |
| Man kann sich allerdings nicht mehr darauf verlassen, dass die Zustandswechsel
| |
| sofort in dem Moment angezeigt wird, in dem die Setter-Methode <code>set state</code>
| |
| aufgerufen wird.
| |
|
| |
| ==Das Schmetterlingssymbol als Spielfigur mit weichen Übergängen: Vereinfachte Version==
| |
|
| |
| Der Code, der im vorangegangenen Abschnitt erstellt wurde, ist ziemlich umfangreich und schwer zu verstehen.
| |
| Wenn Spielfiguren komplexere Bewegungsabläufe aufweisen, ist es i. Allg. noch schwieriger, einen weichen Übergang von Zustand zu Zustand
| |
| zu realisieren. Beispielsweise dreht sich daher eine Spielfigur eines Jump'n'Run-Spiels so gut wie immer schlagartig um 180 Grad,
| |
| wenn der Benutzer die Bewegungsrichtung ändert.
| |
|
| |
| Die Kompelxität der zuvor definierten <code>Butterfly</code>-Klasse ist vor allem der Tatsache geschuldet,
| |
| dass für jeden Zustand eine eigener Frames-Block definiert wurde. Obwohl dies i.Allg. notwendig ist
| |
| (und daher dieser allgemeine Fall auch im Tutorium demonstriert wurde), soll nicht verschwiegen werden,
| |
| dass es für den Schmetterling eine wesentlich einfache Implementierung gibt, die genau dasselbe Verhalten wie
| |
| zuvor realisiert.
| |
|
| |
| Im dritten Frame-Block sind alle gewünschten Zustände enthalten:
| |
| Flügelschlagender Schmetterling, Schmetterling mit offenen Flügeln und Schmetterling mit geschlossenen Flügeln.
| |
| Dehalb reicht es, den Flügelschlag im richtigen Moment anzuhalten bzw. zu starten, um zwischen den einzelen Zuständen zu wechseln.
| |
| Ein Sprung über mehrer Frames hinweg ist (außer beim Rücksprung auf das erste Bild der Framesequenz) gar nicht notwendig.
| |
|
| |
| Folgende Vereinfachungen müssen zunächst am Schmetterling vorgenommen werden:
| |
|
| |
| # In der Zeitleiste des Symbols <code>Butterfly</code> werden die beiden zuvor eingeführten zusätzlichen Frame-Blöcke wieder entfernt: Die Frames 1 bis 39 in allen vier Ebenen gleichzeitig markieren → Rechtsklick in den markierten Bereich → <code>Bilder entfernen</code>.
| |
| # In der Zeitleiste, Ebene <code>labels</code>: Die Label <code>lb_butterfly_open</code> und <code>lb_butterfly_clos</code> in <code>lb_open</code> und <code>lb_close</code> umbenennen.
| |
| # In der Zeitleiste, Ebene <code>scripts</code>, Frame 21: <code>gotoAndPlay("lb_open");</code> an Stelle von <code>gotoAndPlay("lb_fluttering_open");</code>
| |
|
| |
| Den Code in der Datei <code>Butterfly.as</code> durch folgenden Code ersetzen:
| |
|
| |
| <source lang="actionscript">
| |
| package hsa.tutorial.butterfly.view
| |
| {
| |
| import flash.display.MovieClip;
| |
| import hsa.tutorial.butterfly.event.ButterflyEvent;
| |
|
| |
| public class Butterfly extends MovieClip
| |
| {
| |
| /////////////////////////////////////////////////////////////////////////////
| |
| // Constants
| |
| /////////////////////////////////////////////////////////////////////////////
| |
|
| |
| public static const OPEN: String = "open";
| |
| public static const CLOSE: String = "close";
| |
| public static const FLUTTERING: String = "fluttering";
| |
|
| |
| /////////////////////////////////////////////////////////////////////////////
| |
| // Instance variables
| |
| /////////////////////////////////////////////////////////////////////////////
| |
|
| |
| // Instance variables of the attributes
| |
| private var v_state: String;
| |
|
| |
| // Auxiliary variable (for being able to perform delayed state changes)
| |
| private var v_stop_state: String = null;
| |
|
| |
| /////////////////////////////////////////////////////////////////////////////
| |
| // Private methods
| |
| /////////////////////////////////////////////////////////////////////////////
| |
|
| |
| private function m_set_state(p_state: String): void
| |
| { | | { |
| if (v_state != p_state) | | trace(v_state + " ---> " + p_state); |
| {
| |
| v_state = p_state;
| |
| this.dispatchEvent(new ButterflyEvent());
| |
| }
| |
| }
| |
|
| |
| ////////////////////////////////////////////////////////////////////////////
| |
| // Attributes
| |
| /////////////////////////////////////////////////////////////////////////////
| |
|
| |
|
| public function get state(): String
| |
| {
| |
| return v_state;
| |
| }
| |
|
| |
| public function set state(p_state: String): void
| |
| {
| |
| if (p_state == FLUTTERING) | | if (p_state == FLUTTERING) |
| { | | { |
| Zeile 759: |
Zeile 133: |
| } | | } |
| | | |
| ///////////////////////////////////////////////////////////////////////////// | | /** |
| // Methods called from within the timline (should be private, but cannot)
| | * The current state of the wings: |
| /////////////////////////////////////////////////////////////////////////////
| | * <code>OPEN</code> or <code>CLOSE</code>. |
|
| | */ |
| public function m_new_wings_state(p_state: String): void | | public function get stateAnimation(): String |
| { | | { |
| // If the wings are to be stoped, stop them. | | return v_state_animation; |
| if (v_stop_state == p_state)
| |
| {
| |
| this.stop();
| |
| v_stop_state = null;
| |
| m_set_state(p_state); // Do the state change now!
| |
| };
| |
| } | | } |
|
| | |
| ///////////////////////////////////////////////////////////////////////////// | | ///////////////////////////////////////////////////////////////////////////// |
| // Constructor | | // Constructor |
| Zeile 780: |
Zeile 148: |
| public function Butterfly(p_state: String = OPEN) | | public function Butterfly(p_state: String = OPEN) |
| { | | { |
| this.state = p_state;
| | this.state = p_state; |
| } | | } |
| | | |
| ///////////////////////////////////////////////////////////////////////////// | | ///////////////////////////////////////////////////////////////////////////// |
| // End of class | | // End of class |
| Zeile 790: |
Zeile 158: |
| </source> | | </source> |
|
| |
|
| ===Anmerkung 1=== | | ===Anmerkung=== |
|
| |
|
| Beachten Sie, dass der Code viel kürzer, einfacher und verständlicher ist, als im vorangegangen Beispiel. | | Beachten Sie, dass der Code der Setter-Methode <code>set state</code> kürzer, |
| | einfacher, verständlicher und damit auch leichter zu verifizieren ist, |
| | als im vorangegangen Beispiel. |
|
| |
|
| TBD
| | Das bedeutet: Nicht immer bringt ein Standardvorgehen auch eine optimale Lösung. Manchmal |
| | ist es daher gar nicht schlecht, über eine Lösung noch einmal nachzudenken. |
|
| |
|
| <swf width="183" height="133">http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs5/butterfly/butterfly_07_character/Butterfly07ButterflySimplifiedFlash11.swf</swf>
| |
|
| |
| ==Der Schmetterlings-Movie als Spielfigur==
| |
|
| |
| =Probleme der Implementierung=
| |
|
| |
| =Quellen= | | =Quellen= |
| <noinclude> | | <noinclude> |
| * [[Kowarschick, W.: Multimedia-Programmierung]]</noinclude> | | * [[Kowarschick, W.: Multimedia-Programmierung]]</noinclude> |
| * [http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs5/butterfly/butterfly_07_character/ Musterlösung (Flash CS5)] | | * [http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs5/butterfly/butterfly_07c_character/ Musterlösung (Flash CS5)] |
| * [http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs4/butterfly/butterfly_07_character/ Musterlösung (Flash CS4)] | | * [http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs4/butterfly/butterfly_07c_character/ Musterlösung (Flash CS4)] |
| * [http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs5/butterfly/butterfly_07_character_multi/ Erweiterte Musterlösung (Flash CS4)] | | * [http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs5/butterfly/butterfly_07c_character_multi/ Erweiterte Musterlösung (Flash CS4)] |
| * [http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs4/butterfly/butterfly_07_character_multi/ Erweiterte Musterlösung (Flash CS5)] | | * [http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs4/butterfly/butterfly_07c_character_multi/ Erweiterte Musterlösung (Flash CS5)] |
|
| |
|
| == [[Subversion/HowTo|SVN]]-Repository-Verweise == | | == [[Subversion/HowTo|SVN]]-Repository-Verweise == |
| * [http://glossar.hs-augsburg.de/webdav/tutorium/flash_cs5/butterfly/butterfly_07_character/ Musterlösung (Flash CS5)] | | * [http://glossar.hs-augsburg.de/webdav/tutorium/flash_cs5/butterfly/butterfly_07c_character/ Musterlösung (Flash CS5)] |
| * [http://glossar.hs-augsburg.de/webdav/tutorium/flash_cs4/butterfly/butterfly_07_character/ Musterlösung (Flash CS4)] | | * [http://glossar.hs-augsburg.de/webdav/tutorium/flash_cs4/butterfly/butterfly_07c_character/ Musterlösung (Flash CS4)] |
| * [http://glossar.hs-augsburg.de/webdav/tutorium/flash_cs5/butterfly/butterfly_07_character_multi/ Erweiterte Musterlösung (Flash CS4)] | | * [http://glossar.hs-augsburg.de/webdav/tutorium/flash_cs5/butterfly/butterfly_07c_character_multi/ Erweiterte Musterlösung (Flash CS4)] |
| * [http://glossar.hs-augsburg.de/webdav/tutorium/flash_cs4/butterfly/butterfly_07_character_multi/ Erweiterte Musterlösung (Flash CS5)]<noinclude>[[Kategorie: AS3-Tutorium: Flash: Butterfly]][[Kategorie: Flash-Beispiel]][[Kategorie:Kapitel:Multimedia-Programmierung:Beispiele]] | | * [http://glossar.hs-augsburg.de/webdav/tutorium/flash_cs4/butterfly/butterfly_07c_character_multi/ Erweiterte Musterlösung (Flash CS5)]<noinclude>[[Kategorie: AS3-Tutorium: Flash: Butterfly]][[Kategorie: Flash-Beispiel]][[Kategorie:Kapitel:Multimedia-Programmierung:Beispiele]] |
| {{{{SITENAME}}-konformer Artikel}} | | {{{{SITENAME}}-konformer Artikel}} |
| </noinclude> | | </noinclude> |