Pastor Pixel Tipps Tutorial Anleitungen Hilfe

Programmierte Bewegung

Hier geht es um programmierte Bewegungen mit AS3. Ich verzichte hier mal auf die einfachen Beispiele, die man in meinen AS2 Tipp zu diesem Thema findet, da es nicht schwierig ist, diese Programmierungen in AS3 umzusetzen.

Tipp

Weitere verwandte Themen:
Spirograph
Trigonometrie
Timer

ACHTUNG !!!
Einige Tasten wie ENTER kann man nicht in der Entwicklungsumgebung testen.

stage.addEventListener(KeyboardEvent.KEY_DOWN, KeyDownFunc);

function KeyDownFunc(evt){

anzeige.text=String(evt.keyCode);
if(event.keyCode == Keyboard.ENTER){
anzeige.text=String("ENTER");
}

}

Prozentrechnung oder mit Verhältnissen rechnen

In Flash muss man oftmals Werte von einem Verhältnis in ein anderes umrechnen. Zum Beispiel, wenn man mittels Slider den Alpha Wert oder die X Position einer Movieclipinstanz bestimmen will. Oder wenn man anhand der horizontalen oder vertikalen Mausposition die Eigenschaft eines MCs verändern will.

Für den Inhalt dieser Seite ist eine neuere Version von Adobe Flash Player erforderlich.

Adobe Flash Player herunterladen

Hier ein weiteres Beispiel, wobei mehrerer MC-Instanzen in einer for Schleife deklariert werden. Wenn man diesen beispielsweise eine aufsteigende Transparenz oder Skalierung zuweisen will, kann man es auf diese Weise berechnen. Damit die erste Instanz nicht komplett durchsichtig ist, habe ich den Wert 1/anzahl dazu addiert.

var anzahl:uint = 10
for(var i:uint = 0; i < anzahl; i++){
var kast:Kasten = new Kasten();
addChild(kast);

var alph:Number = i / anzahl + 1/anzahl;
kast.alpha = alph;

kast.x = kast.x = width + i*alph;

trace(alph);
}

 

Tastatur

Tastatureingaben und Events. Die folgende Klasse ist eine Dokumentklasse und sollte folglich im Eigenschaftenfenster angegeben werden. In den trace Funktionen werden Informationen über die gedrückte Taste herausgegeben. Umschalt-Taste (shiftKey) und Strg Taste (ctrlKey) liefern true oder false. Tasten die 2 mal vorkommenm, wie beispielsweise die Shift Taste oder die Tasten auf dem Nummerblock kann man mittels keyLocation unterscheiden.

package {
	import flash.display.MovieClip;
	import flash.display.DisplayObject;
	import flash.events.*;
	import flash.ui.Keyboard;

	public class KeyboardEventExample extends MovieClip {

		public function KeyboardEventExample():void {
			stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
			stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
		}

		private function keyDownHandler(event:KeyboardEvent):void {
			trace("keyDownHandler: " + event.keyCode);
			trace("ctrlKey: " + event.ctrlKey);
			trace("keyLocation: " + event.keyLocation);
			trace("shiftKey: " + event.shiftKey);
			trace("altKey: " + event.altKey);
		}

		private function keyUpHandler(event:KeyboardEvent):void {
			trace("keyUpHandler: " + event.keyCode);
		}
	}
}

Hier das gleiche nochmal im ersten Bild.

import flash.events.*;
import flash.ui.Keyboard;

function keyDownHandler(evt:KeyboardEvent):void
{
	trace("keyDownHandler: " + evt.keyCode);
	trace("ctrlKey: " + evt.ctrlKey);
	trace("keyLocation: " + evt.keyLocation);
	trace("shiftKey: " + evt.shiftKey);
	trace("altKey: " + evt.altKey);
}


function keyUpHandler(evt:KeyboardEvent):void
{
	trace("keyUpHandler: " + evt.keyCode);
}

Pfeiltasten

Hier ein Beispiel ohne Dokumentklasse. Die Pfeiltasten werden abgefragt.


stage.addEventListener(KeyboardEvent.KEY_DOWN, statusKeyDown);

function statusKeyDown(evt:KeyboardEvent) {
	if (evt.keyCode==Keyboard.DOWN) {
		trace("runterTaste");
	} else if (evt.keyCode==Keyboard.UP) {
		trace("raufTaste");
	} else if (evt.keyCode==Keyboard.LEFT) {
		trace("LInks Taste");
	} else if (evt.keyCode==Keyboard.RIGHT) {
		trace("Rechts Taste");
	}

}

Pfeiltasten

Hier ein ganz ähnliches Beispiel. Auch geht es um die 4 Pfeiltasten, welche man häufig in Spielen für die Steuerung irgendwelcher Figuren oder Gefährte braucht. Hier ist wieder alles in eine Dokumentklasse eingefügt. Die if Struktur wurde durch switch ersetzt.


package {
	import flash.display.MovieClip;
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;


	public class pfeiltasten extends MovieClip {
		protected var tinit:Number=.6;
		protected var tauswahl:Number=1;
		protected var thell:Number=.2;
		protected var wahl:String="a";
		protected var auswahl:String="";


		public function pfeiltasten():void {
			stage.addEventListener(KeyboardEvent.KEY_DOWN, pfeiltasteDown);
		}
		public function pfeiltasteDown(evt:KeyboardEvent):void {
			switch (evt.keyCode) {
				case Keyboard.DOWN :
					trace("runterTaste");
					break;
				case Keyboard.UP :
					trace("rauf Taste");
					break;
				case Keyboard.LEFT :
					trace("Links Taste");
					break;
				case Keyboard.RIGHT :
					trace("Rechts Taste");
					break;
				default :
			}
		}
	}
}

 

MovieClip mit Tastensteuerung

In meinen Tipps zum Thema Display Objekte und Movieclips wird erklärt, wie man sich in der Bibliothek eine MovieClip Klasse anlegt und wie man dieser eine Klassendefinition zuordnen kann, um ihr bestimmte Eigenschaften hinzuzufügen. So wird in diesem Fall solch eine MovieClip Klasse mit Tastensteuerung erzeugt. Man hat also ein Movieclipsymbol in der Bibliothek mit Klassennamen TMove und eine Datei TMove.as im gleichen Ordner. Beachte, wie hier der EventListener der Bühne zugewiesen wird. Hier stellt sich jedoch noch ein Problem und zwar wird in der Klasse ein EventListener der Bühne zugewiesen. Wenn man jedoch diese Klasse nicht der Display Liste hinzufügt mit addChild() kann es auch keine Bühne geben, der man diesen Event Listener zuweisen könnte. Deswegen funktioniert dieses Beispiel nur dann, wenn man in der IDE (Entwicklungsumgebung) diese Movieclipklasse aus der Bibliothek auf die Bühne zieht, aber nicht wenn man ein Objekt dieser Klasse per Actionscript erzeugt und dann mit addChild() der Display Liste hinzufügt. Im strikten Modus, gibt es im letzteren Fall eine Fehlermeldung. Gleiches gilt auch für die folgenden Beispiele. Deswegen sind diese Beispiel unter objektorientierten Gesichtspunkten nicht einwandfrei.


package {
	import flash.display.MovieClip;
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;

	public class TMove extends MovieClip {
		public function TMove() {
			this.stage.addEventListener(KeyboardEvent.KEY_DOWN, pfeiltasteDown);
		}

		public function pfeiltasteDown(evt:KeyboardEvent):void {
			switch (evt.keyCode) {
				case Keyboard.DOWN :
					this.y+=5;
					break;
				case Keyboard.UP :
					this.y-=5;
					break;
				case Keyboard.LEFT :
					this.x-=5;
					break;
				case Keyboard.RIGHT :
					this.x+=5;
					break;
				default :
			}
		}
	}
}

Bewegungsfunktionen vererben

