Kapitel 12 Ereignisse
Ereignisprozeduren, Ereignismethoden und Listener
Die Ausführung von Anweisungen läuft in ActionScript sequenziell, d. h. hintereinander ab. Die Abarbeitungsreihenfolge wird jedoch durch Ereignisse beeinflusst und führt so zu einer dynamischen Anwendung.
Flash kennt von Hause aus eine ganze Reihe an Ereignissen. Im Wesentlichen unterscheidet man dabei Systemereignisse wie das Anzeigen eines Bildes (onEnterFrame) und benutzergenerierte Ereignisse wie einen Tastendruck (onKeyDown).
ActionScript arbeitet Anweisungen nur dann ab, wenn es dazu aufgefordert wird. Das heißt, sobald ein passendes Ereignis eintritt, führt Flash die dazugehörenden Anweisungen aus (ereignisorientierte Programmiersprache).
Nachricht
Damit die entsprechenden Anweisungen überhaupt von diesem Ereignis erfahren, schickt Flash eine Nachricht. Diese Nachricht entspricht dabei weitestgehend einem Methodenaufruf. Ob Sie bei meinMovieclip.stop(); nun von einem Methodenaufruf oder dem Senden einer Nachricht an das Objekt sprechen, macht an dieser Stelle keinen Unterschied – außer dass Sie bei einer Methode das auslösende Ereignis und die versandte Nachricht selber bestimmt haben.
ActionScript beherrscht bereits eine ganze Reihe an Ereignissen und versendet bei deren Eintreten die entsprechenden Mitteilung. Das Drücken der Maustaste (Ereignis) führt z.B. zu einer onMouseDown-Nachricht.
Insgesamt kennt Flash neben dem normalen Methoden- oder Funktionsaufruf drei weitere Arten, wie Ereignisse erkannt und entsprechende Nachrichten verschickt werden:
|
Ereignisprozeduren (engl. Eventhandler) |
|
Ereignismethoden |
|
Listener (engl. für Zuhörer, auch als Rückrufmethode bezeichnet) |
12.1 Vor- und Nachteile
Jede der Varianten, auf Ereignisse zu reagieren, bietet ihre Vor- und Nachteile. Wichtig ist hierbei die unterstützte Flash-Version. Und seit Flash MX fällt die Entscheidung nicht immer leicht, weil hier sämtliche Varianten zur Auswahl stehen.
Tabelle 12.1
Vordefinierte Ereignisse
Ereignismethode
|
Listener
|
Ereignisprozedur
|
-
|
-
|
on (keyPress "taste")
|
-
|
Mouse.onMouseWheel
|
-
|
-
|
MovieClipLoader.onLoadComplete
|
-
|
-
|
MovieClipLoader.onLoadError
|
-
|
-
|
MovieClipLoader.onLoadInit
|
-
|
-
|
MovieClipLoader.onLoadProgress
|
-
|
-
|
MovieClipLoader.onLoadStart
|
-
|
-
|
Stage.onResize
|
-
|
Button.onDragOut
|
-
|
on (dragOut)
|
Button.onDragOver
|
-
|
on (dragOver)
|
Button.onKeyDown (Fokus erforderlich)
|
Key.onKeyDown
|
onClipEvent (keyDown)
|
Button.onKeyDown (Fokus erforderlich)
|
Key.onKeyDown
|
onClipEvent (keyDown)
|
Button.onKeyUp (Fokus erforderlich)
|
Key.onKeyUp
|
onClipEvent (keyUp)
|
Button.onKillFocus
|
-
|
-
|
Button.onPress
|
-
|
on (press)
|
Button.onRelease
|
-
|
on (release)
|
Button.onReleaseOutside
|
-
|
on (releaseOutside)
|
Button.onRollOut
|
-
|
on (rollOut)
|
Button.onRollOver
|
-
|
on (rollOver)
|
Button.onSetFocus
|
Selection.onSetFocus
|
-
|
Camera.onActivity
|
-
|
-
|
Camera.onStatus
|
-
|
-
|
ContextMenu.onSelect
|
-
|
-
|
ContextMenuItem.onSelect
|
-
|
-
|
LoadVars.onData
|
-
|
-
|
LoadVars.onLoad
|
-
|
-
|
LocalConnection.allowDomain
|
-
|
-
|
LocalConnection.allowInsecureDomain
|
-
|
-
|
LocalConnection.onStatus
|
-
|
-
|
Microphone.onActivity
|
-
|
-
|
Microphone.onStatus
|
-
|
-
|
MovieClip.onData
|
-
|
onClipEvent (data)
|
MovieClip.onDragOut
|
-
|
on (dragOut)
|
MovieClip.onDragOver
|
-
|
on (dragOver)
|
MovieClip.onEnterFrame
|
-
|
onClipEvent (enterFrame)
|
MovieClip.onKeyDown (Fokus erforderlich)
|
Key.onKeyDown
|
onClipEvent (keyDown)
|
MovieClip.onKeyUp (Fokus erforderlich)
|
Key.onKeyUp
|
onClipEvent (keyUp)
|
MovieClip.onKillFocus
|
-
|
-
|
MovieClip.onLoad
|
-
|
onClipEvent (load)
|
MovieClip.onMouseDown
|
Mouse.onMouseDown
|
onClipEvent (mouseDown)
|
MovieClip.onMouseMove
|
Mouse.onMouseMove
|
onClipEvent (mouseMove)
|
MovieClip.onMouseUp
|
Mouse.onMouseUp
|
onClipEvent (mouseUp)
|
MovieClip.onPress
|
-
|
on (press)
|
MovieClip.onRelease
|
-
|
on (release)
|
MovieClip.onReleaseOutside
|
-
|
on (releaseOutside)
|
MovieClip.onRollOut
|
-
|
on (rollOut)
|
MovieClip.onRollOver
|
-
|
on (rollOver)
|
MovieClip.onSetFocus
|
Selection.onSetFocus
|
-
|
MovieClip.onUnload
|
-
|
onClipEvent (unload)
|
MovieClip.onUpdate (Live-Vorschau)
|
-
|
-
|
NetConnection.onStatus
|
-
|
-
|
NetStream.onStatus
|
-
|
-
|
SharedObject.onStatus
|
-
|
-
|
SharedObject.onSync
|
-
|
-
|
Sound.onID3
|
-
|
-
|
Sound.onLoad
|
-
|
-
|
Sound.onSoundComplete
|
-
|
-
|
System.onStatus
|
-
|
-
|
Textfield.onChanged
|
Textfield.onChanged
|
-
|
Textfield.onKillFocus
|
-
|
-
|
Textfield.onScroller
|
Textfield.onScroller
|
-
|
Textfield.onSetFocus
|
Selection.onSetFocus
|
-
|
TextField.StyleSheet.onData
|
-
|
-
|
TextField.StyleSheet.onLoad
|
-
|
-
|
XML.onData
|
-
|
-
|
XML.onLoad
|
-
|
-
|
XMLSocket.onClose
|
-
|
-
|
XMLSocket.onConnect
|
-
|
-
|
XMLSocket.onData
|
-
|
-
|
XMLSocket.onXML
|
-
|
-
|
12.1.1 Vor- und Nachteile von Ereignisprozeduren
Ereignisprozeduren sind teilweise bereits seit Flash 2 möglich, wobei die gesamte Palette erst mit Flash 5 eingeführt wurde. Abgesehen von dieser Rückwärtskompatibilität einiger Ereignisprozeduren bietet diese Variante nur wenige Vorteile: falls Sie es zum Beispiel vorziehen, die Anweisungen direkt auf einer Instanz in einem Instanzskript zu platzieren. Davon ist aber mittlerweile abzuraten, da dies die Lesbarkeit des Codes verschlechtert. Denn die Skripte liegen verstreut über die gesamte Anwendung. Außerdem funktionieren Ereignisprozeduren nur mit Movieclips und Schaltflächen (engl. Buttons).
12.1.2 Vor- und Nachteile von Ereignismethoden
Die meisten Ereignismethoden hat Macromedia erst mit Flash MX eingeführt. Nur wenige Ereignismethoden wie z.B. XML.onLoad gehören bereits zum Flash 5-Sprachschatz.
Ein Vorteil der Ereignismethoden ist, dass es sie nicht nur für Movieclips und Schaltflächen, sondern u.a. auch für XML- und Sound-Objekte gibt. Außerdem werden Ereignismethoden wie normale Methoden definiert und sehr ähnlich behandelt. Selbst der manuelle Aufruf einer Ereignismethode funktioniert im Gegensatz zu den Ereignisprozeduren wie bei einer normalen Methode problemlos:
mcMonster.onLoad = function() {
// Initialisiere Startposition
this._x = 10;
this._y = 10;
};
mcMonster.onEnterFrame = function() {
this._x += 5;
this._y += 5;
};
mcMonster.onMouseDown = function() {
// Rufe onLoad-Methode "manuel" auf
this.onLoad();
};
Ein weiterer Vorteil der Ereignismethoden ist, dass sie an beliebiger Stelle platziert sein dürfen; Hauptsache, der Pfad zum betreffenden Objekt ist korrekt:
mcMonster.mcLeftArm.onEnterFrame=function () {
// Drehe Arm
this._rotation+=5;
}
12.1.3 Vor- und Nachteile von Ereignismethoden in Flash 5
Obwohl Ereignismethoden für Movieclips und Schaltflächen in Flash 5 fehlen, lassen sie sich leicht simulieren. Alles, was Sie dafür benötigen, sind entsprechende Ereignisprozeduren, die eine gleichnamige Methode aufrufen:
onClipEvent (load) {
Ereignismethode in Flash 5.fla
// Simuliere onLoad-Ereignismethode
this.onLoad();
}
onClipEvent (enterFrame) {
// Simuliere onEnterFrame-Ereignismethode
this.onEnterFrame();
}
Diese Methoden verwenden Sie nun genauso wie in Flash MX, indem Sie der Instanz – in diesem Fall dem Movieclip mcMonster – entsprechende Funktionen zuweisen:
mcMonster.onLoad = function() {
Ereignis als Methode.fla
// Initialisiere Startposition
this._x = 10;
this._y = 10;
};
mcMonster.onEnterFrame = function() {
this._x += 5;
this._y += 5;
};
Einen kleinen Haken hat die Sache dann aber doch. Sobald nämlich eine selbst definierte Ereignismethode denselben Namen trägt wie die bereits in Flash vorhandene, dann wird die Ereignismethode einmal »manuell« über die Ereignisprozedur und zusätzlich automatisch aufgerufen. In diesem Beispiel bewegt sich die Instanz dann z.B. doppelt so schnell – glücklicherweise nur, wenn die Flash-Anwendung im Flash 6-Format veröffentlicht wird.
FLEM: FLash Event Model
Branden Hall und Dave Yang veröffentlichten für Flash 5 bereits ein ausgeklügeltes Ereignismodell namens FLEM (http://chattyfig.figleaf.com/flem/), das sich weitestgehend wie das in Flash MX realisierte verhält. Die grundsätzliche Technik entspricht dabei dem hier vorgestellten Workaround – zugegebenermaßen aber weiter gedacht und die Idee der im Folgenden vorgestellten Listener umfassend.
12.1.4 Vor- und Nachteile von Listener
Auf den ersten Blick erscheinen die in Flash MX eingeführten Listener wie eine kompliziertere Variante der Ereignismethoden. Denn die Definition einer Ereignismethode reicht nicht aus. Zusätzlich muss die Instanz, welche die Methode umfasst, noch angemeldet werden (addListener). Aber genau diese Anmeldung hat zahlreiche Vorteile:
meineInstanz.onKeyDown = function() {
trace("Taste gedrückt");
};
// Melde Listener an
Key.addListener(meineInstanz);
Ereignisprozeduren und Ereignismethoden funktionieren nur mit den dafür vorgesehenen Objekttypen. Listener sind mit jedem Objekt möglich. Nicht nur Movieclips und Schaltflächen, sondern auch abstrakte selbst definierte Objekte erhalten zum Beispiel die Fähigkeit, auf einen Tastendruck zu reagieren. Dies liegt daran, dass das zuhörende Objekt das Ereignis nicht selber kennt, sondern über dessen Eintritt nur eine Nachricht erhält – mit dem Nachteil, dass das Objekt als Zuhörer (engl. Listener) bei einem Objekt angemeldet werden muss, das dieses Ereignis kennt und die entsprechende Nachricht übermittelt.
Zusätzlich spricht für Listener, dass bei einem Objekt pro Ereignis ohne Listener immer nur eine Ereignisprozedur oder Ereignismethode möglich ist: Dies führt dazu, dass in komplexen Programmen wichtige Anweisungen schnell aus Versehen überschrieben werden. Gerade wenn die Definitionen an unterschiedlichen Stellen und mit unterschiedlichen Pfaden bzgl. derselben Instanz durchgeführt werden, geschieht dies oft aus Versehen:
// Definition der Ereignismethode A
mehrere Listener.fla
_root.onMouseDown=function () {
trace("Ereignismethode A");
}
// Definition der Ereignismethode B überschreibt Ereignismethode A
this.onMouseDown =function () {
trace("Ereignismethode B");
}
Mit Listenern passiert das in dieser Form nicht, da jeder einzelne Listener separat angemeldet wird. Auf diese Art und Weise darf ein Objekt mehrere Listener erhalten, die alle dem gleichen Ereignis lauschen:
// Definition des Listener-Objektes A
meineInstanzA=new Object();
meineInstanzA.onMouseDown=function () {
trace("Listener A");
}
Mouse.addListener(meineInstanzA);
// Definition des Listener-Objektes A
meineInstanzB=new Object();
meineInstanzB.onMouseDown=function () {
trace("Listener B");
}
Mouse.addListener(meineInstanzB);
Dieser Unterschied zu Ereignismethoden ist zwar eher konzeptioneller Natur, macht aber die grundsätzliche Arbeitsweise von Listenern deutlich, die ab Seite 325 noch weiter vertieft wird.
|