9.2 Selbst definierte Funktionen
Sie brauchen in Flash natürlich nicht auf eigene Funktionen zu verzichten und dürfen jederzeit selber neue Funktionen erstellen.
9.2.1 Funktionen erstellen und verwenden
Der konventionelle Weg einer Funktionsdeklaration gelingt mit Hilfe des Schlüsselwortes function gefolgt von dem Bezeichner für den Funktionsnamen und runden Klammern, die optionale Parameter zusammenhalten. Die eigentlichen Anweisungen, aus denen die Funktion besteht, geben Sie anschließend durch geschweifte Klammern eingerahmt an:
function funktionsName () {
// Hier stehen die Anweisungen
}
Die so deklarierte Funktion steht – egal an welcher Stelle in einem Skript sie definiert ist – von Anfang an zur Verfügung und kann über den Bezeichner gefolgt von runden Klammern aufgerufen werden. Die runden Klammern teilen Flash an dieser Stelle mit, dass die Anweisungen innerhalb der Funktion abgearbeitet werden sollen:
funktionsName();
Um beispielsweise eine Flash-Anwendung am Anfang zu initialisieren, könnten Sie die folgende Funktion schreiben, die eine unskalierte Darstellung in 100 Prozent erzwingt und das Kontextmenü soweit möglich deaktiviert:
function init () {
// Verhindere Skalierung
Stage.scaleMode = "noScale";
// Deaktiviere Kontextmenü soweit möglich
Stage.showMenu = false;
}
Um diese Funktion aufzurufen und die darin befindlichen Anweisungen abzuarbeiten, müssen Sie nur die folgenden Anweisung schreiben:
init();
Methoden sind Funktionen, die zu einem Objekt gehören.
Bei dem Aufruf der Funktion sollten Sie jedoch beachten, wo diese Funktion definiert ist und von wo aus Sie diese Funktion ansprechen, um sie korrekt aufzurufen. Sollten diese beiden Orte nicht identisch sein, dann müssen Sie einen Pfad verwenden, so wie das im Kapitel »DOM« auf Seite 276 erklärt ist. Sollte die Funktion beispielsweise in der Hauptzeitleiste (_level0) liegen, dann reicht es aus, dem Aufruf diesen absoluten Pfad voranzustellen: _level0.init();.
9.2.2 Funktion als Methode
Fast jede Funktion in Flash ist gleichzeitig eine Methode. Denn – abgesehen von lokal erstellten oder anonym definierten Funktionen – jede Funktion gehört zu einem Objekt. Toplevel-Funktionen sind Methoden des globalen Objektes (_global). Bei den meisten anderen Funktionen handelt es sich um Methoden eines Movieclips so wie die Hauptzeitleiste (_root bzw. _level0).
Meist bemerken Sie das zugehörige Objekt nicht, da globale Funktionen überall verfügbar sind und der Pfad zum Objekt nicht angegeben werden muss. Und wenn Sie eine Funktion in einem Movieclip platzieren, dann ist der Pfad üblicherweise auch nicht notwendig, da Flash die Funktion automatisch dem Objekt zuordnet, in dem sie deklariert ist – außer Sie geben einen Pfad an (siehe Inline-Schreibweise).
Movieclip durch Methode verkleinern
1. |
Erstellen Sie ein Movieclip-Symbol |
|
|
Legen Sie ein Movieclip-Symbol an, und wechseln Sie in den Bearbeitungsmodus dieses Movieclips, um eine Funktion direkt im Symbol erstellen zu können.
2. |
Platzieren Sie die Methode in dem Symbol |
|
|
Platzieren Sie im ersten Schlüsselbild innerhalb des Symbols die folgende Funktion, die dann als Methode für alle Instanzen des Symbols bereitsteht:
function shrink() {
02_Programmierung\Funktionen als Methode
_xscale = _xscale/2;
_yscale = _yscale/2;
}
3. |
Verwenden Sie den Movieclip |
|
|
Platzieren Sie eine Instanz des Movieclip-Symbols in der Hauptzeitleiste der Anwendung, und geben Sie dieser Instanz einen eindeutigen Instanznamen.
4. |
Verwenden Sie die Methode |
|
|
Um die Methode des Symbols aus der Hauptzeitleiste heraus verwenden zu können, brauchen Sie diese nur über den Instanznamen kombiniert mit dem Methodennamen anzusprechen:
function onMouseDown () {
box_mc.shrink();
}
Bitte beachten Sie, dass der direkte Aufruf dieser Methode in diesem Beispiel erst nach einem Bildwechsel geschehen kann, da die Methode erst dann in der Instanz initialisiert ist.
Methode gezielt einem Objekt zuordnen
Um nicht nur den Aufruf einer Methode gezielt über einen Pfad zu erlauben, sondern auch die Erstellung gezielt in einem Objekt zu erreichen, benötigen Sie die Inline-Schreibweise (Seite 255).
box_mx.shrink = function () {
_xscale = _xscale/2;
_yscale = _yscale/2;
}
box_mc.shrink();
9.2.3 Parameter übergeben
Falls Sie eine Funktion wie ein Grundrezept betrachten, dann ist es nützlich, dieses zu parametrisieren, also es durch weitere Angaben zu variieren, ohne das Grundrezept neu schreiben zu müssen. Sämtliche Parameter einer Funktion sollten Sie typisieren, wie im Kapitel »Typisierung«, Seite 192, erklärt.
Stellen Sie sich das Grundrezept für einen Nudelteig als Funktion vor, der Sie nur noch die Gesamtmenge übergeben müssen, damit alle satt werden:
// abhängig von der Personenzahl
function macheNudelteig(personenZahl) {
// in Stück
var eier = 1 * personenZahl;
// in Gramm
var mehl = 100 * personenzahl;
// in Esslöffel
var oel = 1 * personenzahl;
//
var nudelteig = vermenge(eier, mehl, oel);
}
macheNudelteig(4);
Durch Kommata getrennt dürfen Sie natürlich auch mehrere Parameter übergeben, deren Werte dann in der Funktion als lokale Variablen zur Verfügung stehen. Das folgende Beispiel füllt anhand der Parameter für den Verknüpfungsnamen eines Symbols (engl. Linkage), der Anzahl der Elemente (itemsCount) und der Spaltenzahl (columnsCount) ein Raster mit dem verknüpften Symbol.
Raster aus Objekten
1. |
Verknüpfungsnamen festlegen |
|
|
02_Programmierung\Tabelle
Legen Sie ein Movieclip-Symbol an, und verknüpfen Sie dieses in der Bibliothek mit einem Namen wie z.B. »monster«. Die Verknüpfung (engl. Linkage) legen Sie in der Bibliothek über die Verknüpfungseigenschaften eines Symbols fest.
Hier klicken, um das Bild zu Vergrößern
Abbildung 9.1
Ein Raster aus Objekten
Erstellen Sie im ersten Schlüsselbild der Hauptzeitleiste die Funktion in der folgenden Form:
function createGrid(linkage, itemsCount, columnsCount) {
// Movieclip-Instanz
var item_mc;
// horizontale Schrittweite
var hspace = 80;
// vertikale Schrittweite
var vspace = 80;
// Zähler
var i;
// Erzeuge Gitter
for (i=0; i<itemsCount; i++) {
item_mc = _root.attachMovie(linkage, "item"+String(i), i);
// Berechne Spalte mit Modulo
item_mc._x = (i%columnsCount)*hspace;
// Berechne Zeile
item_mc._y = Math.floor(i/columnsCount)*vspace;
}
}
Um die Funktion nun nutzen zu können, reicht es aus, diese mit den passenden Parametern aufzurufen: createGrid("monster", 20, 6);
Typsicher
Das vorhergehende Beispiel kommt ohne Typisierung aus, was jedoch bei komplexeren Projekten zu Problemen führen kann. Aus diesem Grund ist die folgende Funktion mit Typangaben der Version aus dem Beispiel vorzuziehen:
02_Programmierung\Tabelle mit Modulo
function createGrid(linkage:String, itemsCount:Number,
columnsCount:Number):Void {
// Movieclip-Instanz
var item_mc:MovieClip;
// horizontale Schrittweite
var hspace:Number = 80;
// vertikale Schrittweite
var vspace:Number = 80;
// Zähler
var i:Number;
// Erzeuge Gitter
for (i=0; i<itemsCount; i++) {
item_mc = _root.attachMovie(linkage, "item"+String(i), i);
// Berechne Spalte mit Modulo
item_mc._x = (i%columnsCount)*hspace;
// Berechne Zeile
item_mc._y = Math.floor(i/columnsCount)*vspace;
}
}
9.2.4 arguments-Array
Anzahl und Typ der Parameter einer Funktion sind nicht immer im Vorfeld bekannt. Um bei einem Kochrezept als Beispiel zu bleiben: In einem Fall kann Nudelteig mit Mehl und in einem anderen Fall mit Mehl und Hartweizengrieß gemacht werden:
vermenge(eier, mehl, oel);
vermenge(eier, mehl, hartweizengriess, oel);
Diese beiden Varianten unterscheiden sich nicht nur in der Anzahl der Parameter, sondern auch in deren Bedeutung. Denn der dritte Parameter hat bei der zweiten Variante eine ganz andere Bedeutung als im ersten Fall. Einige Programmiersprachen erlauben hier, dass für jede Art und Weise des Aufrufs (also der Signatur) eine andere Funktion mit demselben Namen erstellt wird. ActionScript kann das leider nicht – auch nicht mit Version 2.0. Doch mit dem arguments-Array naht Hilfe.
Bei dem arguments-Array handelt es sich um ein ganz normales Array (also eine Liste von Werten), das zusätzlich noch über die beiden Eigenschaften callee und caller verfügt.
Der callee enthält die Referenz auf die Funktion selber, um diese z. B. noch einmal rekursiv aufrufen zu können, ohne den Funktionsnamen wissen zu müssen (siehe »Rekursion«, Seite 264). Der caller enthält die Referenz auf die Funktion, von der aus die aktuelle Funktion aufgerufen wurde, um die Herkunft des Aufrufs ermitteln zu können. Sollte die Funktion nicht von einer anderen Funktion aus aufgerufen worden sein, so ist der Wert null.
Überladen von Funktionen
Innerhalb des arguments-Arrays merkt sich Flash alle Parameter des Funktionsaufrufs, so dass das Überladen von Funktionen durch unterschiedliche Signaturen auch in Flash simuliert werden kann:
function vermenge() {
if (arguments.length == 3) {
// Mit Mehl
} else if (arguments.length == 4) {
// Mit Mehl und Hartweizengrieß
} else {
// Unbekanntes Rezept
}
}
Das folgende Beispiel ermittelt abhängig von den übergebenen Parametern eine Zufallszahl:
function ermittleZufallswert () {
02_Programmierung\Arguments Objekt
// Diese Funktion akzeptiert eine obere Schranke oder einen von und bis Bereich
var ergebnis = undefined;
if (arguments.length == 1) {
ergebnis = Math.floor(Math.random()*arguments[0]);
} else if (arguments.length == 2) {
ergebnis = Math.floor(Math.random()*(arguments[1]+1-
arguments[0]))+arguments[0];
}
return ergebnis;
}
// Berechne einen zufälligen Wert zwischen 0 and 9
trace (ermittleZufallswert(10));
// Berechne einen zufälligen Wert zwischen 13 and 20
trace (ermittleZufallswert(13, 20));
Wo finde ich das arguments-Array?
Das arguments-Array ist in der Datei FunctionArguments.as innerhalb des classes-Ordners im Konfigurationsverzeichnis von Flash (siehe 99) definiert.
9.2.5 Rückgabewerte
Funktionen und Methoden dienen häufig nicht nur als Container für immer wiederkehrende Aufgaben, sondern auch als Platzhalter für Werte. Und damit Funktionen einen Wert zurückgeben können, benötigen sie einen Rückgabewert, der mit return angegeben wird.
Movieclip mit der größeren Fläche ermitteln
1. |
Erstellen Sie die Funktion |
|
|
02_Programmierung\Größenvergleich
Die folgende Funktion für den Größenvergleich zweier Movieclips gibt den größeren Movieclip für die weitere Verwendung als Ergebnis zurück:
function maxMovieclip(a_mc, b_mc) {
var a_size = a_mc._width*a_mc._height;
var b_size = b_mc._width*b_mc._height;
if (a_size>b_size) {
return a_mc;
} else {
return b_mc;
}
}
2. |
Verwenden Sie die Funktion |
|
|
Um die Funktion zu verwenden, können Sie diese ganz normal aufrufen und bei Bedarf das Ergebnis sogar in einer Variablen ablegen:
max_mc = maxMovieclip(castle_mc, house_mc);
max_mc._alpha = 50;
Alternativ könnten Sie aber auch die Funktion direkt als Platzhalter für den größeren Movieclip einsetzen:
maxMovieclip(castle_mc, house_mc)._alpha = 50;
Die Ausführung einer return-Anweisung beendet eine Funktion auch dann, wenn noch weitere Anweisungen folgen würden. Deshalb ist ein return auch sehr beliebt, um Funktionsausführungen frühzeitig abzubrechen:
function onEnterFrame() {
02_Programmierung\Funktion Abbrechen
if (mc._x>550) {
return;
}
mc._x += 10;
}
Getter/Setter
Funktionen können sich auch hinter Eigenschaften verbergen. Dies wird oft dann benötigt, wenn eine Eigenschaft Verwendung findet, deren Wert jedoch wie bei einer Funktion berechnet werden muss. Dies erreichen Sie in ActionScript 1 über die für alle Objekte verfügbare Methode addProperty. Mehr Informationen zu Getter-/Setter-Funktionen erhalten Sie im Zusammenhang mit ActionScript 2.0, wo dies deutlich einfacher erstellt werden kann.
9.2.6 Anonyme Funktionen
Nicht immer müssen Funktionen einen Namen tragen. In diesem Fall spricht man dann auch von einer anonymen Funktion. Oft kommt dieses Konzept zum Einsatz, wenn eine Funktion als Parameter übergeben wird (denn eine Funktion ist auch nichts anderes als ein Objekt und kann genauso wie ein Objekt verwendet werden).
Das Array-Objekt bietet z.B. eine Sortierfunktion, die als Parameter eine Funktion erhalten darf:
Liste umgekehrt sortieren
1. |
Erstellen Sie eine Liste |
|
|
Erstellen Sie eine Liste mit Elementen, die sortiert werden sollen:
liste = ["a", "e", "d", "c", "b"];
02_Programmierung\Anonyme Funktion
2. |
Sortieren Sie die Liste umgekehrt |
|
|
Sortieren Sie die Liste mit den Elementen, in dem Sie die sort-Methode aufrufen und dieser eine Funktion für das umgekehrte Sortieren übergeben:
liste.sort(function (a, b) {return (a<b);});
9.2.7 Inline-Schreibweise
Anonyme Funktionen haben neben der Übergabe als Parameter noch einen weiteren Einsatzzweck. Denn mit Hilfe anonymer Funktionen kann eine Funktion einem beliebigen Objekt als Methode zugewiesen werden. Die »normale« Funktionsdeklaration erlaubt nämlich nur die Angabe eines Bezeichners und nicht eines kompletten Pfades zu einem Objekt. Die folgende Funktion ist deshalb nicht erlaubt und erzeugt einen Fehler:
function box_mx.shrink () {
_xscale = _xscale/2;
_yscale = _yscale/2;
}
Aus diesem Grund bietet es sich an, einer beliebigen Eigenschaft eines Objektes einfach eine anonyme Funktion zuzuordnen:
box_mx.shrink = function () {
_xscale = _xscale/2;
_yscale = _yscale/2;
}
Eine Besonderheit der Inline-Schreibweise ist, dass die Funktion erst von dem Zeitpunkt an zur Verfügung steht, ab dem sie erstellt wurde. Dies ist anders als bei normalen Funktionen, die unabhängig von ihrer Position in einem Skript von Anfang an bereitstehen:
// tut nichts, da vor der Deklaration
tuwas();
// Inline-Schreibweise
tuwas = function () {
trace("tut was");
};
// tut was
tuwas();
Alternative zur Inline-Schreibweise
Ebenfalls sehr beliebt ist es, eine Funktion auf die herkömmliche Weise zu deklarieren und diese dann nachträglich einem Objekt zuzuweisen:
function shrink () {
_xscale = _xscale/2;
_yscale = _yscale/2;
}
box_mx.shrink = shrink;
Diese Variante hat jedoch den Nachteil, dass es dann zwei Referenzen auf die Funktion gibt (die in der Zeitleiste platzierte Referenz und die in dem Objekt definierte Eigenschaft).
9.2.8 Funktionsobjekt
Jede Funktion ist gleichzeitig ein Objekt und besitzt somit ähnliche Fähigkeiten wie ein Objekt. Erst wenn diese Art von Objekt mit nachfolgenden Klammern aufgerufen wird, versucht Flash, dieses Objekt als Funktion auszuführen. D.h. auch einer Funktion kann eine Eigenschaft oder eine Methode zugeordnet werden.
Eine vordefinierte Eigenschaft aller Funktionen ist prototype. Diese Eigenschaft wird für die objektorientierte Programmierung benötigt. Zu den vordefinierten Methoden zählt toString(), die eine Funktion in eine Zeichenkette umwandelt (normalerweise ist das Ergebnis von funktion.toString(); die Zeichenkette "[type Function]").
Weitere Methoden jeder Funktion sind call(); und apply();. Diese erlauben es, eine Funktion in einem anderen Kontext zu verwenden. So können die Anweisungen innerhalb der Funktion über das Schlüsselwort this auf diesen neuen Kontext zugreifen.
function shrink() {
02_Programmierung\Funktion als Objekt
this._xscale = this._xscale/2;
this._yscale = this._yscale/2;
}
// Verkleinere die Anwendung
shrink();
// Verkleinere den Movieclip
// (ändere die Referenz this in der Funktion von der Hauptzeitleiste auf box_mc)
shrink.call(box_mc);
shrink.apply(box_mc);
Die beiden Methoden unterscheiden sich sonst nur durch die Art und Weise, wie weitere Parameter anzugeben sind, die an die Funktion gesendet werden. Bei call legen Sie die Parameter durch Kommata getrennt fest, bei apply fügen Sie ein Array an:
function move(x, y) {
this._x = this._x+x;
this._y = this._y+y;
}
// Bewege den Movieclip
move.call(box_mc, 10, 10);
move.apply(box_mc, [10, 10]);
Wo finde ich das Funktionsobjekt?
Das Funktionsobjekt ist in der Datei Function.as innerhalb des classes-Ordners im Konfigurationsverzeichnis von Flash definiert.
|