Will man seine Flashanwendungen objektorientiert anlegen, macht es wenig Sinn, in jeder Klasse die gleichen Bewegungsfunktionen einzubauen. Besser ist, man packt die Bewegung per Tastatursteuerung in eine Klasse und vererbt sie an alle, die sie benötigen. In diesem Falle bleibt die Klasse TMove, (siehe voriges Beispiel) so wie sie ist, nur dass sie kein entsprechendes Movieclipsymbol in der Bibliothek bekommt. Alle Klassen, die diese Bewegung übernehmen sollen, erben von der Klasse TMove. Hier habe ich das MovieClip Symbol "Biene" in der Bibliothek als Klasse angelegt. Die entsprechende Klassendatei Biene.as erbt von TMove. Das kann man natürlich jetzt schön erweitern. Zum Beispiel könnte man in der Konstruktorfunktionen einen Parameter für eine z-Position im 3-D Raum definieren mit dem die Bewegung entsprechend angepasst wird. Siehe meine "3D-Tipps" in AS2. Ein weiter hintenliegendes Objekt müßte sich langsamer bewegen, als ein weiter vorne liegendes.

MC mit Maus anklicken und Pfeiltasten benutzen

package {
public class Biene extends TMove {
}
}

Bewegungen optimieren

Die vorige Bewegung ist sehr einfach. Hier wird nun der ENTER_FRAME Event hinzugefügt, um die Bewegung etwas dynamischer anzulegen. Die Geschwindigkeit stoppt nicht plötzlich, sondern wird zum Ende langsamer. Ein ähnliches Beispiel findet man in meinem AS2 Tipp zum Thema. Doch auch diese Bewegung ist noch nicht optimal, sondern stockend.

MC mit Maus anklicken und Pfeiltasten benutzen

package {
	import flash.display.MovieClip;
	import flash.events.KeyboardEvent;
	import flash.events.Event;
	import flash.ui.Keyboard;

	public class TDynMove extends MovieClip {
		var vertMove:int=0;
		var vertDir:int;
		var horMove:int =0;
		var horDir:int;	
		var speed:int=14;
		
		public function TDynMove() {
			this.stage.addEventListener(KeyboardEvent.KEY_DOWN, pfeiltasteDown);
			addEventListener(Event.ENTER_FRAME,bewegung);
		}

		public function pfeiltasteDown(evt:KeyboardEvent):void {
			switch (evt.keyCode) {
				case Keyboard.DOWN :
					vertMove = speed;
					vertDir = 1;
					break;
				case Keyboard.UP :
					vertMove = speed;
					vertDir = -1;
					break;
				case Keyboard.LEFT :
					horMove = speed;
					horDir = -1;
					break;
				case Keyboard.RIGHT :
					horMove = speed;
					horDir = 1;
					break;
				default :
			}
		}
		
		public function bewegung(evt:Event):void {
			if (horMove>0) {
				horMove--;
			}			
			if (vertMove>0) {
				vertMove--;
			}
			evt.currentTarget.x=evt.currentTarget.x+horMove*horDir;
			evt.currentTarget.y=evt.currentTarget.y+vertMove*vertDir;			
		}
		
	}
}

Flüssige Bewegungen

Hier nun eine weitere Optimierung. Es wurde ein zweiter Event Listener hinzugefügt, der abfragt, ob die Taste losgelassen wurde. Dadurch wird die Sache wesentlich flüssiger.

Beispiel

 

package 
{
	import flash.display.MovieClip;
	import flash.events.KeyboardEvent;
	import flash.events.Event;
	import flash.ui.Keyboard;

	public class TDynamMove extends MovieClip
	{
		var vertMove:int = 0;
		var vertDir:int;
		var horMove:int = 0;
		var horDir:int;
		var speed:int = 14;
		public var upkeydown:Boolean = false;
		public var leftkeydown:Boolean = false;
		public var rightkeydown:Boolean = false;
		public var downkeydown:Boolean = false;


		public function TDynamMove()
		{
			if (stage)
			{
				init();
			}
			else
			{
				addEventListener(Event.ADDED_TO_STAGE,init);
			}
		}


		private function init(e:Event=null):void
		{
			this.stage.addEventListener(KeyboardEvent.KEY_UP,tasteUp);
			this.stage.addEventListener(KeyboardEvent.KEY_DOWN, tasteDown);
			addEventListener(Event.ENTER_FRAME,bewegung);
			removeEventListener(Event.ADDED_TO_STAGE, init);
			addEventListener(Event.REMOVED_FROM_STAGE, destroy);
		}


		private function destroy(e:Event):void
		{
			removeEventListener(Event.REMOVED_FROM_STAGE, destroy);
			this.stage.removeEventListener(KeyboardEvent.KEY_UP,tasteUp);
			this.stage.removeEventListener(KeyboardEvent.KEY_DOWN, tasteDown);
			removeEventListener(Event.ENTER_FRAME,bewegung);
		}


		public function tasteDown(event:KeyboardEvent):void
		{
			switch ( event.keyCode )
			{
				case Keyboard.UP :
					upkeydown = true;
					break;

				case Keyboard.LEFT :
					leftkeydown = true;
					break;

				case Keyboard.RIGHT :
					rightkeydown = true;
					break;
				case Keyboard.DOWN :
					downkeydown = true;
					break;
			}
		}

		protected function tasteUp(event:KeyboardEvent):void
		{
			switch ( event.keyCode )
			{
				case Keyboard.UP :
					upkeydown = false;
					break;

				case Keyboard.LEFT :
					leftkeydown = false;
					break;

				case Keyboard.RIGHT :
					rightkeydown = false;
					break;
				case Keyboard.DOWN :
					downkeydown = false;
					break;
			}
		}

		public function bewegung(evt:Event):void
		{
			if (upkeydown)
			{
				vertMove = speed;
				vertDir = -1;
			}
			if (leftkeydown)
			{
				horMove = speed;
				horDir = -1;
			}
			if (rightkeydown)
			{
				horMove = speed;
				horDir = 1;
			}
			if (downkeydown)
			{
				vertMove = speed;
				vertDir = 1;
			}
			if (horMove>0)
			{
				horMove -=  .5;
			}
			if (vertMove>0)
			{
				vertMove -=  .5;
			}
			this.x = this.x + horMove * horDir;
			this.y = this.y + vertMove * vertDir;
		}
	}
}

Kulissen Bewegung im Jump & Run Spiel

Hier geht es um die Bewegung von Hintergrundkulissen in einem Jump & Run Spiel. Wir haben hier eine ganz einfache 3D-Simulation. Je weiter hinten auf der Z-Achse die Kulissen liegen, desto langsamer sollen Sie sich bewegen. Dazu habe ich eine Klasse TKulisse erstellt. Die einzelnen Kulissenklassen, haben jeweils eine Movieclipklasse in der Bibliothek und eine Klassendatei, welche von der Klasse TKulisse erbt. Sie heißen back1.as, back2.as, back3.as. Jede der Klassen bekommt ein eigenen Paramterwert für die Z-Position. Damit wird die Bewegungsgeschwindigkeit definiert, siehe 3-D Tipp in AS2.

Beispiel

 

