Keywords

Vorbemerkung

 

Animation ergibt sich durch kontinuierliche Veränderung von bestimmten Eigenschaften in der Zeit.

In Flash bzw. ActionScript 3 gibt es verschiedene Möglichkeiten die Eigenschaften von Displayobjekten und im speziellen von Movieclips zu animieren:

  1. In der Flash-Entwicklungsumgebung durch die Verwendung von Animationstechniken entlang der Timeline, wie Bewegungs- oder Formtweening. Für diese Form der Animation ist keine Programmierung notwendig.
     
  2. Erstellen einer Timeline-Loop unter Verwendung von AS3-Methoden zur Steuerung des Abspielkopfes in der Zeitleiste und Änderung von Movieclip-Eigenschaften.
     
  3. Verwendung eines ENTER_FRAME-Eventhandlers.
     
  4. Verwendung eines TIMER-Eventhandlers.
     
  5. Verwendung der Tween-Klasse.
     
Alle 5 Techniken werden in den nachfolgenden Kapiteln an Hand eines einfachen Beispiels erklärt:
Eine Movieclip-Instanz soll sich vom linken Bühnenrand horizontal zum rechten Bühnenrand bewegen und dort stoppen.
D.h. es wird die x-Eigenschaft des Movieclips in der Zeit kontinuierlich verändert  bis ein Abbruchkriterium erfüllt ist und die Animation stoppt.

 

 


Animation von Movieclip-Eigenschaften in der Flash-Entwicklungsumgebung

Im DMA-Modul Animationsarten in Flash werden die verschiedenen Animationstechniken in Flash erklärt bei denen keine Programmierung notwendig ist.

Im nachfolgenden Video wird für das konkrete Beispiel eine Bewegungstween-Animation erstellt.
Damit die Animation nicht loopt, wird am Ende des Bewegungstweens im letzten Frame die Aktion stop(); hinzugefügt, wodurch der Abspielkopf in der Maintimeline gestoppt wird.

 

Die Abspielgeschwindigkeit der Animation hängt von der Bildrate ab. 

Animation mit einer Timeline-Loop

Eine Timeline-Loop ist möglich, wenn in der Timeline nicht nur im ersten Frame Schlüsselbilder enthalten sind.
Nach dem Starten der swf-Datei spielt der Abspielkopf Bild für Bild die Timeline ab und nach dem letzten Frame springt der Abspielkopf automatisch wieder zurück zum ersten Frame.
Auch durch den Aufruf der Movieclip-Methode gotoAndPlay(1) im einem beliebigen Frame, springt der Abspielkopf wieder zurück zum ersten Frame und beginnt dort erneut mit dem Abspielen der Timeline.

Siehe auch Eigenschaften und Methoden von MovieClips.

Allgemeiner Aufbau einer Timeline-Loop

Eine Timeline-Loop besteht aus mindestens zwei aufeinanderfolgenden Frames. Falls notwendig kann noch ein drittes Frame für die Initialisierung von Variablen vorangestellt werden.
Eine Timeline-Loop muss nicht unbedingt im ersten Frame der Timeline beginnen.

  1. Man sollte das Frame, in dem die Loop beginnt mit einem Namen versehen (in einer eigenen Marker-Ebene).
  2. Falls man Variable initialisieren möchte, sollte das im Frame vor dem Loopanfang erfolgen.
  3. In jedem Frame der Loop wird ein Skript geschrieben, das eine Movieclip-Eigenschaft relativ zum alten Wert verändert. Dadurch wird diese Eigenschaft durch wiederholtes Abspielen der Loop animiert.
  4. In jedem Frame der Loop wird überprüft, ob das Abbruchkriterium der Animation erfüllt ist. Bei einer Endlosanimation ist das nicht notwendig.
    Wenn das Abbruchkriterium erfüllt ist, wird der Abspielkopf gestoppt oder zu einem anderen Frame geleitet.
  5. Im letzten Frame der Loop gibt es immer einen gotoAndPlay()-Befehl zum Marker des ersten Loop-Frames.


Das Video zeigt das Erstellen einer Timeline-Loop mit zwei Frames und einem vorangestellten Frame für die Initialisierung einer Variablen. Dabei wird in jedem Loop-Frame der x-Wert der Kreisinstanz um einen bestimmten Wert erhöht. Wenn der Kreis den rechten Rand erreicht hat, wird der Abspielkopf und somit die Timeline-Loop mit der Animation gestoppt.

 

 

