Actionscript
Markus WalthertMit ActionScript ein Objekt aus der Bibliothek laden
Mausbewegung mit Flash onEnterFrame
Objekte in Flash vervielfältigen (for-Schleife)
Movieclip Array in Flash (verschachtelte for-Schleife)
Objekte in Flash spiralförmig anordnen
Objekte in Flash spiralförmig anordnen (2)
Mit ActionScript eine Linie erzeugen
Farben im Hexadezimalsystem
Clear background, Linienpunkt in ActionScript
Linien in ActionScript bewegen
Bezier-Kurven in ActionSript
Mit ActionScript ein Polygon erstellen
Schieberegler mit ActionScript
Drehregler mit ActionScript
Mit ActionScript Objekt aus der Bibliothek laden
Man muss ein Bibliotheksobjekt nicht erst auf der Bühne zeichnen und dann als Symbol konvertieren, es kann auch direkt in der Bibliothek erstellt werden.
Ist das Objekt nicht physisch auf der Bühne vorhanden, sondern wird (z.B. wegen der Übersichtlichkeit) per Script in einen MovieClip geladen, muss bei den Symboleigenschaften die Verknüpfung “Export für ActionScript” gesetzt sein. Ein Instanznamen (im Eigenschaftsfenster) ist hingegen nicht mehr erforderlich.
Möglichst wird der Code nur in der Root, also die unterste Ebene geschrieben. Von da aus könne praktisch alle Objekte mit ihrem Instanznamen (hier “circle”) gefolgt von einem Punkt aufgerufen werden.
// vgl. Help: createEmptyMovieClip....'kreis' entspricht dem Bibliotheksnamen, 1 ist die Ebene circle = this.createEmptyMovieClip('kreis', 1); // Dem Objekt circle wird das Bibliotheksobjekt 'kreis' angefügt, // das zweite 'kreis' ist ein frei definierbarer Begriff und entspricht dem // Instanznamen für das angefügte Objekt. Da die Hier aber direkt der // Variable mc übergeben wird, muss man hier nicht mit dem Instanznamen arbeiten. var mc = circle.attachMovie('kreis', 'kreis', 1); mc._x = Stage.width/2; mc._y = Stage.height/2; mc._xscale = mc._yscale = _xmouse;
Mausbewegung mit Flash onEnterFrame
circle = this.createEmptyMovieClip('kreis', 1); var mc = circle.attachMovie('kreis', 'kreis', 1); mc._x = Stage.width/2; mc._y = Stage.height/2; //Der Wechsel der FrameRate im Eigenschaftsfenster beeinflusst den Renderzyklus circle.onEnterFrame = function() { mc._xscale = mc._yscale=_xmouse; };
Objekte in Flash vervielfältigen (for-Schleife)
Eine for-Schleife beinhaltet in der Klammer die drei Anweisungen:
* Startwert mit der die Schleife beginnen soll
* Bedingung, wie lange die Schleife ausgeführt werden soll
* Inkrement (oder Dekrement), hier wird die variable i in jedem Durchlauf um 1 vergrößert
var numKreise = 30; circle = this.createEmptyMovieClip('kreis', 1); for (i=0; i<numKreise; i++) { var mc = circle.attachMovie('kreis', 'kreis'+i, 1+i); } for (i=0; i<numKreise; i++) { mc = circle['kreis'+i]; mc._x = Stage.width/numKreise*i; mc._y = Stage.height/2; }
Movieclip Array in Flash (verschachtelte for-Schleife)
Ein Array ist eine Variable die über jeden Arrayindex verschiedene Werte abspeichern kann. Der Arrayindex ist die Zahl in der eckigen Klammer und beginnt immer mit 0.
var numKreise = 30; circle = this.createEmptyMovieClip('kreis', 1); var lines = Math.sqrt(numKreise); lines = Math.floor(lines); var circPerLine = Math.round(numKreise/lines); counter = 0; var mc = new Array(numKreise); for (i=0; i<=lines; i++) { for (ii=1; ii<=circPerLine; ii++) { mc[counter]._x = Stage.width/circPerLine*ii-(Stage.width/circPerLine/2); mc[counter]._y = (Stage.height/lines)*i-(Stage.height/lines/2); counter++; } }
Objekte in Flash spiralförmig anordnen
Variante ohne Radians-Umrechnung
var numKreise = 30; circle = this.createEmptyMovieClip('kreis', 1); var initRadius = 1; initScale = 170; initFac = 40; //Center Point cx = Stage.width/2; cy = Stage.height/2; mc = new Array(numKreise); for (var i = 0; i<numKreise; i++) { mc[i] = circle.attachMovie('kreis', 'kreis'+i, 1+i); } PositionCircles = function () { for (var i = 0; i<numKreise; i++) { mc[i]._y = Math.sin(i)*(initRadius+i+initFac)+cy; mc[i]._x = Math.cos(i)*(initRadius+i+initFac)+cx; mc[i]._xscale = mci._yscale=initScale; } }; PositionCircles(); //Das ganze denne noch mit der Maus steuern... circle.onEnterFrame = function() { initScale = _xmouse; initFac = _ymouse; PositionCircles(); };
Objekte in Flash spiralförmig anordnen (2)
var numKreise = 30; circle = this.createEmptyMovieClip('kreis', 1); var initRadius = 1; initScale = 170; initFac = 40; //Center Point cx = Stage.width/2; cy = Stage.height/2; mc = new Array(numKreise); //die winkel nicht einfach aus der Variable i berechnen sondern mit radians und Anzahl Umdrehungen var turns = 30; var angle = 2*Math.PI/numKreise*turns; for (var i = 0; i<numKreise; i++) { mc[i] = circle.attachMovie('kreis', 'kreis'+i, 1+i); } PositionCircles = function () { mc[i]._y = Math.sin(i*angle)*(initRadius+i+initFac)+cy; mc[i]._x = Math.cos(i*angle)*(initRadius+i+initFac)+cx; mc[i]._xscale = mc[i]._yscale=initScale; }; PositionCircles(); //Das ganze denne noch mit der Maus steuern... circle.onEnterFrame = function() { initScale = _xmouse; initFac = _ymouse; PositionCircles(); };
Mit ActionScript eine Linie erzeugen
this.createEmptyMovieClip("line",1); line.lineStyle(0,0xa69a9a,100); for (i=0; i<Stage.height; i += 10) { line.moveTo(0,0); line.lineTo(Stage.width,i); } line.onEnterFrame = function() { line.lineStyle(10,0xdbd8d8,20); line.moveTo(_xmouse,_ymouse); line.lineTo(Stage.width,Stage.height); };
Der Farbwert in Hexadezimal ist ein RGB Wert. Hexadezimalzahlen sind:
0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,10,11,12…19,1A,1B,…1E,1F,20….., FF entspricht dem Wert 255.
0x zeigt dem Script an, dass eine Hex Zahl folgt. Die in Hex-Werten zweistelligen r/g/b Werte folgen paarweise.
1/
this.createEmptyMovieClip("line",1); //erst einfach die Linie mit runden Ecken, dann die zusätzlichen Parameter für die Linienenden onEnterFrame = function () { line.lineStyle(50,0xa69a9a,100); line.moveTo(Stage.width/2,40); line.lineTo(Stage.width/2,Stage.height-40); };
2/
this.createEmptyMovieClip("line",1); onEnterFrame = function () { function dec2hex(dec:Number):String { //rot //return "0x"+dec.toString(16)+"0000"; //green //return "0x00"+dec.toString(16)+"00"; //blue return "0x"+dec.toString(16); } line.lineStyle(50,dec2hex(_ymouse),100,true,"normal","square"); line.moveTo(Stage.width/2,40); line.lineTo(Stage.width/2,Stage.height-40); };
3/
this.createEmptyMovieClip("line",1); onEnterFrame = function () { function dec2hex(dec:Number):String { //rot //return "0x"+dec.toString(16)+"0000"; //green //return "0x00"+dec.toString(16)+"00"; //blue return "0x"+dec.toString(16); } line.lineStyle(50,dec2hex(255/Stage.height*_ymouse),100,true,"normal","square"); line.moveTo(Stage.width/2,40); line.lineTo(Stage.width/2,Stage.height-40); };
4/
this.createEmptyMovieClip("line",1); onEnterFrame = function () { //Farbe aus xmouse und ymouse zusammensetzen function dec2hex2(dec:Number):String { return dec.toString(16); } col = "0x"+dec2hex2(_xmouse)+dec2hex2(_ymouse)+"00"; line.lineStyle(50,col,100,true,"normal","square"); line.moveTo(Stage.width/2,40); line.lineTo(Stage.width/2,Stage.height-40); };
5/
//Hexadezimal in Dezimalzahl umrechnen function hex2dec(hex:String):Number { return Number(hex); }
Clear background, Linienpunkt in ActionScript
Wird onEnterFrame ein Linienpunkt z.B. mit der Maus bewegt, baut sich in Flash der Hintergrund nicht in jedem Renderzyklus neu auf sondern die Bewegung wird in den selben Movie Clip addiert.
Die gängige Möglichkeit dies zu umgehen ist die Methode clear(), die jedoch in diesem Beispiel mit einer dicken Linie mit Linestyle Corner nicht den kompletten erforderlichen Bereich übermalt. Eine mögliche Abhilfe ist, eine Funktion zu definieren und abzurufen, die bei jedem Renderzyklus einen selber definierten Hintergrund malt.
Variablen und Funktionen sind in diesem Codebeispiel korrekt deklariert indem hinter dem “:” die Typen benannt werden.
ActionScript bietet uns die Methode showRedrwaRegions bereits an. Diese dient zur Kontrolle, welche Bereiche der Bühne je Renderzyklus neu gezeichnet werden.
var a:Number; var b:Number; var line:MovieClip = drawLine("line", a, b); line.onEnterFrame = function():Void { //mit clear() wird nicht der komplette Bereich der Line neu gemalt, die Ecken bei //LineStyle Corner werden nicht neu gemalt... //this.clear(); a = _xmouse; b = _ymouse; changeBG(0x333333); drawLine(name,_xmouse,_ymouse); }; //Bei einer Linie mit Ecken schauen diese etwas über den RedrawBereich heraus "round" ist komplett innerhalb des Redraw Bereiches //_global.showRedrawRegions(true); function drawLine(name:String, a:Number, b:Number):MovieClip { var drawer:MovieClip = this.createEmptyMovieClip(name, this.getNextHighestDepth()); //die Deklaration des Liniestils muss in jedem Zyklus erfolgen drawer.lineStyle(50,0xa69a9a,100,true,"normal","square"); drawer.moveTo(a,b); drawer.lineTo(Stage.width,Stage.height); return drawer; } function changeBG(col:Number) { var bg:MovieClip = this.createEmptyMovieClip(name, this.getNextHighestDepth()); bg.moveTo(0,0); bg.beginFill(col); bg.lineTo(Stage.width,0); bg.lineTo(Stage.width,Stage.height); bg.lineTo(0,Stage.height); }
Linien in ActionScript bewegen
Da am Ende mehrere Linien bewegt werden sollen, wird gleich ein Array für die Linien erzeugt, wo hier aber nur der Array-Index 0 verwendet wird
1/
var lineArr = new Array(); lineArr[0] = this.createEmptyMovieClip("lines", this.getNextHighestDepth()); onEnterFrame = function () { moveTheLines(); }; function moveTheLines() { lineArr[0].lineStyle(1,0xa69a9a,100); lineArr[0].moveTo(Stage.width/2,50); lineArr[0].lineTo(Stage.width/2,Stage.height-50); lineArr[0]._x++; }
2/
Mit mehreren Linien (numLines)
onEnterFrame = function () { moveTheLines(); }; function moveTheLines() { for (i=0; i<numLines; i ++) { if (lineArr[numLines-1]._x<Stage.width/2) {//Damit die Linien nicht endlos wandern lineArr[i].lineStyle(1,0xa69a9a,100); lineArr[i].moveTo(Stage.width/2,50); lineArr[i].lineTo(Stage.width/2,Stage.height-50); xPos += 1; lineArr[i]._x = xPos/i; } } }
3/
onMouseDown wird der komplette Array gelöscht und die Bewegung wird neu erzeugt. Die Spiegelung wird dadurch erreicht, dass je Schleifendurchlauf ein Inkrement um zwei erzueugt wird und die eine nach links und die andere nach rechts bewegt wird.
var lineArr = new Array(); var numLines = 90; var xPos = 0; var offset = 30; button = true; for (i=0; i<numLines; i++) { lineArr[i] = this.createEmptyMovieClip("lines", this.getNextHighestDepth()); } onEnterFrame = function () { if (button) { moveTheLines(); } else { button = true; xPos = 0; } }; function moveTheLines() { for (i=0; i<numLines; i += 2) {//die ungeraden gehen nach rechts, die geraden nach links if (lineArr[numLines-1]._x<Stage.width/2) { lineArr[i].lineStyle(1,0xa69a9a,100); lineArr[i].moveTo(Stage.width/2-offset,50); lineArr[i].lineTo(Stage.width/2-offset,Stage.height-50); xPos += 1; lineArr[i]._x = xPos/i; //spiegeln lineArr[i+1].lineStyle(1,0xa69a9a,100); lineArr[i+1].moveTo(Stage.width/2+offset,50); lineArr[i+1].lineTo(Stage.width/2+offset,Stage.height-50); lineArr[i+1]._x = -xPos/i; } } } onMouseDown = function () { button = false; clearLines(); }; function clearLines() { for (i=0; i<numLines; i++) { lineArr[i].clear(); } }
Gerade Linien radial anordnen, das Zentrum ist in der Mitte der Bühne.
1/
var lineArr = new Array(); var numLines = 50; //var angle = 360/numLines;--> FALSCH! Winkel werden in radian berechnet, ein Vollkreis ist 2*PI var angle = 2*Math.PI/numLines; var radius = 120; for (i=0; i<numLines; i++) { lineArr[i] = this.createEmptyMovieClip("lines", this.getNextHighestDepth()); lineArr[i].lineStyle(1,0xa69a9a,100,true,"normal","square"); xPos = (Math.cos(i*angle))*radius; yPos = (Math.sin(i*angle))*radius; lineArr[i].moveTo(Stage.width/2,Stage.height/2); lineArr[i].lineTo(Stage.width/2+xPos,Stage.height/2+yPos); }
Mit CurveTo() und einem zusätzlichen Punkt, dem Haltepunkt wird eine gerade Linie zur Kurve,
Bezierkurve in ActionScript
Alle Haltepunkte beziehen sich auf die selbe Mausposition.
2/
var lineArr = new Array(); var numLines = 50; var angle = 2*Math.PI/numLines; var radius = 120; onEnterFrame = function () { for (i=0; i<numLines; i++) { lineArr[i].clear(); } for (i=0; i<numLines; i++) { lineArr[i] = this.createEmptyMovieClip("lines", this.getNextHighestDepth()); lineArr[i].lineStyle(1,0xa69a9a,100,true,"normal","square"); xPos = (Math.cos(i*angle))*radius; yPos = (Math.sin(i*angle))*radius; lineArr[i].moveTo(Stage.width/2,Stage.height/2); //alle Kurven werden durch die selbe Mausposition beeinflusst lineArr[i].curveTo(_xmouse,_ymouse,Stage.width/2+xPos,Stage.height/2+yPos); } };
Es wird ein Haltepunkt berechnet, der die Linien individuell beeinflusst. Dazu wird entsprechend der Lage im Kreis eine Winkelabweichung und die daraus resultierende X/Y Abweichung berechnet.
3/
var lineArr = new Array(); var numLines = 50; var angle = 2*Math.PI/numLines; var radius = 120; var xMouseAberration; var yMouseAberration; var angleAberration; onEnterFrame = function () { for (i=0; i<numLines; i++) { lineArr[i].clear(); } xMouseAberration = _xmouse-Stage.width/2; yMouseAberration = _ymouse-Stage.height/2; angleAberration = Math.tan(yMouseAberration/xMouseAberration); for (i=0; i<numLines; i++) { lineArr[i] = this.createEmptyMovieClip("lines", this.getNextHighestDepth()); lineArr[i].lineStyle(1,0xa69a9a,100,true,"normal","square"); xPos = (Math.cos(i*angle))*radius; yPos = (Math.sin(i*angle))*radius; lineArr[i].moveTo(Stage.width/2,Stage.height/2); //Die Mausposition wird für jede Linie individuell berechnet xPosHandle = Math.cos(i*angle+angleAberration)*xMouseAberration+Stage.width/2; yPosHandle = Math.sin(i*angle+angleAberration)*yMouseAberration+Stage.height/2; lineArr[i].curveTo(xPosHandle,yPosHandle,Stage.width/2+xPos,Stage.height/2+yPos); } };
Mit ActionScript ein Polygon erstellen
Und über Tastatureingabe die Anzahl der Ecken steuern
Das gleichmäßige Polygon wird errechnet anhand der Seitenlänge und dem Winkel aus der Startposition (posX/posY) zu zwei Ecken. In einer for-Schleife wird ausgehend vom Startpunkt das Polygon abgearbeitet.
1/
var posX = 200;//Startpunkt X var posY = 150;//Startpunkt Y var len = 100;//Seitenlänge var corner = 8;//Anzahl der Ecken this.moveTo(posX+len,posY); this.lineStyle(0,0xcccccc,100); for (var i = 0; i<=corner; i++) { //Die Summe der eingeschlossenen Winkel sind 360 Grad (2*PI) var angle = Math.PI*2/corner*i; var x = Math.cos(angle)*len; var y = Math.sin(angle)*len; this.lineTo(posX+x,posY+y); }
2/
Mit einer Polygon-Funktion kann ein beliebiges Polygon erzeugt werden.
MovieClip.prototype.myPoly = function(fill, trans, col, corner, len, posX, posY) { this.clear(); this.moveTo(posX+len,posY); this.lineStyle(0,0xcccccc,100); if (fill) { this.beginFill(col,trans); } for (var i = 0; i<=corner; i++) { var angle = Math.PI*2/corner*i; var x = Math.cos(angle)*len; var y = Math.sin(angle)*len; this.lineTo(posX+x,posY+y); } }; this.myPoly(true,30,0xff0000,6,100,200,150);
3/
Ein KeyListener wartet auf eiene Eingabe auf der Tastatur. Wenn der Keycode minus 48 gerechnet wird, erhält man für die obere Zahlenreihe auf einer Standardtastatur den jeweiligen Zahlenwert der an die Polygonfunktion übergeben wird.
var keyListener:Object = new Object(); keyListener.onKeyDown = function() { //trace("Virtual key code: "+Key.getCode()); myPoly(true,30,0xff0000,Key.getCode()-48,100,200,150); }; Key.addListener(keyListener); //Prototype ist statisch, kann aberr mit _proto_ von anderen Klassenaus aufgerufen werden MovieClip.prototype.myPoly = function(fill, trans, col, corner, len, posX, posY) { this.clear(); this.moveTo(posX+len,posY); this.lineStyle(0,0xcccccc,100); if (fill) { this.beginFill(col,trans); } for (var i = 0; i<=corner; i++) { var angle = Math.PI*2/corner*i; var x = Math.cos(angle)*len; var y = Math.sin(angle)*len; this.lineTo(posX+x,posY+y); } };
Schieberegler mit ActionScript
Das Resultat des Schiebereglers (Y-Position) wird in ein dynamisches Textfeld ausgegeben.
var sApp = this.createEmptyMovieClip('sliderApp', 1); var handlePos; //Line numerisch - genaer Anfang- und Endpunkt sApp.lineStyle(2,0xCCCCCC,100); sApp.moveTo(100,50); sApp.lineTo(300,50); //. Der Griff des Sliders ist in der Bibliothek erstellt var handle = sApp.attachMovie('sliderHandle', 'sliderApp', 2); handle._x = 100; handle._y = 50; handle._xscale = handle._yscale=30; //AusgabeTextfeld var txt = sApp.attachMovie('outputTXT', 'sliderApp', 3); txt._x = 100; txt._y = 100; handle.onPress = function() { this.startDrag(0,100,this._y,300,this._y); }; handle.onRelease = function() { this.stopDrag(); }; handle.onReleaseOutside = function() { this.stopDrag(); }; onEnterFrame = function () { txt.txtValue.text = handle._x; };
Drehregler sind mit der Maus eher schwer zu bedienen, eignen sich aber z.B. bei Anwendungen mit starker Analogie wie etwa zum einstellen der Beleuchtungsrichtung für einen DropShadow. Entsprechend können Drehregler unterschiedliche Bedienkonzte beinhalten. Für nachfolgendes Beispiel soll gelten:
* Der Drehvorgang kann nur ausgelöst werden, wenn die Maus auf dem Drehknopf liegt
* Der Regler muss am Griff gepackt werden, dieser soll nicht automatisch zur Mausposition springen
* Der Drehvorgang wird so lange ausgeführt, wie die Maustaste gedrückt bleib, also auch außerhalb des Reglers.
* Zusätzlich soll der Regler per Pfeiltasten ansteuerbar sein
var sApp = this.createEmptyMovieClip('sliderApp', 1); var stat = false; var xPos, yPos; var angle_r, angle_d; //Handle aus der Bibliothek var handle = sApp.attachMovie('turnerHandle', 'sliderApp', 2); handle._x = 130; handle._y = 70; handle._xscale = handle._yscale=60; //Ausgabe auf ein dyamisches Textfeld var txt = sApp.attachMovie('outputTXT', 'sliderApp', 3); txt._x = 100; txt._y = 150; handle.onPress = function() { stat = true; angle_d = handle._rotation; }; handle.onRelease = function() { stat = false; }; handle.onReleaseOutside = function() { stat = false; }; handle.onMouseMove = function() { if (stat) { xPos = _xmouse-handle._x; yPos = _ymouse-handle._y; angle_r = Math.atan2(yPos,xPos); //in deg umrechnen und 90 grad dazuzählen (0-punkt oben vs. 0-punkt rechts) angle_d = Math.round(angle_r/Math.PI*180)+90; handle._rotation = angle_d; } }; handle.onEnterFrame = function() { txt.txtValue.text = handle._rotation; }; //Das ganze ist auch über die ArrowKeys ansteuerbar, da reicht "_rotation++/--" var keyListener:Object = new Object(); keyListener.onKeyDown = function() { if (Key.getCode() == 37) {//Arrow Left handle._rotation -= 10; } if (Key.getCode() == 39) {//Arrow Right handle._rotation += 10; } }; Key.addListener(keyListener);