package {
	import flash.display.MovieClip;
	import flash.events.KeyboardEvent;
	import flash.events.Event;
	import flash.ui.Keyboard;

	public class TKulisse extends MovieClip {

		protected var horMove:int =0;
		protected var horDir:int;
		protected var speed:int=14;
		protected var focalLength:int = 300;
		protected var scaleRatio:Number;
		protected var zPos:int=1;
		protected var xPos:int=1;
		protected var leftkeydown:Boolean = false;
		protected var rightkeydown:Boolean = false;


		public function TKulisse() {

			this.stage.addEventListener(KeyboardEvent.KEY_UP,tasteUp);
			this.stage.addEventListener(KeyboardEvent.KEY_DOWN, tasteDown);
			addEventListener(Event.ENTER_FRAME,bewegung);
		}
/*		public function set zPosition(zPos:int):void {
			this.zPos=zPos;
		}*/
		public function tasteDown(event:KeyboardEvent):void {

			switch ( event.keyCode ) {
				case Keyboard.LEFT :
					leftkeydown = true;
					break;

				case Keyboard.RIGHT :
					rightkeydown = true;
					break;
			}
		}
		protected function tasteUp(event:KeyboardEvent):void {
			switch ( event.keyCode ) {
				case Keyboard.LEFT :
					leftkeydown = false;
					break;

				case Keyboard.RIGHT :
					rightkeydown = false;
					break;
			}
		}
		public function bewegung(evt:Event):void {

			if (leftkeydown) {
				horMove = speed;
				horDir = -1;
			}
			if (rightkeydown) {
				horMove = speed;
				horDir = 1;
			}

			if (horMove>0) {
				horMove-=.5;
			}
			this.scaleRatio = this.focalLength/(this.focalLength+this.zPos);
			this.x+=horMove*horDir*this.scaleRatio;
		}
	}
}

 

Die Klassen back2.as und back3.as bekommen einen eigenen Wert für die z-Position, back1.as behält den Wert zPos=1 von TKulisse.as.

package {
public class back2 extends TKulisse {
public function back2() {
zPos=500;
}
}
}

Parallax

Auch in diesem Tipp habe ich die 3D Berechnung aus dem AS2 Tipp verwendet. In AS3 kann man das auch mit den 3D Eigenschaften lösen, indem man die Variable zPos durch die Eigenschaft z ersetzt. Allerdings stellt sich dann das Problem, die obere Kante der Sichtbereichs zu bestimmen.

In der Bibliothek der fla Datei befindet sich eine erweiterte MovieClip Klasse mit der dazugehörigen Klassendatei Parallax.as. Der MC hat in mehreren Schlüsselbildern verschiedenen Grafiken von Menschen. Siehe auch weiter unten das Beispiel Herbstlaub.

Tipp Wenn du das Beispiel nachbaust, solltest du unbedingt auf die Größe der Grafiken im "Parallax"-Mc achten. In meinem Beispiel sind sie ca 120 x 120 Pixel mit Registrierpunkt in der Mitte.

In der fla werden die Instanzen erzeugt. Dort wird auch die Tiefe oder z-Position der Instanzen bestimmt. Anhand dieser Position wird Farbton, Sättigung und Helligkeit definiert, um einen Eindruck von Tiefe zu erzeugen. Näheres zu dieser Color Transformation in meinem Tipp Color.

Beispiel

Klassendatei Parallax.as

package 
{
	import flash.display.MovieClip;
	import flash.events.Event;


	public class Parallax extends MovieClip
	{

		protected var vertMove:int = 0;
		protected var vertDir:int;
		protected var speed:int;
		protected var focalLength:int = 300;
		protected var scaleRatio:Number;
		protected var zPos:int = 1;
		protected var xPos:int = 1;


		public function Parallax(_zPos:int=1, _speed:int=4)
		{

			zPos = _zPos;
			speed = _speed;


			if (stage)
			{
				init();
			}
			else
			{
				addEventListener(Event.ADDED_TO_STAGE,init);
			}


		}

		private function init(e:Event=null):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			addEventListener(Event.REMOVED_FROM_STAGE, destroy);
			addEventListener(Event.ENTER_FRAME,bewegung);
			this.x = Math.random() * this.stage.stageWidth;
			this.y = Math.random() * this.stage.stageHeight;
			gotoAndStop(Math.ceil(Math.random()*this.totalFrames));
			scaleRatio = focalLength / (focalLength + this.zPos);
			this.scaleX = this.scaleY = scaleRatio;

		}

		//-----------------------------------------------

		private function destroy(e:Event):void
		{
			removeEventListener(Event.REMOVED_FROM_STAGE, destroy);
			removeEventListener(Event.ENTER_FRAME,bewegung);
		}

		public function bewegung(evt:Event):void
		{
			vertMove = speed;

			if (y < this.stage.stageHeight+this.height)
			{
				this.scaleRatio = this.focalLength/(this.focalLength+this.zPos);
				this.y +=  vertMove * this.scaleRatio;

			}
			else
			{
				this.y = this.height * -3;
				this.x = Math.random() * this.stage.stageWidth;
			}
		}
	}
}

Action im ersten Bild der fla

import flash.filters.ColorMatrixFilter;
import flash.net.URLRequest;
import fl.motion.AdjustColor;
var anzahl:uint = 60;
var tiefe:uint = 20;

for (var i:uint = 1; i< anzahl; i++)
{
	var figure:Parallax = new Parallax((anzahl*tiefe)-(i*tiefe));	
	addChild(figure);

	var adCol:AdjustColor = new AdjustColor();
	adCol.hue = i*6;//-180 und 180;
	adCol.brightness = 100-i*3;//-100 100;
	adCol.contrast = 0;//-100 100
	adCol.saturation = -100+i*3;//Saturation-100 und 100
	var matrix:Array = adCol.CalculateFinalFlatArray();
	var filter:ColorMatrixFilter = new ColorMatrixFilter(matrix);
	var filterAr:Array = new Array();
	filterAr.push(filter);
	figure.filters = filterAr;
}

 

Movieclip Bewegung und Drehung per Tastatursteuerung

Dieses Beispiel gibt es in den Beispielen von Adobe in abgewandelter Form. Meine Variante hat das Beispiel auf einige Funktionen reduziert, damit man es leichter nachvollziehen kann. http://www.adobe.com/devnet/flash/samples/

Tipp Siehe auch den Tipp Trigonometrie, für weitere programmierte Bewegungen.

Beispiel

 

package {
	import flash.display.MovieClip;
	import flash.events.KeyboardEvent;
	import flash.events.Event;
	import flash.ui.Keyboard;

	public class TDynaMove extends MovieClip {
		public var thrust:Number = 1;
		public var decay:Number = .98;
		public var speed:Number = 0;
		public var xSpeed:Number = 0;
		public var ySpeed:Number = 0;
		public var maxSpeed:Number = 5;
		public var xThrustPercent:Number = 0;
		public var yThrustPercent:Number = 0;
		public var upkeydown:Boolean = false;
		public var leftkeydown:Boolean = false;
		public var rightkeydown:Boolean = false;


		public function TDynaMove() {
			this.stage.addEventListener(KeyboardEvent.KEY_UP,tasteUp);
			this.stage.addEventListener(KeyboardEvent.KEY_DOWN, tasteDown);
			addEventListener(Event.ENTER_FRAME,bewegung);
		}

		public function tasteDown(event:KeyboardEvent):void {

			switch ( event.keyCode ) {
				case Keyboard.UP :
					upkeydown = true;
					break;

				case Keyboard.LEFT :
					leftkeydown = true;
					break;

				case Keyboard.RIGHT :
					rightkeydown = true;
					break;
			}

		}
		protected function tasteUp(event:KeyboardEvent):void {
			switch ( event.keyCode ) {
				case Keyboard.UP :
					upkeydown = false;
					break;

				case Keyboard.LEFT :
					leftkeydown = false;
					break;

				case Keyboard.RIGHT :
					rightkeydown = false;
					break;
			}
		}
		public function bewegung(evt:Event):void {

			if ( upkeydown ) {
				xSpeed += thrust*xThrustPercent;
				ySpeed += thrust*yThrustPercent;

			} else {
				xSpeed *= decay;
				ySpeed *= decay;
			}
			if ( rightkeydown ) {
				rotation += 10;		
			}
			if ( leftkeydown ) {
				rotation -= 10;				
			}
			//wieviel Schub wird gebraucht, basierend auf der Drehung oder Richtung
			xThrustPercent = Math.sin(rotation*(Math.PI/180));
			yThrustPercent = Math.cos(rotation*(Math.PI/180));

			//  Geschwindigkeits Grenze aufrechterhalten
			speed = Math.sqrt((xSpeed*xSpeed)+(ySpeed*ySpeed));
			if ( speed > maxSpeed ) {
				xSpeed *= maxSpeed/speed;
				ySpeed *= maxSpeed/speed;
			}
			y -= ySpeed;
			x += xSpeed;
			//wenn es aus der Bühne fliegt, kommt es an der anderen Seite wieder an
			if(this.y>420){
				this.y=-10;
				}else if(this.y<-20){
					this.y=410;
					}else if(this.x>570){
						this.x=-10;
						}else if(this.x<-20){
							this.x=550;
							}
			
		}
	}
}