Das Skript im Initialisierungsframe:

var speed:Number = 10;

Im Initialisierungframe wird in der Variblen speed die Schrittweite angegeben. Durch Verwendung dieses Initialisierungsframes braucht man den Wert nur einmal ändern.

Das Skript im ersten Loop-Frame:

kreis_mc.x += speed;
if (kreis_mc.x + kreis_mc.width/2 >= stage.stageWidth) {
kreis_mc.x = stage.stageWidth - kreis_mc.width/2;
stop();
}

In der Bedingung der if-Anweisung wird geprüft, ob der rechte Rand des Kreises (= Kreismittelpunkt + halbe Kreisbreite) größer ist als die Bühnenbreite. Wenn das der Fall ist, wird der Kreis genau am rechten Rand ausgerichtet und der Abspielkopf gestoppt. Sonst springt der Abspielkopf ins nächste Frame, und es wird das Skript im zweiten Loop-Frame abgearbeitet.

Das Skript im zweiten Loop-Frame:

kreis_mc.x += speed;
if (kreis_mc.x + kreis_mc.width/2 >= stage.stageWidth) {
kreis_mc.x = stage.stageWidth - kreis_mc.width/2;
stop();
} else {
gotoAndPlay("anfang");
}

Wenn die Bedingung in der if-Anweisung noch nicht erfüllt ist, d.h. der rechte Rand wurde noch nicht erreicht, dann wird durch gotoAndPlay("anfang")der Abspielkopf zurück zum ersten Loop-Frame geschickt. Der Rest des Skripts ist analog zum Skript im ersten Loop-Frame.

 

Wichtig:
Die Geschwindigkeit der Animation wird über die Bildrate gesteuert. Je höher die Bildrate desto weicher läuft die Animation.
Auch über die Schrittweite (in diesem Beispiel über die Variable speed) kann die Geschwindigkeit und die Wirkung der Animation beeinflusst werden.

Animation mit einem Event-Handler für das ENTER_FRAME-Ereignis

In diesem Kapitel wird die Animation unter Verwendung eines Eventhandlers für das ENTER_FRAME-Ereignis erstellt.
Immer wenn der Abspielkopf ein neues Frame betritt, wird das Ereignis ENTER_FRAME ausgelöst.
Bei einer Bildrate von z.B. 15 Bildern in der Sekunde tritt dieses Ereignis 15-mal in der Sekunde auf.
Das passiert, auch wenn es nur im ersten Frame der Timeline Schlüsselbilder gibt oder der Abspielkopf in einem Frame gestoppt wurde.

Siehe auch ActionScript3: Ereigniskonzept und Eventhandler - eine kurze Einführung

Grundsätzlicher Aufbau eines Skripts für eine ENTER_FRAME-Animation

1. Initialisierungblock, in dem Variable initialisiert 
und eventuell für Movieclips die Startwerte für bestimmte Eigenschaften gesetzt werden
 
2. Zuordnung des Eventlisteners:
eventTarget.addEventListener(Event.ENTER_FRAME, enterFrameListener);
 
3. Defintion des Eventlisteners, der auch das Entfernen des Eventlisteners enthält:
function enterFrameListener(e:Event):void {
relative Veränderung von MovieClip-Eigenschaften (das ist der zentrale Punkt für die Animation)
if (Abbruchkriterium für die Animation ist erfüllt) {
abschließende Aktionen
eventTarget.removeEventListener(Event.ENTER_FRAME, enterFrameListener);
}
}

Im nachfolgenden Beispiel gibt es nur ein Skript im ersten Frame der Maintimeline.

 

 

Beim Movieclip Kreis in der Bibliothek muss Export für ActionScript aktiviert sein.

Schritt 1: Initialisierungsblock

Erzeugen einer Kreisinstanz und platzieren am linken Bühnenrand:

var kreis_mc:MovieClip = new Kreis();
this.addChild(kreis_mc);
kreis_mc.x = kreis_mc.width/2;
kreis_mc.y = stage.stageHeight/2;

Die Schrittweite in einer Variablen abspeichern:

var speed:Number = 10;

 

Schritt 2: Zuordnung des Eventlisteners

