AS3-Tutorium: Flash: Butterfly 07a character: Unterschied zwischen den Versionen
Kowa (Diskussion | Beiträge) |
Kowa (Diskussion | Beiträge) |
||
| Zeile 28: | Zeile 28: | ||
==Das Schmetterlingssymbol als Spielfigur== | ==Das Schmetterlingssymbol als Spielfigur== | ||
Die Grundidee ist folgende: Für jeden Zustand der Spielfigur wird im Movie Clip ein Abschnitt definiert. | 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 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: | Das letzte Frame eines jeden Abschnittes wird mit einem ActionScript-Befehl versehen: | ||
* <code>stop();</code>, falls | * <code>stop();</code>, falls die dem Zustand zugeordnete Animation nur einmal abgespielt werden soll | ||
* <code>gotoAndPlay(lb_</code>'''<code>x</code>'''<code>);</code>, falls | * <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. | Zunächst wird das Schmetterlingssymbol auf diese Weise umgestaltet. | ||
| Zeile 38: | Zeile 40: | ||
# In der Bibliothek: Das Symbol <code>Butterfly</code> mit einem Doppelklick öffnen. | # In der Bibliothek: Das Symbol <code>Butterfly</code> mit einem Doppelklick öffnen. | ||
# In der Zeitleiste: Zwei neue Ebenen (ganz oben) einfügen: | # In der Zeitleiste: Zwei neue Ebenen (ganz oben) einfügen: | ||
# * <code>scripts</code> | #* <code>scripts</code> | ||
# * <code>labels</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: 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>: 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. | ||
| Zeile 130: | Zeile 132: | ||
Gemäß den hier verwendeten [[Multimedia-Programmierung: Konventionen|Namenskonventionen]] | Gemäß den hier verwendeten [[Multimedia-Programmierung: Konventionen|Namenskonventionen]] | ||
bedeutet dies, dass von außen nicht mehr direkt auf die Zeitleistenlabels zugegriffen werden soll. | 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 | 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 | Das heißt, auf die Labels wird nur noch innerhalb der Klasse <code>Butterlfy</code> zugegrifen | ||
(konkret: in der Setter-Methode <code> | (konkret: in der Setter-Methode <code>set state</code>). | ||
===Anmerkung 2=== | ===Anmerkung 2=== | ||
| Zeile 151: | Zeile 153: | ||
===Anmerkung 3=== | ===Anmerkung 3=== | ||
Bei jeder Zustandsänderung informiert das Schmetterlings-Objekt alle [[Observer- | Bei jeder Zustandsänderung informiert das Schmetterlings-Objekt alle [[Observer-Pattern|Observer]] (bzw in ActionScript: Listener) | ||
mit Hilfe des Befehls | mit Hilfe des Befehls | ||
<source lang="actionscript"> | <source lang="actionscript"> | ||
| Zeile 158: | Zeile 160: | ||
über die erfolgte Zustandsänderung. Dies wird z.B. im nachfolgenden Beispiel ausgenutzt, | über die erfolgte Zustandsänderung. Dies wird z.B. im nachfolgenden Beispiel ausgenutzt, | ||
um den aktuellen Zustand anzeigen zu können. Hierzu wurde in der | um den aktuellen Zustand anzeigen zu können. Hierzu wurde in der | ||
Haupt-Timeline (da der Movie nur zum Testen der Klasse <code>Butterfly</code> dient) | Haupt-Timeline folgender Code eingefügt (da der Movie nur zum Testen der Klasse <code>Butterfly</code> dient wurde der Code nicht ausgelagert): | ||
<source lang="actionscript"> | <source lang="actionscript"> | ||
Version vom 18. November 2010, 09:12 Uhr
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
Dieser Artikel wird derzeit von einem Autor gründlich bearbeitet. Die Inhalte sind daher evtl. noch inkonsistent.
Weiterentwicklung der sechsten Version des Schmetterling-Movies
In AS3-Tutorium: Flash: Butterfly 06 external code wurde der Code aus den Zeitleisten des Hauptmoivies sowie der Symbole weitestgehend in Klassen ausgelagert.
Allerdings wurde bei der Implementierung bislang nicht das Prinzip Separation of Concerns (siehe auch Programmierprinzipien) beachtet.
Um dies zu erreichen, werden in einem ersten Schritt
die Symbole Butterfly und ButterflyMovie in „Spielfiguren“ (characters) umgewandelt.
Eine Spielfigur kann verschiedene Zustände einnehmen, wie z.B. „stehen“, „laufen nach links“, „laufen nach rechts“, „hüpfen“ etc. 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. 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 Butterfly in eine Spielfigur (im zuvor beschrieben Sinn) umgewandelt, um das Grundprinzip klar zu machen.
Danach wird das Symbol ButterflyMovie in eine „Figur“ umgewandelt. Hierbei wird insbesondere die Progammlogik (fliegen einer via roundsToFly vorgegebenen Anzahl von Runden)
aus der Klasse ButterflyMovie in die Hauptklasse Main verlagert.
<swf width="367" height="267">http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs5/butterfly/butterfly_07_character/Butterfly07Flash11.swf</swf>
Musterlösung (Flash CS5)
(SVN-Repository)
Musterlösung (Flash CS4) (SVN-Repository)
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. lb_x, wobei x durch den aktuellen Zustand ersetzt wird).
Das letzte Frame eines jeden Abschnittes wird mit einem ActionScript-Befehl versehen:
stop();, falls die dem Zustand zugeordnete Animation nur einmal abgespielt werden sollgotoAndPlay(lb_x);, falls die dem Zustand zugeordnete Animation dauerhaft abgespielt werden soll
Zunächst wird das Schmetterlingssymbol auf diese Weise umgestaltet.
- In der Bibliothek: Das Symbol
Butterflymit einem Doppelklick öffnen. - In der Zeitleiste: Zwei neue Ebenen (ganz oben) einfügen:
scriptslabels
- 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
body: Klick auf das Schlüsselbild bei Frame 40 →Alt-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
body: Das Schlüssenbild bei Frame 40 entfernen: Klick auf das Schlüsselbild → Rechtsklick auf das Schlüsselbild →Schlüsselbild löschen. - In der Zeitleiste, Ebene
wings: Klick auf Frame 20 → Rechtsklick auf Frame 20 →Schlüsselbild einfügen. - In der Zeitleiste, Ebene
wings:Strg/Ctrl-Taste drücken und festhalten → Klick auf das Schlüsselbild bei Frame 40 → Rechtsklick auf das Schlüsselbild →Bilder kopieren. - In der Zeitleiste, Ebene
wings: Klick auf Frame 1 → Rechtsklick auf Frame 1 →Bilder einfügen(nichtBild einfügen!!). - In der Zeitleiste, Ebene
wings:Strg/Ctrl-Taste drücken und festhalten → Klick auf das Schlüsselbild bei Frame 50 → Rechtsklick auf das Schlüsselbild →Bilder kopieren. - In der Zeitleiste, Ebene
wings: Klick auf Frame 20 → Rechtsklick auf Frame 20 →Bilder einfügen(nichtBild einfügen!!). - In der Zeitleiste, Ebene
labels: Klick auf Frame 1 → Eigenschaften-Fenster öffnen → Name:lb_opened - In der Zeitleiste, Ebene
labels: Klick auf Frame 20 → Rechtsklick auf Frame 20 →Schlüsselbild einfügen→ Eigenschaften-Fenster, Name:lb_closed - In der Zeitleiste, Ebene
labels: Klick auf Frame 40 → Eigenschaften-Fenster, Name:lb_fluttering - In der Zeitleiste, Ebene
scriptsfolgenden Code eintragen (Schlüsselbilder nicht vergessen!):- Frame 10
stop();- Frame 39
stop();- Frame 59
gotoAndPlay("lb_fluttering");
Als nächstes wird der Code zur Steuerung des Zustandswechsels dem Schmetterlings-Symbol zugeordnet:
- Im Menü:
Datei→Neu→ActionScript 3.0-Klasse(CS5) bzw.ActionScript-Datei(CS4 und früher) →OK
Nur in CS5: -> Klassenname:Butterfly→OK - Im Menü:
Datei→Datei speichern unter→ Im Ordner derfla-Datei folgende Unterordner anlegen:hsa/tutorial/butterfly→ Datei unter dem NamenButterfly.asim zuvor angelegten Unterordner speichern. - In der Bilbliothek: Rechtsklick auf das Symbol
Butterfly→Eigenschaften→ falls notwendig: Klick auf Dreieck hinterErweitert→ Häckchen vorExport für ActionScript→ Klasse:hsa.tutorial.butterfly.ButterflyBlue(oder eine andere Farbe), Basisklassehsa.tutorial.butterfly.Butterfly→OK→OK
Nun kann in die Datei Butterfly.as folgendener Code einfügt werden:
package hsa.tutorial.butterfly
{
import flash.display.MovieClip;
public class Butterfly extends MovieClip
{
/////////////////////////////////////////////////////////////////////////////
// Constants
/////////////////////////////////////////////////////////////////////////////
public static const OPENED: String = "opened";
public static const CLOSED: String = "closed";
public static const FLUTTERING: String = "fluttering";
/////////////////////////////////////////////////////////////////////////////
// Instance variables
/////////////////////////////////////////////////////////////////////////////
private var v_state: String;
////////////////////////////////////////////////////////////////////////////
// Attributes
/////////////////////////////////////////////////////////////////////////////
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);
v_state = p_state;
dispatchEvent(new Event(Event.CHANGE));
};
}
/////////////////////////////////////////////////////////////////////////////
// Constructor
/////////////////////////////////////////////////////////////////////////////
public function Butterfly(p_state: String = OPENED)
{
this.state = p_state;
}
/////////////////////////////////////////////////////////////////////////////
// End of class
/////////////////////////////////////////////////////////////////////////////
}
}
Anmerkung 1
Man beachte, dass im Gegensatz
zu den vorangegangen Tutorien die Labelbezeichnungen nicht
mehr lbOpened, lbClosed und lbFluttering
lauten, sondern lb_opened, lb_closed und lb_fluttering.
Gemäß den hier verwendeten Namenskonventionen
bedeutet dies, dass von außen nicht mehr direkt auf die Zeitleistenlabels zugegriffen werden soll.
Sie werden als private angesehen (auch wenn dies in Flash nicht realisierbar ist).
Das heißt, auf die Labels wird nur noch innerhalb der Klasse Butterlfy zugegrifen
(konkret: in der Setter-Methode set state).
Anmerkung 2
Für den Schmetterling wurde eine saubere Schnittstelle definiert (das Attribut state).
Nur über diese Schnittstelle soll von außen auf das Objekt zugegriffen werden.
Wenn man einen Schmetterling
auf die Bühne legt und ihm den „Instanznamen“ sp_butterfly gibt,
kann man mit folgenden Befehlen dessen Zustand verändern:
import hsa.tutorial.butterfly.*;
sp_butterfly.state=Butterfly.OPENED;
sp_butterfly.state=Butterfly.CLOSED;
sp_butterfly.state=Butterfly.FLUTTERING;
Anmerkung 3
Bei jeder Zustandsänderung informiert das Schmetterlings-Objekt alle Observer (bzw in ActionScript: Listener) mit Hilfe des Befehls
dispatchEvent(new Event(Event.CHANGE));
über die erfolgte Zustandsänderung. Dies wird z.B. im nachfolgenden Beispiel ausgenutzt,
um den aktuellen Zustand anzeigen zu können. Hierzu wurde in der
Haupt-Timeline folgender Code eingefügt (da der Movie nur zum Testen der Klasse Butterfly dient wurde der Code nicht ausgelagert):
// sp_butterfly ist der Schmettrling auf der Bühne.
sp_butterfly.addEventListener(Event.CHANGE, o_change);
function o_change(p_event: Event): void
{
// sp_label_state ist ein Textfeld auf der Bühne.
sp_label_state.text = sp_butterfly.state;
}
<swf width="183" height="133">http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs5/butterfly/butterfly_07_character/Butterfly07ButterflyRoughFlash11.swf</swf>
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 CLOSED ind FLUTTERING wechselt, werden die Flügel schlagartig geöffnet.
Sowohl beim vorangegangenen Beispielfilm, als auch bei nachfolgenden Beispielsfilm wird alle 30 Frames 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/Butterfly07ButterflySmoothFlash11.swf</swf>
Um das Problem 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_openedabändern. - In der Zeitleiste, Ebene
labels: Folgenden Labelnamen in Frame 50 einfügenlb_fluttering_closed. - In der Zeitleiste, Ebene
scriptsfolgenden zusätzlichen Code eintragen (Schlüsselbilder nicht vergessen!):- Frame 40
m_new_wings_state(OPENED);- Frame 50
m_new_wings_state(CLOSED);
Der Code in der Datei Butterfly.as wird durch folgendenden Code ersetzt:
package hsa.tutorial.butterfly
{
import flash.display.MovieClip;
import flash.events.Event;
public class Butterfly extends MovieClip
{
/////////////////////////////////////////////////////////////////////////////
// Constants
/////////////////////////////////////////////////////////////////////////////
public static const OPENED: String = "opened";
public static const CLOSED: String = "closed";
public static const FLUTTERING: String = "fluttering";
/////////////////////////////////////////////////////////////////////////////
// Instance variables
/////////////////////////////////////////////////////////////////////////////
private var v_state: String;
private var v_next_state: String = null;
////////////////////////////////////////////////////////////////////////////
// Attributes
/////////////////////////////////////////////////////////////////////////////
public function get state(): String
{
return v_state;
}
public function set state(p_state: String): void
{
if (p_state != OPENED && p_state != CLOSED && p_state != FLUTTERING)
throw (new Error("Butterfly: State '" + p_state + "' is unknown!"));
if (p_state != v_state)
{
if (v_state == FLUTTERING) // p_state == OPENED || CLOSED
{
// Delay the state change until the wings are in the correct position.
v_next_state = p_state;
}
else // v_state == OPENED || CLOSED
{
if (p_state == FLUTTERING)
{
// Jump to the corret position of the fluttering movie.
this.gotoAndPlay("lb_" + p_state + "_" + v_state);
v_state = p_state;
dispatchEvent(new Event(Event.CHANGE));
}
else // v_state == OPENED | CLOSED, p_state = CLOSED || OPENED
{
// Flutter until the correct position of the wings is reached.
v_next_state = p_state;
this.gotoAndPlay("lb_fluttering_" + v_state);
};
};
};
}
/////////////////////////////////////////////////////////////////////////////
// Constructor
/////////////////////////////////////////////////////////////////////////////
public function Butterfly(p_state: String = OPENED)
{
v_state = p_state;
this.gotoAndPlay(v_state);
dispatchEvent(new Event(Event.CHANGE));
}
/////////////////////////////////////////////////////////////////////////////
// Methods called from within the timline (should be private, but cannot)
/////////////////////////////////////////////////////////////////////////////
public function m_new_wings_state(p_state: String): void
{
if (v_next_state == p_state)
{
// As now the wings are in the correct position:
// Perform the delayed state change now!
v_state = v_next_state;
v_next_state = null;
this.gotoAndPlay("lb_" + v_state);
dispatchEvent(new Event(Event.CHANGE));
};
}
/////////////////////////////////////////////////////////////////////////////
// End of class
/////////////////////////////////////////////////////////////////////////////
}
}
Anmerkung
Man beachte, dass hier nur eine verbesserte 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.
Dennoch ist die Implementierung deutlich aufwändiger, da in vielen Fällen der Zustandswechsel verzögert werden muss.
Der Schmetterlings-Movie als Spielfigur
Probleme der Implementierung
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)