Programmierte Bewegung nach Mausposition

Hier ein Beispiel welches in ähnlicher Form in dem entsprechenden AS2 Tipp genauer erklärt wird.

Wir haben hier eine Movielcipklasse in der Bibliothek und die dazugehörige Klassendatei

Actions der fla

var gallery:MausMove = new MausMove();
addChild(gallery);

Actions der as Datei MausMove.as


package {
	import flash.display.MovieClip;
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;
	import flash.events.MouseEvent;
	import flash.events.Event;

	public class MausMove extends MovieClip {
		private var xziel:Number;
		private var ab:uint=20;
		public function MausMove() {
			this.addEventListener(MouseEvent.MOUSE_MOVE,mauspos);
			addEventListener(Event.ENTER_FRAME, bewegung);
		}

		public function mauspos(evt:MouseEvent):void {
			xziel = (((evt.currentTarget.width-550)/(550-ab*2))*(evt.stageX-ab))*-1;
		}
		
		public function bewegung(evt:Event):void {
			evt.currentTarget.x = evt.currentTarget.x+(xziel-evt.currentTarget.x)/6;
			}	
		
	}
}

Programmierte Bewegung nach Mausposition (dynamisch)

auch dieses Beispiel gibt es in meinen AS2 Tipps programmierte Bewegung

Hier wurde an beiden Seiten Abstand hinzugefügt. Es ist die Variable mit dem Bezeichner ab.

Actions der fla

var gallery:MausMove = new MausMove();
addChild(gallery);

Actions der as Datei MausMove.as

package {
	import flash.display.MovieClip;
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;
	import flash.events.MouseEvent;
	import flash.events.Event;

	public class MausMove extends MovieClip {
		private var xziel:Number;
		private var ab:uint=20;
		public function MausMove() {
			this.addEventListener(MouseEvent.MOUSE_MOVE,mauspos);
			addEventListener(Event.ENTER_FRAME, bewegung);
		}

		public function mauspos(evt:MouseEvent):void {
			xziel = (((evt.currentTarget.width-550)/(550-ab*2))*(evt.stageX-ab))*-1;
		}
		
		public function bewegung(evt:Event):void {
			evt.currentTarget.x = evt.currentTarget.x+(xziel-evt.currentTarget.x)/6;
			}	
		
	}
}

Event Enter Frame stoppen

 

Für den Inhalt dieser Seite ist eine neuere Version von Adobe Flash Player erforderlich.

Adobe Flash Player herunterladen

In den vorigen Beispielen läuft der Event ENTER_FRAME permanent durch und wird nicht gestoppt. Das kann zu Performanceverlust und auch einem Ruckeln führen. Hier wird der Event entfernt, wenn das Ziel erreicht ist.

Theoretisch wird das Ziel zwar nie erreicht, aber praktisch schon, da Flash die Zahlen nicht bis zur unendlichen Stelle hinter dem Komma ausrechnet. Ich habe hier die Variable xziel als int also Ganzzahl ausgewiesen. Sie bekommte ihren Wert während die Maus sich beweget MOUSE_MOVE. In der ENTER_FRAME bewege Funktion wird ermittelt ob die gerundete Position das xziel erreicht hat, damit der ENTER_FRAME Event Listener dann entfernt werden kann.

Außerdem habe ich den Abstand zu beiden Seiten als Parameter der Konstruktorfunktion eingegeben. So hat man die Möglichkeit beim Deklarieren einen Abstand einzugeben.

var pic:MausMove2 = new MausMove2(10);

Desweiteren funktioniert dieses Beispiel mit jeder Bühnengröße, da diese abgefragt wird. Das Thema ADDED_TO_STAGE wird unter Displayliste erklärt.

Das vorige Beispiel wurde hier erweitert.

package
{
	import flash.display.MovieClip;
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;
	import flash.events.MouseEvent;
	import flash.events.Event;

	public class MausMove2 extends MovieClip
	{
		private var xziel: int;
		private var ab: uint;
		public var stagewidth: Number;


		public function MausMove2(_ab: uint = 20)
		{
			ab = _ab;
			if (stage)
			{
				init();
			}
			else
			{
				addEventListener(Event.ADDED_TO_STAGE, init);
			}


		}
		protected function init(evt: Event = null)
		{
			stagewidth = this.stage.stageWidth;
			this.addEventListener(MouseEvent.MOUSE_MOVE, mauspos);
		}

		public function mauspos(evt: MouseEvent): void
		{
			xziel = (this.width - stagewidth) / (stagewidth - ab * 2) * (evt.stageX - ab) * -1;
			addEventListener(Event.ENTER_FRAME, bewegung);
		}

		public function bewegung(evt: Event): void
		{
			this.x = this.x + (xziel - this.x) / 6;

			if (Math.round(this.x) == xziel)
			{
				removeEventListener(Event.ENTER_FRAME, bewegung);
				trace("stop");
			}

		}

	}
}

 

Panorama

Beispiel

Hier wurde ein Movieclip eingesetzt, der so aufgebaut ist, wie die Grafik. Die Grundlage ist ein Bild, welches sich horizontal kacheln lässt. Es ist mit der linken oberen Kante am Registrierpunkt ausgerichtet und 1960 Pixel breit. Wie man auf der Grafik sieht, wird das Bild am linken und rechten Ende gekachelt. Der gekachelte Bereich muss breiter sein als die Bühnenbreite.

Die Programmierung sorgt dafür, dass das Bild, sobald es Gefahr läuft aus der Bühne heraus zu laufen zum jeweils gegenüberliegenden Ende springt.

panorama

import flash.display.MovieClip;
stage.scaleMode = StageScaleMode.NO_SCALE;

var stageBreite:Number = stage.stageWidth;

var breite:Number = 1960;
var speed:Number;
panorama.addEventListener(Event.ENTER_FRAME, movement);

function movement(evt:Event):void
{
	speed= (stage.mouseX-stageBreite/2)/-10;


	if (panorama.x <  -  breite)
	{
		panorama.x = panorama.x+breite + speed;
	}
	else if (panorama.x > 0)
	{
		panorama.x +=   -  breite + speed;
	}
	else
	{
		panorama.x +=  speed;
	}
}

Panorama nach allen Seiten, Spielfeld Matrix

Beispiel siehe auch Trigonometrie

Im folgenden Beispiel wurde das vorige Beispiel einfach um die vertikale Bewegung erweitert. Eine Programmierung, die sich gut für Spiele aus der Vogelperspektive einsetzen lässt.

import flash.display.MovieClip;
stage.scaleMode = StageScaleMode.NO_SCALE;
 
var stageBreite:Number = stage.stageWidth;
 var stageHoehe:Number = stage.stageHeight;
var breite:Number = 1306;
var hoehe:Number = 684;
var speedX:Number;
var speedY:Number;
panorama.addEventListener(Event.ENTER_FRAME, movement);
 
function movement(evt:Event):void
{
    speedX= (stage.mouseX-stageBreite/2)/-10;
	 speedY= (stage.mouseY-stageHoehe/2)/-10;
 
 
    if (panorama.x <  -  breite)
    {
        panorama.x = panorama.x+breite + speedX;
    }
    else if (panorama.x > 0)
    {
        panorama.x +=   -  breite + speedX;
    }
    else
    {
        panorama.x +=  speedX;
    }
	    if (panorama.y <  -  hoehe)
    {
        panorama.y = panorama.y+hoehe + speedY;
    }
    else if (panorama.y > 0)
    {
        panorama.y +=   -  hoehe + speedY;
    }
    else
    {
        panorama.y +=  speedY;
    }
}

 

 