Die Kreisinstanz "abonniert" das Ereignis ENTER_FRAME. Der Instanz kreis_mc wird der Eventlistener (Eventhandler) bewegeKreis zugeordnet, der auf das Ereignis ENTER_FRAME "horcht". D.h. immer wenn das Ereignis ENTER_FRAME eintritt, wird der Eventlistener  bewegeKreis aufgerufen.

kreis_mc.addEventListener(Event.ENTER_FRAME, bewegeKreis);

Variante: Das Mainmovie (die Maintimeline) erhält den Eventlistener. Über this wird in diesem Fall die Maintimeline angesprochen.

this.addEventListener(Event.ENTER_FRAME, bewegeKreis);

 

Schritt 3: Definition des Eventlisteners (Eventhandlers)

Ein Eventhandler ist eine Funktion, die als Input das auslösende Event erhält. Eventhandler haben keinen Output.

function bewegeKreis(e:Event):void {
e.target.x += speed;
if (e.target.x + e.target.width/2 > stage.stageWidth) {
e.target.x = stage.stageWidth - e.target.width/2;
e.target.removeEventListener(Event.ENTER_FRAME, bewegeKreis);
}
}

Über die Eigenschaft target des Events e (d.h. e.target) kann die Instanz angesprochen werden, die das Ereignis abonniert hat. In diesem Fall ist damit die Instanz kreis_mc gemeint, deren x-Koordinate um den Wert von speed erhöht wird.

Wenn der Kreis den rechten Rand erreicht hat, muss er nicht mehr auf das Ereignis ENTER_FRAME horchen und daher wird in diesem Fall der Eventlistener mit e.target.removeEventListener(Event.ENTER_FRAME, bewegeKreis) entfernt. D.h. "das Abonnement des Ereignisses wird storniert".

Variante: Dem Mainmovie (die Maintimeline) wurde der Eventlistener zugeordnet.
In diesem Fall ist mit e.target die Maintimeline gemeint und daher muss man die Instanz kreis_mc explizit in den Eventhandler hineinschreiben.
Der Eventlistener wird in dieser Variante mit this.removeEventListener(Event.ENTER_FRAME, bewegeKreis) von der Maintimeline entfernt.

function bewegeKreis(e:Event):void {
kreis_mc.x += speed;
if (kreis_mc.x + kreis_mc.width/2 > stage.stageWidth) {
kreis_mc.x = stage.stageWidth - kreis_mc.width/2;
this.removeEventListener(Event.ENTER_FRAME, bewegeKreis);
}
}

 

Das Skript zusammengefasst:
 

var kreis_mc:MovieClip = new Kreis();
this.addChild(kreis_mc);
kreis_mc.x = kreis_mc.width/2;
kreis_mc.y = stage.stageHeight/2;

var speed:Number = 10;

kreis_mc.addEventListener(Event.ENTER_FRAME, bewegeKreis);
function bewegeKreis(e:Event):void {
e.target.x += speed;
if (e.target.x + e.target.width/2 > stage.stageWidth) {
e.target.x = stage.stageWidth - e.target.width/2;
e.target.removeEventListener(Event.ENTER_FRAME, bewegeKreis);
}
}
 
Die Variante zusammengefasst:
 
var kreis_mc:MovieClip = new Kreis();
this.addChild(kreis_mc);
kreis_mc.x = kreis_mc.width/2;
kreis_mc.y = stage.stageHeight/2;

var speed:Number = 10;

this.addEventListener(Event.ENTER_FRAME, bewegeKreis);
function bewegeKreis(e:Event):void {
kreis_mc.x += speed;
if (kreis_mc.x + kreis_mc.width/2 > stage.stageWidth) {
kreis_mc.x = stage.stageWidth - kreis_mc.width/2;
this.removeEventListener(Event.ENTER_FRAME, bewegeKreis);
}
}

Animation mit einem Timer

In den vorhergehenden Kapiteln ist die Geschwindigkeit der Animation von der Bildrate der swf-Datei abhängig. Um von der Bildrate (fast) unabhängig zu sein, kann man einen Timer definieren, der regelmäßig in einem frei wählbaren Intervall ein Timer-Ereignisse auslöst.
Diese Timer-Ereignisse kann der Timer nun mit einem Eventlistener (Eventhandler) abonnieren, der damit eine Eigenschaft regelmäßig verändert (animiert).

Grundsätzlicher Aufbau eines Skripts für eine TIMER-Animation

