Vektorfeld
Mittels ActionScript soll eine kleine Flash-Anwendung programmiert werden, die als graphische Oberfläche ein Feld von Pfeilen enthalten soll, die sich nach der Position des Mauszeigers ausrichten – als stellten diese Pfeile Kompassnadeln dar. Zur Umsetzung dieser Anwendung werden folgende ActionScript-Themen behandelt:
1.) Das Einbinden eines MovieClip-Objekts
2.) Das Vervielfältigen eines MovieClip-Objekts
3.) Das interaktive Reagieren auf Mausereignisse
Zunächst muss eine kleine Grafik in Form eines Pfeils erstellt werden (beispielsweise mit Photoshop). Ich habe hierfür eine quadratische Zeichenfläche mit einer Seitenlänge von 25 Pixeln gewählt und das Bild im PNG-24-Format mit transparentem Hintergrund abgespeichert. Der Pfeil in dieser Ausgangsgrafik zeigt dabei noch Norden.
1.) Das Einbinden eines MovieClip-Objekts
Nun wird diese Grafik in den Flash-Editor importiert und an beliebiger Stelle im ersten Frame der ersten Schicht abgelegt (als Maße für die Bühne habe ich 400 x 300 Pixel gewählt und eine Frame-Rate von 60 eingestellt; diese erste Schicht habe ich in Preparation
umbenannt). Als nächstes muss diese Grafik in ein MovieClip-Objekt umgewandelt (Convert Symbol to... → MovieClip) und mit einem Instanznamen gekennzeichnet werden; ich habe diese Instanz Arrow
genannt. Wichtig ist hiernach, dass das Rotationszentrum dieses MovieClips ggf. manuell so angepasst wird, dass es in der Mitte des Clips liegt – sofern dies nicht bereits der Fall ist. Um das Rotationszentrum anzupassen, muss der MovieClip in den Edit-Modus gebracht werden (doppelt mit der linken Maustaste anklicken). Hier muss die Grafik dann relativ zum ursprünglichen Zentrum (gekennzeichnet durch ein statisches Kreuz) so verschoben werden, dass dieses Zentrum nun in der Mitte der Grafik liegt.
2.) Das Vervielfältigen eines MovieClip-Objekts
Mit dem nächsten Schritt beginnt die eigentlich Programmierung, wofür eine weitere Schicht hinzugefügt wird, die ich Stage
genannt habe. Zunächst soll unser MovieClip, welcher den Pfeil repräsentiert, vervielfältigt werden, so dass im Endergebnis eine Matrix mit 17 x 13 Pfeil-Elementen entsteht, die die gesamt sichtbare Fläche der Flash-Anwendung ausfüllt. Dies wird durch eine doppelte for
-Schleife erreicht:
for(i = 0;i < 17; i++)
{
for(j = 0;j < 13;j++)
{
duplicateMovieClip(Arrow,"Arrow"+(i*13+j),(i*13+j));
setProperty("Arrow" + (i*13+j),_x,i*25);
setProperty("Arrow" + (i*13+j),_y,j*25);
}
}
Die innerhalb der Schleife verwendete Methode duplicateMovieClip()
leistet hierbei die Vervielfältigung des ursprünglichen MovieClips Arrow
. Dieser Methode müssen drei Argumente übergeben werden, wobei das erste Argument auf den zu vervielfältigenden MovieClip verweist (hier Arrow
), das zweite Argument den neuen Instanznamen generiert (hier nenne ich alle weiteren Kopien von Arrow
ebenfalls Arrow
und hänge ihnen einen numerischen Index an) und das dritte Argument die Tiefenebene einer jeden Kopie repräsentiert. Für den Namensindex der Kopien (z.B. Arrow17
) wie für die Angabe der zugehörigen Tiefenebene verwende ich jeweils denselben Wert, der für jede folgende Kopie bei jedem Schleifendurchgang einfach inkremeniert wird (i*13+j
). Im Endergebnis wurden also genau 221 Kopien unseres ursprünglichen MovieClip-Objekts hergestellt, deren Instanznamen Arrow0
, Arrow1
, ..., Arrow220
lauten.
Mit den nächsten beiden Codezeilen innerhalb des Schleifenkörpers wird jedem dieser 221 MovieClips seine x- und y-Position im Fenster zugewiesen: Der Methode setProperty()
muss dabei jeweils der Instanzname des MovieClips übergeben werden, sowie die Eigenschaft, die gesetzt werden soll (im vorliegenden Fall also _x
, bzw. _y
) und natürlich der Wert dieser Eigenschaft (hier die Pixelkoordinaten innerhalb des Fensters).
3.) Das interaktive Reagieren auf Mausereignisse
Mit diesen Schritten haben wir also bereits das gesamte Fenster unserer Flash-Anwendung mit Pfeilen gefüllt – jedoch zeigen diese alle noch nach Norden. Als nächstes muss also Interaktivität ins Spiel gebracht werden, wozu zunächst eine eigene Funktion programmiert werden muss. Aufgabe dieser Funktion wird es sein, ausgehend von der aktuellen Position des Mauszeigers, jedem MovieClip-Element seine neue Orientierung zuzuweisen:
function adjustOrientation(xm:Number,ym:Number):Void
{
for(i = 0;i < 221;i++)
{
var x:Number = getProperty("Arrow"+i,_x);
var y:Number = getProperty("Arrow"+i,_y);
var a:Number = xm - x;
var b:Number = ym - y;
var alpha:Number = 180*Math.atan(a/b)/Math.PI;
if(ym < y)
setProperty("Arrow"+i,_rotation,-alpha);
else
setProperty("Arrow"+i,_rotation,180-alpha);
}
}
Ich habe dieser Funktion den Namen adjustOrientation
; gegeben und so aufgebaut, dass ihr zwei Argumente übergeben werden müssen: xm
und ym
, welche für die absolute x- und y-Position des Mauszeigers stehen. Der eigentliche Code zur Berechnung der neuen Orientierung der einzelnen Pfeil-Elemente ist wieder in eine Schleife eingebunden. Dieses Mal habe ich jedoch keine Doppelschleife verwendet (wie beim vorangegangenen Kopiervorgang), sondern eine einfache Schleife, da ich die Instanznamen für die Kopien ja so vergeben habe, dass sie eine Reihe von 0-220 bilden.
Die Mathematik, die ich für die Berechnung der neuen Orientierungen der Pfeile benutzt habe, ist einfache Trigonometrie und soll daher nur kurz umrissen werden. Die Variablen x
und y
repräsentieren die x- und y-Koordinaten eines jeden MovieClips und werden mithilfe der Methode getProperty(Instanzname des MovieClips, Eigenschaft)
ermittelt. Die Variablen a
und b
repräsentieren den horizonzalen (a
), bzw. vertikalen Abstand (b
) zwischen dem jeweiligen MovieClip und der Mauszeiger-Position. Mit diesen Werten wird ein rechtwinkliges Dreieck aufgespannt, wobei die Hypotenuse die Strecke zwischen der Mauszeigerposition und dem jeweiligen MovieClip repräsentiert. Mit diesen Werten kann ich nun den Winkel zwischen der Mauszeigerposition und dem jeweiligen MovieClip bestimmen, der in der Variablen alpha
gespeichert wird. Zum Schluss muss noch eine Fallunterscheidung durchgeführt werden, da die Zuweisung von Rotationen mithilfe der hier verwendeten Methode setProperty()
in Abhängigkeit vom Vorzeichen des übergebenen Winkels, entweder im Uhrzeigersinn, oder gegen den Uhrzeigersinn erfolgt.
Diese Funktion muss nun mit einem Maus-Ereignis verbunden werden, denn eine Änderung der Orientierung jeder einzelnen Kompassnadel soll jedes Mal erfolgen, wenn sich die Position des Mauszeigers innerhalb des Fensters ändert. Am einfachsten fand ich hierfür die folgende Vorgehensweise: Auf der Schicht Preparation
habe ich einfach ein weiteres Symbol an beliebiger Stelle eingefügt (ein einfaches graphisches Objekt, beispielsweise ein Quadrat) und es in einen MovieClip konvertiert. Einem solchen MovieClip-Objekt kann man eine Vielzahl von vordefinierten Maus-, bzw. Tastatur-Ereignissen zuweisen, d.h. jedes Mal, wenn ein solches Ereignis eintritt (wie eine Mausbewegung oder das Loslassen einer bestimmten Taste), wird dieses vom Programm registriert und der sogenannte “event handler” aufgerufen, der mit diesem Ereignis verbunden ist. Für unsere Zwecke benötigen wir also das Ereignis “Mausbewegung”: Wir klicken in der Schicht Preparation
; den gerade hinzugefügten MovieClip an, dem ich zuvor den Instanznamen Empty
gegeben habe und wähle dann im ActionScript-Interface in der Auswahl die Option mouseMove
aus. Sofort erscheint im Code-Fenster die noch leere Methode onClipEvent(mouseMove) { }
, die nur noch mit etwas eigenem Code befüllt werden muss:
onClipEvent(mouseMove)
{
var mx:Number = _level0._xmouse;
var my:Number = _level0._ymouse;
_level0.adjustOrientation(mx,my);
}
Dieser Code ist sehr einfach aufgebaut: Zunächst habe ich zwei interne Variablen defniert, welche die x- und die y-Position des Mauszeigers innerhalb des Fensters repräsentieren. Die aktuellen Positionswerte der Maus werden hierbei mit der Eigenschaft _xmouse
, bzw. _ymouse
abgefragt. Zu beachten ist hierbei, dass diesen beiden Funktionen die Levelspezifikation _level0.
vorangestellt werden muss, damit die globale Mausposition erfasst wird, d.h. die Mausposition innerhalb des gesamten Anzeigefensters. Würde man diese Leveldefinition weglassen oder stattdessen ein this.
voranstellen, würde nicht die globale Mausposition erfasst sondern die Position der Maus relativ zur Position des MovieClip-Objekts Empty
. Probieren Sie das einfach einmal aus! Als letztes wird nun mit diesen beiden Werden die zuvor definierte Funktion adjustOrientation(mx,my)
aufgerufen, die ja die eigentliche Arbeit leistet, indem sie für jeden Pfeil innerhalb des Fensters die neue Orientierung berechnet und den MovieClip-Objekten zuweist. Auch hier ist zu beachten, dass auf das übergeordnete Level mittels _level0.
verwiesen werden muss, denn andernfalls wäre dem MovieClip-Objekt Empty
; diese Funktion gar nicht bekannt.
Mit diesen Schritten ist die Funktionalität unserer Flash-Anwendung bereits voll implementiert: Starten Sie die Anwendung im Vorschaufenster und lassen Sie den Mauszeiger über das Fenster wandern. Die Pfeile richten sich immer nach der aktuellen Position des Mauszeigers aus. Einen Schönheitsfehler hat die Anwendung jedoch noch, denn es sind im Fenster noch das ursprüngliche MovieClip-Objekt Arrow
und das Objekt Empty
zu sehen. Diese werden nun mit einem letzten Codeblock unsichtbar gemacht, der in das ActionScript-Fenster der Schicht Preparation
; eingefügt wird:
setProperty("Arrow",_visible,false);
setProperty("Empty",_visible,false);
Wieder nutzen wir hierfür die Methode setProperty()
und übergeben ihr jeweils den Instanznamen des MovieClip-Objekts (Arrow
, bzw. Empty
;), dann die zu modifizierende Eigenschaft _visible
und den Wert false
.
© 2011 G. Wendt
Sie haben Schwierigkeiten damit, die richtige Farb- kombination und passende Schriftformate für Ihren Web-Auftritt zu finden?
Nutzen Sie das Werkzeug Farbe & Schrift auf dieser Website, um interaktiv die Farb- und Schrifteigenschaften für Ihre eigene Seite zu gestalten. Das Ergebnis Ihrer Einstellungen können Sie einfach als CSS-Format in Ihr Webprojekt einbinden.
M | D | M | D | F | S | S |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |