Photoshop
Cinema 4d
HTML / CSS
JavaScript
PHP
Flash
Fotografie
Terragen
Webserver
Informatik
Sonstige
mx.transitions-Tween mit AS (Flash Tutorial)
Tutorial erstellt von Labrar in 8, letzte Änderung am 03.07.2008Tweens mit Actionscript (mx.transitions)
In diesem kurzen Tutorial möchte ich euch zeigen, wie man mittels Actionscript MovieClips mit Hilfe der mx.transitions-Klasse tweenen kann.
Die Problematik bei normalem Zeitleistentweens, welche uns Flash als Bordmittel zur Verfügung stellt, ist die Performance. Bei genauer Überlegung ist das auch logisch, da Flash hier jedes einzelne Bild berechnen muss.
Anders natürlich beim Tweenen via Actionscript, da hier nur die X- bzw. Y-Koordinate oder die Größe berechnet wird. Da uns Flash (ab Version 8) hier mit mx.transitions eine mächtige Klasse zur Verfügung stellt, werde ich euch hier erklären, wie ihr dieses Werkzeug sinnvoll einsetzen könnt, um MovieClips zu verschieben, zu skalieren oder zu verzerren. Um aber genau zu verstehen, wie die Klasse funktioniert, stelle ich euch zunächst die veraltete Methode vor, um euch zu zeigen, was generell passieren muss, um unseren MC durch die Gegend zu tweenen.
Los geht's
Zieht ein Quadrat auf, wandelt es mit F8 in einen MC und gebt im den Instanznamen „square“:

Kopiert folgenden Code in euer Schlüsselbild und testet dann den Film:
Code:
MovieClip.prototype.tween = function(x)
{
this.onEnterFrame = function()
{
this._x += (x - this._x)/2;
}
}
square.tween(Stage.width - square._width);
{
this.onEnterFrame = function()
{
this._x += (x - this._x)/2;
}
}
square.tween(Stage.width - square._width);
Prototype-Funktionen unterscheiden sich nur gering von normalen Funktionen, mit denen es im Übrigen auch funktionieren würde. Prototypen haben aber den Vorteil, dass man sie direkt an den entsprechenden MC „kleben“ kann. Das ist sinnvoll bei einer onEnterFrame-Schleife, da sich diese dann speziell auf den aufrufenden MC bezieht und nicht durch ein „delete this.onEnterFrame“ an vielleicht anderer Scriptstelle gelöscht werden kann, wie es bei einer normalen Funktion der Fall wäre.
Andererseits aber belasten onEnterFrame-Schleifen wie gerade oben benutzt in Prototypen natürlich auch ordentlich die CPU. Das liegt daran, dass die onEnterFrame-(künftig oEF-)Schleife im obigen Script auch dann nicht gelöscht wird, wenn unser MC seine Endposition erreicht hat. Natürlich könnte man hier eine Abfrage einbauen, die dieses dann tut. Versucht es einmal und testet:
Code:
MovieClip.prototype.tween = function(x)
{
this.onEnterFrame = function()
{
this._x += (x - this._x)/2;
trace(this._x + " " + x);
if(this._x == x)
{
delete this.onEnterFrame;
trace("Bin da");
}
}
}
square.tween(Stage.width - square._width);
{
this.onEnterFrame = function()
{
this._x += (x - this._x)/2;
trace(this._x + " " + x);
if(this._x == x)
{
delete this.onEnterFrame;
trace("Bin da");
}
}
}
square.tween(Stage.width - square._width);
Anmerkung
"/2" steht übrigens dafür, dass der Wert ständig durch 2 geteilt wird. Somit können wir unseren Tween auch noch mit den Augen verfolgen und er bremst zum Ende hin weich ab. Erhöht oder verringert 2 einfach mal und testet. Oder lasst "/2" mal ganz weg. Wobei bei letzterem Fall die Tweenstrecke (egal ob x,y oder scale) sehr lang sein muss, damit man es mit dem Auge noch erkennen kann.
Im Code oben wird nun allerdings „Bin da“ gar nicht bis selten getraced, da this._x je immer nur um die Hälfte des Abstands zu x an x heranrückt und den Wert x somit nie oder nur sehr spät erreicht. Mit Math.round würde es besser gehen:
Code:
MovieClip.prototype.tween = function(x)
{
this.onEnterFrame=function()
{
this._x += (x - this._x)/2;
trace(this._x + " " + x);
if(Math.round(this._x) == x)
{
delete this.onEnterFrame;
trace("Bin da");
}
}
}
square.tween(Stage.width - square._width);
{
this.onEnterFrame=function()
{
this._x += (x - this._x)/2;
trace(this._x + " " + x);
if(Math.round(this._x) == x)
{
delete this.onEnterFrame;
trace("Bin da");
}
}
}
square.tween(Stage.width - square._width);
Dennoch ist diese Lösung veraltet und alles in allem unbefriedigend. Aber bleiben wir einen Augenblick dabei. Mit dem selbem leicht modifizierten Script können wir unseren MC auch skalieren. Die Befehle „_xscsale“ und „_yscale“ skalieren unseren MC prozentual auf der X- bzw Y-Achse. Ausgangsprozentzahl ist immer 100%. Sprich: die Zeile
Code:
square._xscale = 100;
würde nix bringen, da unser Quadrat zumindest zu Beginn ja schon 100% seiner Größe hat. Also ziehen wir es einmal doppelt so groß auf (200%):
Code:
MovieClip.prototype.tween = function(prz)
{
this.onEnterFrame = function()
{
this._xscale += (prz - this._xscale)/2;
this._yscale += (prz - this._yscale)/2;
if(Math.round(this._xscale) == prz)
{
delete this.onEnterFrame;
}
}
}
square.tween(200);
{
this.onEnterFrame = function()
{
this._xscale += (prz - this._xscale)/2;
this._yscale += (prz - this._yscale)/2;
if(Math.round(this._xscale) == prz)
{
delete this.onEnterFrame;
}
}
}
square.tween(200);
Bitte testen. - Natürlich geht das Ganze auch mit festgesetzten Pixelwerten. Sagen wir: 200 breit und 110 hoch?
Code:
MovieClip.prototype.tween = function(b,h)
{
this.onEnterFrame = function()
{
this._width += (b - this._width)/2;
this._height += (h - this._height)/2;
if(Math.round(this._width) == b && Math.round(this._height) == h)
{
delete this.onEnterFrame;
}
}
}
square.tween(200,110);
{
this.onEnterFrame = function()
{
this._width += (b - this._width)/2;
this._height += (h - this._height)/2;
if(Math.round(this._width) == b && Math.round(this._height) == h)
{
delete this.onEnterFrame;
}
}
}
square.tween(200,110);
mx.transitions
Jetzt haben wir also ein paar Möglichkeiten durchgespielt. Stellt euch jetzt aber vor, ihr möchtet diesen Tween nach Beendigung in rückwärts wiederholen.
Oder ihr möchtet, dass euer MC wie ein Gummiball zum Endpunkt hüpft. Oder oder oder. Das geht alles sicher auch mit der Prototypeklasse. Aber überlegt euch einfach mal, welchen programmiertechnischen Aufwand das bedeuten würde. Von der Performance mal ganz zu schweigen. Koordinaten müssten ständig abgefragt, berechnet und verändert wiedergegeben werden.
Hier kommt mx.transitions ins Spiel.
Entgegen der Flashhilfe oder diversen Büchern muss die mx.transitions Klasse nicht erst importiert werden, sofern es sich nur um reine Bewegungen oder Skalierungen dreht. (Tween) Wir müssen sie aber jeweils neu definieren. Bsp. am Bruchteil der Codezeile
Code:
MeinKlassenname = new mx.transitions
Folgende Parameter sind bei reinem Tweening möglich (hier zumindest die wichtigsten):
Bounce = (Einfach übersetzen: springen, hüpfen)
Regular = (Mit Beschleunigung und/oder Abbremsen ähnlich der Zeitleiste)
Elastic = (Gummiseileffekt)
None = (nur der reine Tween)
easeIn = langsam beschleunigen
easeOut = langsam abbremsen
easeInOut = langsam bechleunigen und langsam abremsen
Einmal rechter Bühnenrand mit Abbremsen, bitte
Code:
X = new mx.transitions.Tween(square, "_x", mx.transitions.easing.Regular.easeOut, square._x, Stage.width - square._width, 1, true);
Bitte wieder testen. - So geht's als auch. Tauscht nun Regular gegen Bounce oder Elastic oder None. Ebenso könnt ihr auch easeOut gegen easeIn oder easeInOut tauschen. - Stark gell? Gehen wir die Zeile mal durch:
Code:
X = new mx.transitions.Tween
X war jetzt einfach mal ein beliebiger Bezeichner für unseren Tween. Dieser Tween lässt sich dann also mit X ansprechen, z.B. um ihn anzuhalten mit
Code:
X.stop()
.X = new mx.transitions. (Klassenaufruf ".") Allerdings gibt es viele mx.transition - also welchen davon? Richtig, „Tween“. Gefolgt von der eigentlichen Anweisung in Klammern ()
Code:
(square, "_x", mx.transitions.easing.Regular.easeOut, square._x, Stage.width - square._width, 1, true);
Übersetzt:
(MovieClip, Methode, welche transitions' easing=Bewegung', easingMethode, easeMethode, Startpunkt, Endpunkt, Zeitzahl, Zeitmethode)
Auch der letzte Parameter (Zeitmethode) ist interessant. Steht er auf "true", wird die Tweendauer auf die Zeitzahl in Sekunden gesetzt. Bei "false" auf FramesPerSecond (BPS) oder (FPS).
Natürlich gibt es auch noch eine Handvoll anderer Methoden (eher: MC-Eigenschaften), mit denen ihr 'rumprobieren könnt:
"_x" = Wie hier verwendet: Bewegung auf der X Achse
"_y" = Bewegung auf der Y Achse
"_width" = Auf angegebenen Pixelwert in Breite vergrößern
"_height" = Auf angegebenen Pixelwert in Höhe vergrößern
"_xscale" = Auf angegebenen Prozentwert in Breite vergrößern
"_yscale" = Auf angegebenen Prozentwert in Höhe vergrößern
"_rotation" = Auf angegebene Gradzahl drehen
"_alpha" = Auf angegebenen Alphawert setzen
So, wer glaubt, das wäre das Ende der Fahnenstange dieser hervorragenden Klasse, der irrt: Wir können unseren Tween auch während oder nach Beendigung abfragen und entsprechend agieren. - Kleines Beispiel:
Code:
X = new mx.transitions.Tween(square, "_x", mx.transitions.easing.None.easeInOut, square._x, Stage.width - square._width, 1, true);
X.onMotionChanged = function(){ trace("Ich bewege mich noch"); }
X.onMotionFinished = function(){ trace("Ich bin fertig"); }
X.onMotionChanged = function(){ trace("Ich bewege mich noch"); }
X.onMotionFinished = function(){ trace("Ich bin fertig"); }
Wieder Testen.
Wir haben doch oben schon einmal darüber gesprochen, dass es doch cool wäre, wenn unser MC den Tween nach Beendigung nochmal rückwärts abspielte:
Code:
wiederholung = 1;
wert = 0;
X = new mx.transitions.Tween(square, "_x", mx.transitions.easing.None.easeInOut, square._x, Stage.width - square._width, 1, true);
X.onMotionFinished = function()
{
if(wert != wiederholung)
{
X.yoyo();
wert++;
}
}
wert = 0;
X = new mx.transitions.Tween(square, "_x", mx.transitions.easing.None.easeInOut, square._x, Stage.width - square._width, 1, true);
X.onMotionFinished = function()
{
if(wert != wiederholung)
{
X.yoyo();
wert++;
}
}
Testen. Erhöht auch ruhig mal den Wert von „wiederholung“. Natürlich können wir mit yoyo auch (wofür diese Funktion auch eigentlich gedacht ist) einen Endlos-Loop unseres Tweens erreichen:
Code:
X = new mx.transitions.Tween(square, "_x", mx.transitions.easing.None.easeInOut, square._x, Stage.width - square._width, 1, true);
X.onMotionFinished = function()
{
X.yoyo();
}
X.onMotionFinished = function()
{
X.yoyo();
}
Die Möglichkeiten sind fast unbegrenzt, zumal ich euch hier nur einen kleinen Ausschnitt der transitions-Welt gezeigt habe.
Ich hoffe, ich konnte euch das Ganze etwas näher bringen und ihr könnt das eine oder andere sinnvoll für eure Zwecke nutzen.
Viel Spaß ;)
>> Allgemeine Fragen oder Probleme mit dem Tutorial? Hier gehts zum Forum!