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.









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.