1. Initialisierungblock, in dem Variable initialisiert 
und eventuell für Movieclips die Startwerte für bestimmte Eigenschaften gesetzt werden
 
2. Timerobjekt erzeugen, :
var timer:Timer = new Timer(Zeitintervall);

3. Zuordnung des Eventlisteners (das Timerobjekt "abonniert" das Timerevent):
timer.addEventListener(TimerEvent.TIMER, timerListener);

4. Starten des Timers:
timer.start();
 
5. Defintion des Eventlisteners, der ein Screenupdate sowie
das Entfernen des Eventlisteners und Stoppen des Timers enthält:
function timerListener(e:TimerEvent):void {
relative Veränderung von MovieClip-Eigenschaften (das ist der zentrale Punkt für die Animation)
e.updateAfterEvent();
if (Abbruchkriterium für die Animation ist erfüllt) {
abschließende Aktionen
timer.removeEventListener(TimerEvent.TIMER, timerListener);
timer.stop();
}
}

 
Beispiel: Bewegen eines Kreises vom linken zum rechten Bühnenrand

Das nachfolgende Skript ist wieder im ersten Frame der Timeline platziert.
Beim Movieclip Kreis in der Bibliothek muss Export für ActionScript aktiviert sein.

Schritt 1: Initialisierungsblock

Erzeugen und platzieren einer Kreisinstanz am linken Bühnenrand und Schrittweite festlegen:

var kreis_mc:MovieClip = new Kreis();
this.addChild(kreis_mc);
kreis_mc.x = kreis_mc.width/2;
kreis_mc.y = stage.stageHeight/2;
var speed:Number = 10;

Schritt 2: Eine Timer-Instanz aus der Timer-Klasse erzeugen

var timer:Timer = new Timer(20,0)
 
new Timer (20,0)
erzeugt ein Timerobjekt, das alle 20 Millisekunden ein Timerereignis auslöst.
Der zweite Parameter gibt die Anzahl der Wiederholungen an. Wenn der Wert 0 ist, wird der Timer unbegrenzt ausgeführt.

Schritt 3: Zuordnung des Eventlisteners

timer.addEventListener(TimerEvent.TIMER, bewegeKreis);
Schritt 4: Timer starten
timer.start();
Schritt 5: Eventhandler definieren
function bewegeKreis(e:TimerEvent):void {
kreis_mc.x += speed;
e.updateAfterEvent();
if (kreis_mc.x + kreis_mc.width/2 > stage.stageWidth) {
kreis_mc.x = stage.stageWidth - kreis_mc.width/2;
timer.removeEventListener(Event.ENTER_FRAME, bewegeKreis);
timer.stop();
}
}
Durch e.updateAfterEvent(); wird unabhängig von der Bildrate ein Neuzeichnen der Bühne erzwungen. Dieser Befehl ist wichtig, denn sonst würde die Bühne wieder nur entsprechend der Bildrate aktualisiert werden. Aber genau das möchte man durch die Verwendung eines Timers umgehen.

Das Skript zusammengefasst:
var kreis_mc:MovieClip = new Kreis();
this.addChild(kreis_mc);
kreis_mc.x = kreis_mc.width/2;
kreis_mc.y = stage.stageHeight/2;
var speed:Number = 10;
 
var timer:Timer = new Timer(20,0);
timer.addEventListener(TimerEvent.TIMER, bewegeKreis);
timer.start();
 
function bewegeKreis(e:TimerEvent):void {
kreis_mc.x += speed;
e.updateAfterEvent();
if (kreis_mc.x + kreis_mc.width/2 > stage.stageWidth) {
kreis_mc.x = stage.stageWidth - kreis_mc.width/2;
timer.removeEventListener(Event.ENTER_FRAME, bewegeKreis);
timer.stop();
}
}
Wichtige Anmerkungen:
 
Ein Timer ist NICHT völlig unabhängig von der Bildrate, denn ein Timerevent kann sich höchsten 10-mal zwischen zwei normalen Screen-Updates ereignen.

Beipiel: Bei einer Bildrate von 10 Bildern pro Sekunde kann eine Timerevent nur 100-mal pro Sekunde auftreten. D.h.das kleinste mögliche Timerintervall ist 10 Millisekunden.
Bei einer Bildrate von 20 Bildern pro Sekunde kann eine Timerevent nur 200-mal pro Sekunde auftreten. D.h.das kleinste mögliche Timerintervall ist 5 Millisekunden.