Dynamische Bewegung zu einem Zielpunkt

Im folgenden wird eine dynamische Bewegung auf einen Zielpunkt programmiert. Ähnliche Beispiele findet man in meinen Flash AS2 Tipps. Die Instanz bewegt sich onEnterFrame (mit der Bildlaufrate) auf den Zielpunkt zu. Die Bewegung wird zum Zielpunkt abgebremst. Das wird erreicht, indem die Instanz den Abstand zum Ziel mit der Bildlaufrate um die Hälfte (oder einene Wert) verkürzt. Oder anders ausgedrückt, die Instanz bewegt sich um die Hälfte des Weges auf das Ziel zu.


var ziel:Point=new Point(20,20);

meinMc.addEventListener(Event.ENTER_FRAME, smoothMove);

function smoothMove(evt:Event):void {
	evt.currentTarget.x+=(ziel.x-evt.currentTarget.x)/10;
	evt.currentTarget.y+=(ziel.y-evt.currentTarget.y)/10;
	if (Math.round(evt.currentTarget.x)==ziel.x&&Math.round(evt.currentTarget.y)==ziel.y) {
		delete evt.currentTarget.onEnterFrame;
	}
}

Im nächsten Beispiel bewegt sich die Instanz bei jedem Mausklick auf die Mausposition zu.

Für den Inhalt dieser Seite ist eine neuere Version von Adobe Flash Player erforderlich.

Adobe Flash Player herunterladen


var ziel:Point=new Point();


stage.addEventListener(MouseEvent.MOUSE_UP, goToPoint);

function goToPoint(evt:MouseEvent):void {
	ziel.x=mouseX;
	ziel.y=mouseY;
	meinMc.addEventListener(Event.ENTER_FRAME, smoothMove);
}


function smoothMove(evt:Event):void {
	evt.currentTarget.x+=(ziel.x-evt.currentTarget.x)/10;
	evt.currentTarget.y+=(ziel.y-evt.currentTarget.y)/10;
	if (Math.round(evt.currentTarget.x)==ziel.x&&Math.round(evt.currentTarget.y)==ziel.y) {
		delete evt.currentTarget.onEnterFrame;
	}
}


Programmierte Bewegung / Abprallen an der Wand / Richtungswechsel

Siehe auch das Beispiel von dem ich "geklaut" hab Change Speed Direction after hitting the boundary

Hier haben wir ein Standarbeispiel ein MC bewegt sich innerhalb der Hauptbühne und prallt an den Wänden ab. Siehe dazu auch getBounds(). Durch mc.getBounds(mc.parent). wird ein Rechteck zurückgegeben, welches sich auf das Koordinatensystem bezieht in das der mc eingebettet ist. Durch Eigenschaften des Rectangle und der Bühnenweite werden alle Werte geliefert, die man benötigt, um zu erfahren, ob der mc eine der Kanten überschritten hat.

Für den Inhalt dieser Seite ist eine neuere Version von Adobe Flash Player erforderlich.

Adobe Flash Player herunterladen

Beispiel balla.fla


var kugel:Abprall = new Abprall();
kugel.x=20;
kugel.y=100;
addChild(kugel);


Es folgt nun das Actionscript der Klasse Abprall


package {
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Rectangle;

	public class Abprall extends Sprite {
		public var speedX:int=5;
		public var speedY:int=-5;

		public function Abprall() {
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
			graphics.beginFill(0xFF, 1);
			graphics.drawCircle(0, 0, 25);
			graphics.endFill();


		}

		private function onEnterFrame(event:Event):void {
			x+=speedX;
			y+=speedY;

			var bounds:Rectangle=getBounds(parent);


			if (bounds.left<0||bounds.right>stage.stageWidth) {
				speedX*=-1;
			}
			if (bounds.top<0||bounds.bottom>stage.stageHeight) {
				speedY*=-1;
			}
		}
	}
}

Drehknopf / rotation Slider

Siehe zu diesen Tipp auch meinen AS2 Tipp Math.atan2(). Dort wird die Sachlage ein mehreren Beispielen genau erklärt. Das folgende Beispiel kann man sich gut als Drehknopf Komponente vorstellen, um beispielsweise einen Lautstärkeregler zu erstellen.

Für den Inhalt dieser Seite ist eine neuere Version von Adobe Flash Player erforderlich.

Adobe Flash Player herunterladen

Hier nun eine Klasse, dieses Drehsliders. Die Grafiken werden programmatisch erstellt.

 

package de.pastorpixel.tools
{
	
	//von Michael Albers Dortmund www.pastorpixel.de www.on-design.de
	//rotationSliderKomponente Zugriff über die beiden public Variablen 
	//degreeVal für Winkel
	//radianVal für Winkel im Bogenmaß
	//Grafiken und Textfeld werden in Funktion init erzeugt
	
	import flash.events.*;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.display.Shape;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.text.TextFormatAlign;


	public class RotationSlider extends Sprite
	{
		protected var tFormat:TextFormat = new TextFormat();
		protected var tFeld:TextField = new TextField();
		protected var knop:Sprite = new Sprite();
		protected var draggin:Boolean = false;
		public var degreeVal:Number;
		public var radianVal:Number;


		public function RotationSlider()
		{
			// constructor code
			super();

			if (stage)
			{
				init();
			}
			else
			{
				addEventListener(Event.ADDED_TO_STAGE,init);
			}


		}

		private function init(e:Event=null):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			//Textfeld erzeugen
			tFormat.size = 25;
			tFormat.font = "_sans";
			tFormat.align = TextFormatAlign.CENTER;
			tFeld.defaultTextFormat = tFormat;
			tFeld.selectable = false;
			tFeld.x = -100;
			tFeld.y = 35;
			tFeld.width = 200;
			tFeld.text = "0";
			addChild(tFeld);
			//Außenkreis erzeugen
			this.graphics.lineStyle(2, 0x909090, 1);
			this.graphics.drawCircle(0,0,100);
			//knop Grafik erzeugen;
			knop.graphics.lineStyle(1, 0x000000, 1);
			knop.graphics.beginFill(0x707070,1);
			knop.graphics.drawCircle(100,0,15);
			addChild(knop);

			this.knop.addEventListener(MouseEvent.MOUSE_DOWN, startSlide);
			stage.addEventListener(MouseEvent.MOUSE_UP, stopSlide);
		}


		protected function turn(evt:Event):void
		{
			var deltaY:Number = evt.currentTarget.parent.mouseY - evt.currentTarget.y;
			var deltaX:Number = evt.currentTarget.parent.mouseX - evt.currentTarget.x;
			var rotationRadian:Number = Math.atan2(deltaY,deltaX);
			var winkel:Number = (rotationRadian / Math.PI) * 180;
			evt.currentTarget.rotation = winkel;
			degreeVal = winkel;
			radianVal = rotationRadian;
			this.tFeld.text = String(Math.round(evt.currentTarget.rotation));
		}

		protected function startSlide(evt:MouseEvent):void
		{
			draggin = true;
			this.knop.addEventListener(Event.ENTER_FRAME, turn);
		}

		protected function stopSlide(evt:MouseEvent):void
		{
			if (draggin)
			{
				this.knop.removeEventListener(Event.ENTER_FRAME, turn);
			}
			draggin = false;
		}

	}

}

 


Pendelbewegung mit Sinus

Hier eine einfache Pendelbewegung. Siehe hierzu auch meine Trigonometrie Tipps, sowohl in AS2 als auch in AS3. Der Math.sin() erzeugt hier einen Wert zwischen -1 und +1. Das wird dann mit dem gewünschten Winkel multipliziert, und man erhält die Pendelbewegung.

Für den Inhalt dieser Seite ist eine neuere Version von Adobe Flash Player erforderlich.

Adobe Flash Player herunterladen

import flash.events.Event;

var multi:Number = 0.3;

