Objekt in Richtung eines Punktes bewegen

Hier zeige ich eine Möglichkeit, wie ein Objekt in Richtung eines vorgegebenen Punktes fährt.  Das Objekt soll sich immer langsamer an den Punkt annähern. Dies erreichen wir, in dem wir die Distanz vom Objekt zum Ziel ermitteln und mit einem Faktor (xSpeed, ySpeed) mulitpliziren. Den so ermittelten Wert können wir ganz einfach zu der aktuellen Position des Objektes addieren.  Um der ganzen Bewegung ein Ende zu geben, brechen wir mit einem vorgegebenen Kleinstwert (xTeminate, yTerminate) ab.

Die Klasse Target zeigt das aktuelle Ziel an. Wie man hier sehen kann, funktioniert die Technik auf zum Skalieren. Es gibt zudem noch unzählige andere Möglichkeiten.

Am Ende des Beitrages befindet der sich der Link für die Sourcen. Umgesetzt habe ich dies mit FlashDevelop 3.0.6  RTM

package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;

	/**
	 * @author Andreas Khong
	 * @copy www.flashdevelop.de
	 */
	public class Main extends Sprite
	{
		/* Die ersten vier Werte können im Bereich zwischen 1 - 0 eingestellt werden */

		/* Werte für die Bewegungsgeschwindikeit */
		public var xSpeed:Number = .1;
		public var ySpeed:Number = .1;

		/* Werte ab welchem Kommawert beendet werden soll */
		public var xTerminate:Number = .05;
		public var yTerminate:Number = .05;

		/* Wo solls hingehen */
		private var _moveTo:Point; 

		/* Der Ball */
		private var _ball:Sprite;

		/* Optisches Zielsignal*/
		private var _target:Target;

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

		private function init(e:Event = null):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point

			// optisches Ziel auf Bühnenmitte erstellen
			_target = new Target();
			_target.x = stage.stageWidth >> 1;
			_target.y = stage.stageHeight >> 1;
			addChild(_target);

			// Ball zeichnen
			_ball = new Sprite();
			_ball.graphics.beginFill(0xff0000);
			_ball.graphics.drawCircle(0, 0, 10);
			_ball.graphics.endFill();
			//Auf die Bühnenmitte
			_ball.x = stage.stageWidth >> 1;
			_ball.y = stage.stageHeight >> 1;
			addChild(_ball);

			//Auf Click-Event horchen. Listener auf oberste Ebene setzen (parent)
			parent.addEventListener(MouseEvent.CLICK, handleMouseClick);

			// Infotext
			var tf:TextField = new TextField();
			tf.defaultTextFormat = new TextFormat("Verdana", 14, 0x000000);
			tf.mouseEnabled = false;
			tf.selectable = false;
			tf.autoSize = TextFieldAutoSize.CENTER;
			tf.multiline = false;
			tf.x = stage.stageWidth >> 1;
			tf.y = stage.stageHeight - 20;
			tf.text = "Auf die Bühne klicken, damit der Ball dort hinfährt!";
			addChild(tf);
		}

		/**
		 * Setzt die Position _moveTo an die Mausposition.
		 * @param	evt		MouseEvent
		 */
		private function handleMouseClick(evt:MouseEvent):void
		{
			// geklickte Position setzen
			_moveTo = new Point(evt.target.mouseX, evt.target.mouseY);

			// optisches Ziel versetzen
			_target.x = _moveTo.x;
			_target.y = _moveTo.y;

			//EnterFrame-Listener hinzufügen
			addEventListener(Event.ENTER_FRAME, update);

			// optisches Ziel animieren
			_target.play();
		}

		/**
		 * Bewegt den Ball in Richtung des Ziels _moveTo
		 * @param	evt		Event
		 */
		private function update(evt:Event):void
		{
			// nächste X und Y Werte errechnen
			var dx:Number = (_moveTo.x - _ball.x) * xSpeed;
			var dy:Number = (_moveTo.y - _ball.y) * ySpeed;

			// kleinste Kommawerte terminieren und EnterFrame-Listener entfernen
			if (Math.abs(dx) < xTerminate && Math.abs(dy) < yTerminate)
			{
				dx = 0;
				dy = 0;

				//hier können wir den Ball auch auf die genaue Position setzen
				_ball.x = _moveTo.x;
				_ball.y = _moveTo.y;

				// EnterFrame-Listener entfernen
				removeEventListener(Event.ENTER_FRAME, update);

				// animation vom optischen Ziel stopen
				_target.stop();
			}

			// Ball umd dx und dy verschieben
			_ball.x += dx;
			_ball.y += dy;
		}

	}

}
package
{
	import flash.display.MovieClip;
	import flash.events.Event;
	/**
	 * ...
	 * @author Andreas Khong
	 * @copy www.flashdevelop.de
	 */
	public class Target extends MovieClip
	{
		/* Skalierungsrichtung */
		private var _scaleTo:Number;

		public function Target()
		{
			// paar Kreise mit unterschiedlichem Alpha
			graphics.lineStyle(1, 0x004993, .1);
			graphics.drawCircle(0, 0, 1);
			graphics.lineStyle(1, 0x004993, .2);
			graphics.drawCircle(0, 0, 2);
			graphics.lineStyle(1, 0x004993, .4);
			graphics.drawCircle(0, 0, 4);
			graphics.lineStyle(1, 0x004993, .6);
			graphics.drawCircle(0, 0, 6);
			graphics.lineStyle(1, 0x004993, .8);
			graphics.drawCircle(0, 0, 8);
			graphics.lineStyle(1, 0x004993, 1);
			graphics.drawCircle(0, 0, 10);

			// Skalierung setzen
			_scaleTo = 2;
		}

		/**
		 * Skaliert sich selbst von klein nach groß nach klein ...
		 * @param	evt  Event
		 */
		private function update(evt:Event):void
		{
			// nächsten Wert errechnen. Hier brauchen wir nur scaleX oder scaleY, da beide synchron laufen.
			var d:Number = (_scaleTo - scaleX) * .1;

			// bei ganz kleinen Kommawerten Richtung ändern
			if (Math.abs(d) < .01)
			{
				_scaleTo = _scaleTo == 2 ? 1 : 2;
			}

			// skalieren
			scaleX += d;
			scaleY += d;

		}

		/**
		 * @see flash.display.MovieClip.play
		 */
		override public function play():void
		{
			super.stop();

			// Listener hinzufügen
			addEventListener(Event.ENTER_FRAME, update);
		}

		/**
		 * @see flash.display.MovieClip.stop
		 */
		override public function stop():void
		{
			super.play();

			// Listener hinzufügen
			removeEventListener(Event.ENTER_FRAME, update);

			// auf Originalgröße setzen
			scaleX = 1;
			scaleY = 1;

			// zurücksetzen auf Anfangswert
			_scaleTo = 2;
		}

	}

}

