AS3-Tutorium: Flash: Butterfly 07b character
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
Das Schmetterlingssymbol als Spielfigur mit weichen Übergängen
<swf width="367" height="267">http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs5/butterfly/butterfly_07b_character/Butterfly07bFlash11.swf</swf> Musterlösung (Flash CS5) (SVN-Repository)
Musterlösung (Flash CS4) (SVN-Repository)
Einen Nachteil hat die im Teil 7a angegebene Implementierung des Schmetterlingssymbols 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.
In beiden folgenden Filmen (links: Lösung gemäß Teil 7a, rechts: Lösung gemäß Teil 7b) 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_07a_character/Butterfly07aProblemFlash11.swf</swf> | <swf width="183" height="133">http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs5/butterfly/butterfly_07b_character/Butterfly07bFlash11.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 Butterfly
notwendig:
- In der Zeitleiste, Ebene
labels
: Labelnamen von Frame 40 inlb_fluttering_open
abändern. - In der Zeitleiste, Ebene
labels
: Folgenden Labelnamen in Frame 50 einfügenlb_fluttering_close
. - In der Zeitleiste, Ebene
scripts
;- Frame 59
gotoAndPlay("lb_fluttering_open");
// an Stelle vongotoAndPlay("lb_fluttering");
Die Implementierung der Setter-Methode set state
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:
Aktueller Zustand | Neuer Zustand | Aktion |
---|---|---|
OPEN |
FLUTTERING |
gotoAndPlay("lb_fluttering_open") ⇒ der neue Status wird sofort erreicht
|
CLOSE |
FLUTTERING |
gotoAndPlay("lb_fluttering_close") ⇒ der neue Status wird sofort erreicht
|
In den übrigen vier Fällen muss der Statuswechsel verzögert werden:
Aktueller Zustand | Neuer Zustand | Aktion |
---|---|---|
OPEN |
CLOSE |
gotoAndPlay("lb_fluttering_open") Aufruf von m_new_wings_state(CLOSE) ⇒ neuer Status ist erreicht
|
CLOSE |
OPEN |
gotoAndPlay("lb_fluttering_close") Aufruf von m_new_wings_state(OPEN) ⇒ neuer Status ist erreicht
|
FLUTTERING |
CLOSE |
Aufruf von m_new_wings_state(CLOSE) ⇒ neuer Status ist erreicht
|
FLUTTERING |
OPEN |
Aufruf von m_new_wings_state(OPEN) ⇒ 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:
Aktueller Zustand | Neuer Zustand | Aktion |
---|---|---|
irgendein Zustand | FLUTTERING |
Der Schmetterling hat den neuen Zustand bereits erreicht, da er bereits flattert. Die verzögerte Zustandsänderung muss(!) unterbrochen werden. |
OPEN oderCLOSE |
CLOSE |
Aufruf von m_new_wings_state(CLOSE) ⇒ neuer Status ist erreicht
|
OPEN oderCLOSE |
OPEN |
Aufruf von m_new_wings_state(OPEN) ⇒ neuer Status ist erreicht
|
Wenn man die obigen Tabellen in Code umsetzt, ändert sich der Inhalt der
Datei Butterfly.as
wie folgt:
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";
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;
private var v_state_animation: String;
// Auxiliary variable (for being able to perform delayed state changes)
private var v_next_state: String = null;
/////////////////////////////////////////////////////////////////////////////
// Private methods
/////////////////////////////////////////////////////////////////////////////
// Should be private, but cannot as it is accessed from within the timeline!
public function m_new_wings_state(p_state: String): void
{
if (p_state != v_state_animation)
{
v_state_animation = p_state;
// The state of the wings has changed. Inform the observers!
this.dispatchEvent
(new ButterflyEvent(ButterflyEvent.CHANGE_BUTTERFLY_ANIMATION));
};
// 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;
};
}
private function m_set_state(p_state: String): void
{
trace(v_state + " ===> " + p_state);
if (v_state != p_state)
{
v_state = p_state;
this.dispatchEvent(new ButterflyEvent());
}
}
////////////////////////////////////////////////////////////////////////////
// Attributes
/////////////////////////////////////////////////////////////////////////////
/**
* The current state of the butterfly:
* <code>OPEN</code>, <code>CLOSE</code> or <code>BUTTERFLY</code>.
*/
public function get state(): String
{
return v_state;
}
public function set state(p_state: String): void
{
trace(v_state + " ---> " + p_state);
if (p_state != OPEN && p_state != CLOSE && p_state != FLUTTERING)
throw (new Error("Butterfly: State '" + p_state + "' is unknown!"));
if (v_next_state == null) // Currently no delayed state change is performed!
{
if (v_state != FLUTTERING)
this.gotoAndPlay( c_label_prefix_fluttering
+ ((v_state == null) ? OPEN : v_state)
);
if (p_state == FLUTTERING)
m_set_state(p_state); // Do the state change now!
else // p_state == OPEN || CLOSE
v_next_state = p_state; // Delay the stage change.
}
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;
}
}
/**
* The current state of the wings:
* <code>OPEN</code> or <code>CLOSE</code>.
*/
public function get stateAnimation(): String
{
return v_state_animation;
}
/////////////////////////////////////////////////////////////////////////////
// Constructor
/////////////////////////////////////////////////////////////////////////////
public function Butterfly(p_state: String = OPEN)
{
this.state = p_state;
}
/////////////////////////////////////////////////////////////////////////////
// End of class
/////////////////////////////////////////////////////////////////////////////
}
}
Anmerkung
Man beachte, dass hier nur eine verbesserte, wenn auch viel aufwändigere Implementierung des Symbols Butterfly
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 set state
aufgerufen wird.
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)