addEventListener(Event.ENTER_FRAME, turn);
function turn(evt:Event):void
{
	zeiger.rotation = Math.sin(multi+=0.03)*90 +90;
}

 

 

Pendelbewegungen

In den folgednen Beispielen werden mehrere Pendelbewegungen vorgestellt. Die Beispiele werden immer komplexer.

Pendel1
Diese Bewegung beginnt schnell und verlangsamt sich zum Ende hin.

Für den Inhalt dieser Seite ist eine neuere Version von Adobe Flash Player erforderlich.

Adobe Flash Player herunterladen

import flash.events.Event;

zeiger.addEventListener(Event.ENTER_FRAME, turn);
zeiger.turnDir = 1;
function turn(evt:Event):void
{
	if (Math.ceil(zeiger.rotation) == 180)
	{
		zeiger.turnDir = -1;
		zeiger.rotation = 179;
	}
	else if (Math.floor(zeiger.rotation)==0)
	{
		zeiger.turnDir = 1;
		zeiger.rotation = 1;

	}


	if (zeiger.turnDir == 1)
	{
		zeiger.rotation +=  (180 - zeiger.rotation) * 0.1;
	}
	else
	{
		zeiger.rotation -=  (zeiger.rotation) * 0.1;
	}
}

Pendel 2
Diese Bewegung beginnt mit einer gleichmäßigen Geschwindigkeit und wird zum Ende hin langsamer.

Für den Inhalt dieser Seite ist eine neuere Version von Adobe Flash Player erforderlich.

Adobe Flash Player herunterladen

import flash.events.Event;

zeiger.addEventListener(Event.ENTER_FRAME, turn);
zeiger.turnDir = 1;
function turn(evt:Event):void
{
	if (Math.ceil(zeiger.rotation) == 180)
	{
		zeiger.turnDir = -1;
		zeiger.rotation = 179;
	}
	else if (Math.floor(zeiger.rotation)==0)
	{
		zeiger.turnDir = 1;
		zeiger.rotation = 1;

	}


	if (zeiger.turnDir == 1)
	{
		if (zeiger.rotation < 150)
		{
			zeiger.rotation +=  2;
		}
		else
		{
			zeiger.rotation +=  (180 - zeiger.rotation) * 0.1;
		}

	}
	else
	{
		if (zeiger.rotation > 30)
		{
			zeiger.rotation -= 2;
		}
		else
		{
			zeiger.rotation -=  (zeiger.rotation) * 0.1;
		}
	}
}

Pendel 3
Hier ist nun eine typische Pendelbewegung, die zur Mitte hin schneller wird und ab der Mitte zum Ende hin langsamer wird.

Für den Inhalt dieser Seite ist eine neuere Version von Adobe Flash Player erforderlich.

Adobe Flash Player herunterladen

import flash.events.Event;



zeiger.addEventListener(Event.ENTER_FRAME, turn);
zeiger.turnDir = 1;
function turn(evt:Event):void
{
	if (Math.ceil(zeiger.rotation) == 180)
	{
		zeiger.turnDir = -1;
		zeiger.rotation = 180-1;
	}
	else if (Math.floor(zeiger.rotation)==0)
	{
		zeiger.turnDir = 1;
		zeiger.rotation = 1;

	}


	if (zeiger.turnDir == 1)
	{
		if (zeiger.rotation < (180/2))
		{
			zeiger.rotation +=  (zeiger.rotation) * 0.1;
		}
		else
		{
			zeiger.rotation +=  (180 - zeiger.rotation) * 0.1;
		}

	}
	else
	{
		if (zeiger.rotation > (180/2))
		{
			zeiger.rotation -=  (180-zeiger.rotation) * 0.1;
		}
		else
		{
			zeiger.rotation -=  (zeiger.rotation) * 0.1;
		}
	}
	
}

Pendel 4
Diese Bewegung ist die gleiche wie in in Pendel 3. Die Programmierung ist optimiert. Da die Eigenschaft mc.rotation stellenweise im Minusbereich liegt, wird hier der Winkel in einer Variablen abgelegt und erst nach der Berechnung zugewiesen. Außerdem wird hier noch ein Wert hinzuaddiert und eine Rotation auf einer 3D Achse hinzugefügt.

Für den Inhalt dieser Seite ist eine neuere Version von Adobe Flash Player erforderlich.

Adobe Flash Player herunterladen

import flash.events.Event;


var rotationSpeed = 0.05;
var turnDir:int = 1;
var range:Number = 180;
var winkel:Number = 0;



blatt.addEventListener(Event.ENTER_FRAME, turn);

function turn(evt:Event):void
{
	if (Math.ceil(winkel) == range)
	{
		turnDir = -1;
		winkel = range-1;
	}
	else if (Math.floor(winkel)==0)
	{
		turnDir = 1;
		winkel = 1;

	}


	if (turnDir == 1)
	{
		if (winkel < (range/2))
		{
			winkel +=  (winkel) * rotationSpeed;
		}
		else
		{
			winkel +=  (range - winkel) * rotationSpeed;
		}

	}
	else
	{
		if (winkel > (range/2))
		{
			winkel -=  (range-winkel) * rotationSpeed;
		}
		else
		{
			winkel -=  (winkel) * rotationSpeed;
		}
	}
	//-180 wird abgezogen, damit es sich unten dreht
	blatt.rotation = winkel - 180;
	blatt.rotationX = winkel;
	
}

Parallax und Peneldbewegung / fallendes Herbstlaub

Hier habe ich die beiden Beispiele Parallax und die letzte Pendelbewegung in einer Klasse "Herbstlaub" zusammengeführt. Zu dieser erweiterten Movieclipklasse gibt es ein Symbol in der Bibliothek der fla Datei. Dort sind in mehreren Schlüsselbildern verschiedene Blattgrafiken hinterlegt.

Für den Inhalt dieser Seite ist eine neuere Version von Adobe Flash Player erforderlich.

Adobe Flash Player herunterladen

 

package 
{
	import flash.display.MovieClip;
	import flash.events.Event;
	

	public class Herbstlaub extends MovieClip
	{

		protected var vertMove:int = 0;
		protected var vertDir:int;
		protected var speed:int;
		protected var focalLength:int = 300;
		protected var scaleRatio:Number;
		protected var zPos:int = 1;
		//Drehung Pendelbewegung
		protected var rotationSpeed = 0.05;
		protected var turnDir:int = 1;
		protected var range:Number = 180;
		protected var winkel:Number;
		protected var addWinkel:Number;




		public function Herbstlaub(_zPos:int=1, _speed:int=9)
		{

			zPos = _zPos;
			speed = _speed;
			winkel = Math.floor(Math.random()*range);
			addWinkel = Math.random()*-180;


			if (stage)
			{
				init();
			}
			else
			{
				addEventListener(Event.ADDED_TO_STAGE,init);
			}


		}

		private function init(e:Event=null):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			addEventListener(Event.REMOVED_FROM_STAGE, destroy);
			addEventListener(Event.ENTER_FRAME,bewegung);
			this.x = Math.random() * this.stage.stageWidth;
			this.y = Math.random() * this.stage.stageHeight;
			gotoAndStop(Math.ceil(Math.random()*this.totalFrames));
			scaleRatio = focalLength / (focalLength + this.zPos);
			this.scaleX = this.scaleY = scaleRatio;
			this.rotation = Math.random() * 180;
		}

		//-----------------------------------------------

		private function destroy(e:Event):void
		{
			removeEventListener(Event.REMOVED_FROM_STAGE, destroy);
			removeEventListener(Event.ENTER_FRAME,bewegung);
		}

		public function bewegung(evt:Event):void
		{
			vertMove = speed;

			if (y < this.stage.stageHeight+this.height)
			{
				this.scaleRatio = this.focalLength/(this.focalLength+this.zPos);
				this.y +=  vertMove * this.scaleRatio;

			}
			else
			{
				this.y = this.height * -3;
				this.x = Math.random() * this.stage.stageWidth;
			}

			//Pendelbewegung Drehung
			if (Math.ceil(winkel) == range)
			{
				turnDir = -1;
				winkel = range - 1;
			}
			else if (Math.floor(winkel)==0)
			{
				turnDir = 1;
				winkel = 1;

			}


			if (turnDir == 1)
			{
				if (winkel < (range/2))
				{
					winkel +=  (winkel) * rotationSpeed;
				}
				else
				{
					winkel +=  (range - winkel) * rotationSpeed;
				}

			}
			else
			{
				if (winkel > (range/2))
				{
					winkel -=  (range - winkel) * rotationSpeed;
				}
				else
				{
					winkel -=  (winkel) * rotationSpeed;
				}
			}
			
			this.rotation = winkel + addWinkel;
			this.rotationX = winkel;


		}
	}
}