Projektdateien findet ihr unter diesem Link: Objekt in Richtung eines Punktes bewegen

Mausverfolger aus dem ersten  Kommentar.

Teilen macht glücklich!
  • facebook
  • Twitter
  • Delicious
  • Digg
  • StumbleUpon
  • Google Bookmarks
  • email
  • RSS

Tags: , , , , , ,

Ein Kommentar zu “Objekt in Richtung eines Punktes bewegen”

  1. A. Khong sagt:

    mit wenigen Handgriffen kann daraus auch ein Mausverfolger gemacht werden.

    Zu Beginn der update-Funktion einfach _moveTo jedes mal neu setzen.
    /**
    * Bewegt den Ball in Richtung des Ziels _moveTo
    * @param evt Event
    */
    private function update(evt:Event):void
    {
    _moveTo = new Point(parent.mouseX, parent.mouseY);

    Dann muss noch dafür gesort werden, dass update kontinuielich ausgeführt wird. In dem man init addEventListener(Event.EnterFrame, update); aufruft. MouseEvent.CLICK muss entfernt werden und ebenfalls das removeEvnetListener(Event.EnterFrame, update); in Zeile 120, ansonsten muss der Event wieder gestartet werden, sobald sich die Maus bewegt.

Kommentar hinterlassen

*