AS3-Tutorium: Flash: Butterfly 05 external code: Unterschied zwischen den Versionen
Kowa (Diskussion | Beiträge) |
Kowa (Diskussion | Beiträge) |
||
| Zeile 130: | Zeile 130: | ||
Bei Filmstart soll der Fokus auf das Eingabe-Feld gesetzt werden (ein blauer Rahmen wird um das Eingabe-Feld gezeichnet und Tastatureingabe werden direkt in dieses Feld geschrieben, siehe die erweiterte Musterlösung): | Bei Filmstart soll der Fokus auf das Eingabe-Feld gesetzt werden (ein blauer Rahmen wird um das Eingabe-Feld gezeichnet und Tastatureingabe werden direkt in dieses Feld geschrieben, siehe die erweiterte Musterlösung): | ||
<source lang="actionscript"> | <source lang="actionscript">mc_user_input.mc_input_rounds.setFocus();</source> | ||
mc_user_input.mc_input_rounds.setFocus(); | |||
</source> | |||
Leider greift die Methode <code>setFocus</code> auf die Bühne zu. | Leider greift die Methode <code>setFocus</code> auf die Bühne zu. | ||
Version vom 26. Oktober 2010, 14:16 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
Verbesserung der vierten Version des Schmetterling-Movies
In AS3-Tutorium: Flash: Butterfly 04 variable number of rounds wurde ein Schmetterling erzeugt, der eine vom Benutzer vorgegebene Anzahl von Runden auf einem Rundkurs fliegt bevor er die Bühne verlässt.
Das Verhalten des Schmetterlings wird nicht verändert. Allerdings wird der Code von der Hauptbühne in eines externe Klasse ausgelagert.
<swf width="367" height="267">http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs5/butterfly/butterfly_05_external_code/butterfly_05_external_code.swf</swf> Musterlösung: butterfly_05_external_code.swf
Der Code des Hauptmovies wird ausgelagert
- Klick auf
Szene 1in der linken oberen Ecke der Bühne → Die Hauptbühne wird geöffnet. - Die Ebene
scriptslöschen. (Der hier enthaltene Code wird in die DateiMain.asausgelagert.) - Klick auf den grauen Hintergrund außerhalb der Bühne → Alle Objekte auf der Bühne werden deselektiert.
- Im Fenster
Eigenschaften: Im EigabefeldKlasseden KlassenamenMaineintragen (erster Buchstabe groß, keine Endung.as!). Datei→Neu→ActionScript 3.0-Klasse→OK-> Klassenname:MainDatei→Datei speichern unter→Main.as(im selben Ordner wie die zugehörigefla-Datei.)
In die Datei Main.as wird folgender Code eingefügt:
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
public class Main extends MovieClip
{
/////////////////////////////////////////////////////////////////////////////
// MovieClips on the stage
/////////////////////////////////////////////////////////////////////////////
public var mc_user_input: MovieClip;
public var mc_butterfly: MovieClip;
/////////////////////////////////////////////////////////////////////////////
// Constructor
/////////////////////////////////////////////////////////////////////////////
public function Main()
{
mc_user_input.mc_button_start.addEventListener(MouseEvent.CLICK, o_start);
}
/////////////////////////////////////////////////////////////////////////////
// Observer methods
/////////////////////////////////////////////////////////////////////////////
private function o_start(p_event: MouseEvent): void
{
mc_user_input.visible = false;
var l_rounds_to_fly: Number = parseInt(mc_user_input.mc_input_rounds.text);
if (isNaN(l_rounds_to_fly) || l_rounds_to_fly < 0)
l_rounds_to_fly = 0;
mc_butterfly.roundsToFly = l_rounds_to_fly;
mc_butterfly.gotoAndPlay("lbStart");
}
/////////////////////////////////////////////////////////////////////////////
// End of class
/////////////////////////////////////////////////////////////////////////////
}
}
Eine Flash-Klasse ist immer in einem package enhalten. Wenn die
Klasse im selben Ordner wie der Flash-Film gespeichert wird, gibt es keinen
Package-Namen. Wird dagegen die Datei beispielsweise in einem Unterordner
main eines Unterordners example gespeichert, so
lautet der Package-Name example.main:
package example.main
{
...
}
Jede Klassen-Datei muss genau eine öffentliche Klasse (public)
mit dem Namen der Datei (ohne Endung .as) enthalten. Weitere
interne Klassen können in der Datei enthalten sein, aber keine weitere
öffentlich zugängliche Klasse.
Wie in Java steht vor der Klasse eine Liste import-Anweisungen,
die den direkten Zugriff auf andere Klassen im Code ermöglicht. In der
Flash-Zeitleiste müssen im Prinzip dieselben import-Anweisungen
vorhanden sein. Allerdings werde in der Flash-Zeitleiste einige Standard-Klassen-Pakete
defaultmäßig importiert, so dass eine Angabe von import-Anweisungen
in diesem Fall unterbleiben kann. In eine Flash-Klasse dagegen müssen stets alle notwendigen
import-Anweisungen angegeben werden.
Die Objekte, die auf der Bühne liegen und einen Objektnamen erhalten haben, sollten
in der Klasse als öffentliche public Zustandsvariablen (instance variables)
deklariert werden. Sie werden von Flash automatisch initialisiert.
Man könnte auf die Deklaration diese Variablen verzichten, erhält damit aber Code der schwerer zu lesen ist. Falls man den Code nicht mit Flash, sondern mit dem Flash Builder bearbeitet, würde man außerdem Fehlermeldungen erhalten, sobald man im Code auf diese Objekte zugreift.
Der eigentlich Code aus der Zeitleiste des ursprünglichen Movies wird in zwei Teile geteilt:
- Im Konstruktor
public function Main()wird derjenige Code eigefügt, der in der Zeitleiste direkt ausgeführt wird. - Hinter den Konstruktor werden alle Methoden eingefügt, die in der Zeiltleiste definiert wurden. Diese Methoden werden i. Allg. als
privatemarkiert, da der Zugriff auf diese Methoden i. Allg. nur innerhalb der Klasse erfolgt.
Im Code können und sollten Kommentare eingefügt werden (siehe ASDoc).
Das Problem mit der nicht-existierenden Bühne
Ein Problem existiert jedoch noch. Wenn in der Zeitleiste Befehle ausgeführt werden,
die direkt auf die Bühne (stage) zugreifen, können diese nicht einfach in den Konstruktor übernommen werden,
da zum Zeitpunkt der Konstruktion des zugehörigen Objekte die Bühnen nicht nicht existiert.
Man erhält für derartige Befehle beim Starten des Filmes Null-Pointer-Exceptions.
In der Zeitleiste passieren derartige Fehler nicht, da der Code im ersten Frame erst ausgeführt wird, wenn die Bühne bereits existiert.
In Flex gibt es ein spezielles Ereignis APPLICATION_COMPLETE, sobald die Bühne erzeugt wurde.
In Flash gibt es ein derartiges EReignis leider nicht. Man kann sich allerdings behelfen,
indem man das Ereignis ENTER_FRAME abfängt. Sobald der erste Frame des Movies betreten
wird existiert die Bühne bereits.
Beispiel
<swf width="367" height="267">http://glossar.hs-augsburg.de/beispiel/tutorium/flash_cs5/butterfly/butterfly_05_external_code/multi/butterfly_05_external_code_multi.swf</swf> Erweiterte Musterlösung: butterfly_05_external_code_multi.swf
Bei Filmstart soll der Fokus auf das Eingabe-Feld gesetzt werden (ein blauer Rahmen wird um das Eingabe-Feld gezeichnet und Tastatureingabe werden direkt in dieses Feld geschrieben, siehe die erweiterte Musterlösung):
mc_user_input.mc_input_rounds.setFocus();
Leider greift die Methode setFocus auf die Bühne zu.
Der folgende Konstruktor erzeugt also eine Null-Pointer-Exception.
package example.main
...
public function Main()
{
mc_user_input.mc_button_start.addEventListener(MouseEvent.CLICK, o_start);
}
...
Das Problem lässt sich lösen, indem man die Initialisierung erst beim Betreten des ersten Frames durchführt.
package example.main
...
public function Main()
{
// Wenn das Ereignis ENTER_FRAME eintritt, rufe o_init auf
this.addEventListener(Event.ENTER_FRAME, o_init);
}
/////////////////////////////////////////////////////////////////////////////
// Observer methods
/////////////////////////////////////////////////////////////////////////////
private function o_init(p_event: Event): void
{
// Da die Initialisierung nur im ersten Frame erfolgen soll,
// muss der Event-Listener gleich wieder entfernt werden.
this.removeEventListener(Event.ENTER_FRAME, o_init);
// Nun existiert die Bühne!
mc_user_input.mc_input_rounds.setFocus();
mc_user_input.mc_button_start.addEventListener(MouseEvent.CLICK, o_start);
}
...
Quellen
- Kowarschick, W.: Multimedia-Programmierung
- butterfly_05_external_code (Flash CS5)
- butterfly_05_external_code (Flash CS4)
- SVN-Repository (Flash CS5)
- SVN-Repository (Flash CS4)