Actions im ersten Bild der fla Datei

var anzahl:uint = 60;
var tiefe:uint = 20;
for (var i:uint = 1; i< anzahl; i++)
{
	var blatt:Herbstlaub = new Herbstlaub((anzahl*tiefe)-(i*tiefe));
	addChild(blatt);

}

Programmierte Bewegung mit Perspektive

In diesem Beispiel habe ich die Perspektive von Adobe benutzt. Die programmierte Bewegung ist ganz ähnlich, wie oben im Tipp Parallax, nur hier bewegen sich die Instanzen nicht von oben nach unten sondern entlang der z Achse. Außerdem bestimmt die Z-Position den Alpha, so dass die Instanzen im Hintergrund verschwinden. focal Length und Brennweite hab ich händisch im Eigenschafenfenster der fla eingestellt. Das ist möglich, wenn man eine MC Instanz mit einem der beiden 3D Werkezeuge verändert.

Die Klasse Walker hat ein Movieclipsymbol in der Bibliothek, welches in 3 hintereinanderliegenden Schlüsselbildern, jeweils eine Laufanimation als Movieclip enthält.

Für den Inhalt dieser Seite ist eine neuere Version von Adobe Flash Player erforderlich.

Adobe Flash Player herunterladen

 

Actions in der Klasse Walker

package 
{
	import flash.display.MovieClip;
	import flash.events.Event;

	public class Walker extends MovieClip
	{

		protected var speed:int;
		protected var zPos:int = 1;
		protected var xPos:int = 1;

		public function Walker(_zPos:int=1, _speed:int=4)
		{
			this.z = _zPos;
			speed = _speed;

			if (stage)
			{
				init();
			}
			else
			{
				addEventListener(Event.ADDED_TO_STAGE,init);
			}


		}

		private function init(e:Event=null):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			addEventListener(Event.REMOVED_FROM_STAGE, destroy);
			addEventListener(Event.ENTER_FRAME,bewegung);
			this.x = Math.random() * this.stage.stageWidth;
			gotoAndStop(Math.ceil(Math.random()*this.totalFrames));
			this.y = 400;
		}

		//-----------------------------------------------

		private function destroy(e:Event):void
		{
			removeEventListener(Event.REMOVED_FROM_STAGE, destroy);
			removeEventListener(Event.ENTER_FRAME,bewegung);
		}

		public function bewegung(evt:Event):void
		{
			
			if (z < 1200)
			{
				this.z +=  speed;
			}
			else
			{
				this.z = -1;
				this.x = Math.random() * this.stage.stageWidth;
			}
			this.alpha= ((1200-z))/1200;
		}
	}
}

Actions im ersten Bild der fla Datei

var anzahl:uint = 40;
var tiefe:uint = 30;
for (var i:uint = 1; i< anzahl; i++)
{
	var person:Walker = new Walker((anzahl*tiefe)-(i*tiefe));
	addChild(person);

}

Schlangenbewegung AS3

Hier wird in mehreren Schritten eine Art Schlangenbewegung erklärt. Ein MC folgt der Maus und jedes weitere Element folgt dem vorigen Element.

In der Bibliothek der fla befindet sich ein MC mit Klassennamen "Ball"

Im letzten SWF Beispiel folgt eine ausführliche Erklärung des Scripts.

Beispiel 1

Die dynamische Bewegung auf die Maus zu.

Für den Inhalt dieser Seite ist eine neuere Version von Adobe Flash Player erforderlich.

Adobe Flash Player herunterladen

 

import flash.events.Event;
import flash.display.MovieClip;

var speed:Number = 0.1;
//Ball ist eine MC Klasse in der Bibliothek mit Grafik
var b1:Ball = new Ball();
//Ball wird an der rechten Seite der Bühne plaziert
b1.x = stage.stageWidth - b1.width;
b1.y = 100;


addChild(b1);

b1.addEventListener(Event.ENTER_FRAME, followMouse);

function followMouse(evt:Event):void
{
	//horizontaler Abstand zur Mausposition
	var deltaX:Number = stage.mouseX - b1.x;
	//vertikaler Abstand zur Mausposition
	var deltaY:Number = stage.mouseY - b1.y;
	//Ball legt ein zehntel der Strecke zur Maus zurück: speed=0.1;
	//dadurch ensteht eine dynamische Bewegung, die immer langsamer wird
	b1.x +=  deltaX * speed;
	b1.y +=  deltaY * speed;
}

Beispiel 2

Die Elemente werden aufgestellt.

Für den Inhalt dieser Seite ist eine neuere Version von Adobe Flash Player erforderlich.

Adobe Flash Player herunterladen

import flash.events.Event;
import flash.display.MovieClip;
var anzahl:uint = 10;
var speed:Number = 0.1;//ein Array, in dem alle Ball-Instanzen gespeichert werden
var chain:Array = new Array();
var b1:Ball = new Ball();
b1.x = stage.stageWidth - b1.width;
b1.y = 100;
chain.push(b1);
addChild(b1);
var abstand:Number = b1.width;

for (var i:uint=1; i < anzahl; i++)
{
	//neue Ball Instanz
	var balla:Ball = new Ball();//Referenz auf diese Instanz wird im Array hinterlegt
	chain.push(balla);
	//die Instanz wird links neben der vorigen Instanz plaziert;
	balla.x = chain[i - 1].x - abstand;
	balla.y = b1.y;
	addChild(balla);
}

b1.addEventListener(Event.ENTER_FRAME, followMouse);
function followMouse(evt:Event):void
{
	var deltaX:Number = stage.mouseX - b1.x;
	var deltaY:Number = stage.mouseY - b1.y;
	b1.x +=  deltaX * speed;
	b1.y +=  deltaY * speed;
}

Beispiel 3

Die Element folgen einander.

Für den Inhalt dieser Seite ist eine neuere Version von Adobe Flash Player erforderlich.

Adobe Flash Player herunterladen

import flash.events.Event;
import flash.display.MovieClip;
var anzahl:uint = 10;
var speed:Number = 0.1;
var chain:Array = new Array();
var b1:Ball = new Ball();
b1.x = stage.stageWidth - b1.width;
b1.y = 100;
chain.push(b1);
addChild(b1);
//dist_new ist der gewünschte Abstand, den eine Kugel zur vorigen Kugel einnehmen soll
var dist_new:Number = b1.width;


for (var i:uint=1; i < anzahl; i++)
{
	var chainPart:Ball = new Ball();
	chain.push(chainPart);
	chainPart.x = b1.x - dist_new * (i);
	chainPart.y = b1.y;
	addChild(chainPart);
}