Die Verwendung von zu vielen verschiedenen Timern kann zu Performanceproblemen führen, dazu zu oft zwischendurch Screen-Updates durchgeführt werden müssen.

Animation mit der Tween-Klasse

Mithilfe der Tween-Klasse kann man eine Eigenschaft  eines Movieclips für die Animation über mehrere Bilder oder Sekunden einstellen.

Mit der Tween-Klasse kann man auch verschiedene Beschleunigungsmethoden festlegen. "Beschleunigen" bezieht sich auf die allmähliche Beschleunigung oder Verlangsamung bei der Animation, wodurch Animationen realistischer erscheinen. Im fl.transitions.easing-Paket stehen für diese Beschleunigung und Verlangsamung viele Beschleunigungsmethoden zur Verfügung, die die Animation entsprechend ändern.

Grundsätzlicher Aufbau eines Skripts für eine Animation mit einem Tween-Objekt

1. Einbindung der notwendigen fl-Pakete, die die benötigten Klassen enthalten: 
import fl.transitions.Tween;
import fl.transitions.easing.*;

 
2. Initialisierungblock, in dem Variable initialisiert
und eventuell für den Movieclip die Startwerte für bestimmte Eigenschaften gesetzt werden
 
3. Tweenobjekt erzeugen:
var tween:Tween = new Tween(Movieclip, Eigenschaft, Funktion, Startwert, Endwert, Dauer, true/false);
 
4. Tweenanimation starten:
tween.start();

 
Beispiel: Bewegen eines Kreises vom linken zum rechten Bühnenrand

Das nachfolgende Skript ist wieder im ersten Frame der Timeline platziert.
Beim Movieclip Kreis in der Bibliothek muss Export für ActionScript aktiviert sein.

Schritt 1: fl-Pakete importieren

import fl.transitions.Tween;
import fl.transitions.easing.*;
 
Das fl.transitions.easing-Paket enthält Klassen, die mit den fl.transition-Klassen zur Erstellung von Beschleunigungseffekten verwendet werden können. "Beschleunigung" bezieht sich auf die allmähliche Beschleunigung oder Verlangsamung bei der Animation, wodurch Animationen realistischer erscheinen. Eine gleichförmige, lineare Änderung einer Eigenschaft zählt dabei auch zu den "Beschleunigungseffekten".

Schritt 2: Initialisierungsblock
Erzeugen und platzieren einer Kreisinstanz am linken Bühnenrand:

var kreis_mc:MovieClip = new Kreis();
this.addChild(kreis_mc);
kreis_mc.x = kreis_mc.width/2;
kreis_mc.y = stage.stageHeight/2;

Schritt 3: Eine Tween-Instanz aus der Tween-Klasse erzeugen

var tween:Tween = new Tween(kreis_mc, "x", None.easeNone, kreis_mc.x, stage.stageWidth-kreis_mc.width/2, 2, true);

Der Konstruktor benötigt 7 Eingabewerte:

  1. kreis_mc ist der Movieclip von dem eine  Eigenschaft animiert werden soll
  2. "x" ist die zu animierende Eigenschaft als Zeichenkette geschrieben
  3. None.easeNone ist die Beschleunigungsfunktion (die None-Klasse definiert Beschleunigungsfunktionen zum unbeschleunigten, linearen Ändern einer Eigenschaft)
  4. kreis_mc.x ist der Anfanfgswert der Eigenschaft
  5. stage.stageWidth - kreis_mc.width/2 ist der Endwert der Eigenschaft nach der Animation
  6. 2 ist die Dauer der Animation in Sekunden, weil ...
  7. ... der 7. Parameter auf true gesetzt ist.
    Wenn dieser Parameter auf false ist, gibt der Wert im 6. Parameter die Anzahl der Bilder in der Animation an.

Schritt 4: Tween-Animation starten

tween.start();

 
Das Skript zusammengefasst:

import fl.transitions.Tween;
import fl.transitions.easing.*;
 
var kreis_mc:MovieClip = new Kreis();
this.addChild(kreis_mc);
kreis_mc.x = kreis_mc.width/2;
kreis_mc.y = stage.stageHeight/2;
 
var tween:Tween = new Tween(kreis_mc, "x", None.easeNone, kreis_mc.x, stage.stageWidth-kreis_mc.width/2, 2, true);
tween.start();