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.

Siehe auch Timer, dort werden programmierte Bewegungen mittels Timer erstellt

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

stage.addEventListener(KeyboardEvent.KEY_DOWN, KeyDownFunc);

function KeyDownFunc(event){

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

}

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.

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);
		}
	}
}

 

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("runterTASte");
	} 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.

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;			
		}
		
	}
}

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.

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 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;
}
}
}

 

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/

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 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. Im Gegensatz zu AS2 kann man in AS3 nicht einfach über _root._xmouse, _root._ymouse auf die Mousposition zugreifen, sondern hier sind die Mauskoordinaten an einen Mouse-Event gebunden.

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

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;
			}	
		
	}
}

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;
			}
		}
	}
}


http://www.pastorpixel.de