b1.addEventListener(Event.ENTER_FRAME, followMouse);
function followMouse(evt:Event):void
{
	var deltaX:Number = stage.mouseX - b1.x;
	var deltaY:Number = stage.mouseY - b1.y;
	b1.x +=  deltaX * speed;
	b1.y +=  deltaY * speed;
	

	for (i = 1; i < anzahl; i++)
	{
		//horizontaler Abstand zum vorigen Element,
		var distX:Number = chain[i - 1].x - chain[i].x;
		//vertikaler Abstand zum vorigen Element
		var distY:Number = chain[i - 1].y - chain[i].y;
		//Abstand zum vorigen Element (Satz des Pythagoras a² * b² = c²)
		var dist:Number = Math.sqrt(distX*distX+distY*distY);
		//Verhältnis horizontaler Abstand zum wirklichen Abstand
		var cx:Number = distX / dist;//Verhältnis vertikaler Abstand zum wirklichen Abstand
		var cy:Number = distY / dist;
		//der gewünschte Abstand ist "dist_new", der momentane Abstand ist "dist"
		//Das Verhältnis horizontaler Abstand zu momenten Abstand ist "cx"
		//Nun kann man anhand des Verhältnis cx den gewünschten X-Abstand ausrechnen
		var distX_new:Number = cx * dist_new;
		//auf gleiche Weise wird auch der gewünschte Y-Abstand errechnet
		var distY_new:Number = cy * dist_new;
		//Die neue Position wird gesetzt, der errechnete Abstand wird von der Position
		//des vorigen Elementes abgezogen
		chain[i].x = chain[i - 1].x - distX_new;
		chain[i].y = chain[i - 1].y - distY_new;
	}
}

Tutorial Schlangenbewegung

Für den Inhalt dieser Seite ist eine neuere Version von Adobe Flash Player erforderlich.

Adobe Flash Player herunterladen

Weiteres Beispiel mit Rotation

Siehe dazu Math.atan() und Math.atan2() in meinen AS2 Tipps.

Für den Inhalt dieser Seite ist eine neuere Version von Adobe Flash Player erforderlich.

Adobe Flash Player herunterladen

import flash.events.Event;
import flash.display.MovieClip;
var anzahl:uint = 15;
var speed:Number = 0.1;
var chain:Array = new Array();
var b1:Ball = new Ball();
b1.x = stage.stageWidth - b1.width;
b1.y = 100;
chain.push(b1);
addChild(b1);
//dist_new ist der gewünschte Abstand, den eine Kugel zur vorigen Kugel einnehmen soll
var dist_new:Number = b1.width * 0.8;
 
 
for (var i:uint=1; i < anzahl; i++)
{
    var chainPart:Ball = new Ball();
    chain.push(chainPart);
    chainPart.x = b1.x - dist_new * (i);
    chainPart.y = b1.y;
    addChild(chainPart);
}
 
 
b1.addEventListener(Event.ENTER_FRAME, followMouse);
function followMouse(evt:Event):void
{
    var deltaX:Number = stage.mouseX - b1.x;
    var deltaY:Number = stage.mouseY - b1.y;
	//mit Math.atan2() den Winkel im Bogenmaß berechnen
	var rotationRadian:Number = Math.atan2(deltaY,deltaX);
	b1.rotation = (rotationRadian / Math.PI) * 180;
    b1.x +=  deltaX * speed;
    b1.y +=  deltaY * speed;
     
 
    for (i = 1; i < anzahl; i++)
    {
        //horizontaler Abstand zum vorigen Element,
        var distX:Number = chain[i - 1].x - chain[i].x;
        //vertikaler Abstand zum vorigen Element
        var distY:Number = chain[i - 1].y - chain[i].y;
        //Abstand zum vorigen Element (Satz des Pythagoras a² * b² = c²)
        var dist:Number = Math.sqrt(distX*distX+distY*distY);
        //Verhältnis horizontaler Abstand zum wirklichen Abstand
        var cx:Number = distX / dist;//Verhältnis vertikaler Abstand zum wirklichen Abstand
        var cy:Number = distY / dist;
        //der gewünschte Abstand ist "dist_new", der momentane Abstand ist "dist"
        //Das Verhältnis horizontaler Abstand zu momenten Abstand ist "cx"
        //Nun kann man anhand des Verhältnis cx den gewünschten X-Abstand ausrechnen
        var distX_new:Number = cx * dist_new;
        //auf gleiche Weise wird auch der gewünschte Y-Abstand errechnet
        var distY_new:Number = cy * dist_new;
        //Die neue Position wird gesetzt, der errechnete Abstand wird von der Position
        //des vorigen Elementes abgezogen
        chain[i].x = chain[i - 1].x - distX_new;
        chain[i].y = chain[i - 1].y - distY_new;
        //Drehung mit Math.atan2()
        rotationRadian = Math.atan2(distY,distX);
		chain[i].rotation = (rotationRadian / Math.PI) * 180;
    }
}

Schlangenbewegung mittels Point Methoden

Beispiel

Hier noch eine alternative Lösung , welche weitaus weniger Code benötigt, siehe dazu auch das Beispiel in meinem Tipp Point interpolate. Das Beispiel benötigt die Point Methoden, welche in AS2 oder Javascript / Easel JS nicht zur Verfügung stehen, von daher hat auch das vorige Beispiel seine Berechtigung, auch wenn diese Methode einfacher ist.

Jeder MC nimmt zu seinem Vorgänger eine bestimmte Position ein. Die beiden Positionen dieser beiden Instanzen werden in p1 und p2 gespeichert. Zwischen beiden Punkten liegt eine Strecke. Auf dieser Strecke direkt neben der vorigen Instanz liegt die neue Position. Mittels Point.interpolate, kann man diese neue Position bestimmen. Dazu muss man den dritten Parameter ermitteln. Der dritte Parameter ist das Verhältnis des neuen Abstands zum alten Abstand. oder dist_new / dist.

import flash.events.Event;
import flash.display.MovieClip;
import flash.geom.Point;

var anzahl:uint = 15;
var speed:Number = 0.1;
//Array für alle MC Instanzen der Schlange oder Kette
var chain:Array = new Array();
//erstes Element, wird postioniert und folgt der Maus
var b1:Ball = new Ball();
b1.x = stage.stageWidth - b1.width;
b1.y = 100;
chain.push(b1);

b1.addEventListener(Event.ENTER_FRAME, followMouse);

//dist_new ist der gewünschte Abstand, den eine Kugel 
//zur vorigen Kugel einnehmen soll
var dist_new:Number = b1.width * 0.5;
//verschiedene Points, die später zur Bestimmung der Position benötigt werden
var p1:Point;
var p2:Point;
var p3:Point;

//alle weiteren Instanzen werden erzeugt und nebeneinander positioniert
for (var i:int=1; i < anzahl; i++)
{
	var chainPart:Ball = new Ball();
	chainPart.x = b1.x - dist_new * (i);
	chainPart.y = b1.y;
	chain.push(chainPart);
}

//Instanzen der Displayliste hinzufügen, das letzte zuerst
for (i = chain.length-1; i >= 0; i--)
{
	addChild(chain[i]);
}

//Enter Frame, Maus folgen und alle Elemente anordnen
//siehe Tipp Point interpolate und Point.distance

function followMouse(evt:Event):void
{
	//dynamische Bewegung des ersten Elements auf die Maus zu
	var deltaX:Number = stage.mouseX - b1.x;
	var deltaY:Number = stage.mouseY - b1.y;
	b1.x +=  deltaX * speed;
	b1.y +=  deltaY * speed;


	for (i = 1; i < anzahl; i++)
	{
		//Positionen von 2 aufeinanderfolgednen Elementen
		p1 = new Point(chain[i].x,chain[i].y);
		p2 = new Point(chain[i - 1].x,chain[i - 1].y);
        chain[i].scaleX = chain[i].scaleY = 1.2 - i/anzahl;
		//der Abstand der beiden Punkte bzw. mcs
		var dist:Number = Point.distance(p1,p2);       	
        //neuer Abstand auf der Strecke, die zwischen beiden Punkten liegt
        // mittels interpolate
		//Verhältnis von "dist" zu "dist_new" bestimmt den Abstand(ein Wert zwischen 0 und 1)
		dist_new = chain[i].width/3;
        p3 = Point.interpolate(p1,p2,  dist_new/dist);
		chain[i].x = p3.x;
		chain[i].y = p3.y;
	}
}

 

 

 

http://www.pastorpixel.de