Drag and Drop - zurück zum Ausgangspunkt

Häufig sieht man folgende Variante von Drag and Drop:Wenn beim Loslassen der Maustaste das gezogene Objekt nicht über dem Ziel liegt, soll das Objekt wieder zum Ausgangspunkt zurückspringen. Oder umgekehrt formuliert: Beim Loslassen über einem "verbotenen" Bereich soll das Objekt wieder seine ursprüngliche Position einnehmen.

Zum Ausprobieren: Durch Klick auf die dunkelblaue Fläche einen Stern erzeugen. Wenn dieser nach dem Ziehen wieder über der dunkelblauen Fläche losgelassen wird, springt es zum Ausgangspunkt zurück.

 

 

Zu diesem Zweck muss man sich beim Anklicken des Objekts die momentane Position merken und beim Loslassen der Maustaste prüfen, ob das Objekt über dem Ziel liegt. Wenn das nicht der Fall ist, wird das Objekt auf die gespeicherte Ausgangsposition zurückgesetzt.

Wir definieren dazu zwei Variable startPosX und startPosY in denen die Ausgangsposition gespeichert wird:
 

var startPosX: Number;
var startPosY: Number;

Beim Anklicken des Objekts wird der Eventhandler startZiehen ausgeführt. Darin werden die x- und y-Koordinaten des angeklickten Objekts e.target in den beiden Variablen startPosX und startPosY gespeichert und damit für später gemerkt.
 

function startZiehen(e:MouseEvent):void {
e.target.startDrag(false);
startPosX = e.target.x;
startPosY = e.target.y;

}

Beim Loslassen der Maustaste wird der Eventhandler stopZiehen ausgeführt. Darin wird nach einer der im letzten Kapitel vorgestellten Methoden überprüft, ob das losgelassene Objekt über dem Ziel liegt. Wenn das der Fall ist, wird das Objekt auf das Ziel ausgerichtet. Wenn nicht, werden die x- und y-Koordinaten des gezogenen Objekts e.target auf die in startPosX und startPosY gespeicherten Ausgangswerte zurückgesetzt.
 

function stopZiehen(e:MouseEvent):void {
e.target.stopDrag();
if (e.target.hitTestObject(ziel)) {
e.target.x = ziel.x;
e.target.y = ziel.y;
} else {
e.target.x = startPosX;
e.target.y = startPosY;
}

}

Zusammengefasst ergibt sich folgendes Skript im ersten Frame der Maintimeline:
 

// Stern durch Anklicken der Bühne erzeugen
this.stage.addEventListener(MouseEvent.MOUSE_UP,erzeugeStern);
function erzeugeStern(e:MouseEvent):void {
if (e.target == e.currentTarget) {
var stern:MovieClip = new GelberStern();
this.addChild(stern);
stern.x = e.stageX;
stern.y = e.stageY;
}
}
// Stern bei gedrückter Maustaste ziehen
var startPosX: Number;
var startPosY: Number;

this.addEventListener(MouseEvent.MOUSE_DOWN, startZiehen);
function startZiehen(e:MouseEvent):void {
e.target.startDrag(false);
startPosX = e.target.x;
startPosY = e.target.y;

}
this.addEventListener(MouseEvent.MOUSE_UP, stopZiehen);
function stopZiehen(e:MouseEvent):void {
e.target.stopDrag();
if (e.target.hitTestObject(ziel)) {
e.target.x = ziel.x;
e.target.y = ziel.y;
} else {
e.target.x = startPosX;
e.target.y = startPosY;
}

}

 

Wo müssen die Variblen startPosX und startPosY deklariert werden?

Da die Variablen startPosX und startPosY in den beiden Funktionen stopZiehen und startZiehen verwendet werden, muss die var-Deklaration außerhalb der Funktionen erfolgen.

Wir können daher, wie im obigen Beispiel den Deklarationsblock

var startPosX: Number;
var startPosY: Number;
  1. im Skript der Maintimeline außerhalb der Funktionsdefinitionen platzieren oder
     
  2. im ersten Frame des Movieclips GelberStern. In diesem Fall sind die Variablen Eigenschaften des Movieclips.
    Um die beiden Variablen in den Funktionsdefinitionen von startZiehen und stopZiehen richtig anzusprechen muss man
    e.target.startPosX bzw. e.target.startPosY
    schreiben, weil sie Eigenschaften des angeklickten Objekts sind.
An diesem kleinen Beispiel sieht man, dass es immer mehrere Möglichkeit gibt, ein Problem zu lösen.
 

Verfeinerung des Skripts:

Mit dem obigen Skript kann man einen Stern, der einmal in den hellblauen Kreis gezogen wurde, nicht mehr aus diesem herausziehen.
Wenn man das ermöglichen möchte, muss man eine weitere boolsche Variable hitTest einführen, in der gespeichert wird, ob die Ausgangsposition des Sterns über dem hellblauen Kreis war oder nicht.
Beim Loslassen der Maustaste über der dunkelblauen Fläche (d.h. außerhalb des Ziels) wird dann die Variable hitTest abgefragt. Nur wenn die Ausgangsposition nicht über dem hellblauen Kreis war (hitTest hat den Wert false) erfolgt das Zurückspringen in die Ausgangsposition.
 

var startPosX: Number;
var startPosY: Number;
var hitTest:Boolean;
this.addEventListener(MouseEvent.MOUSE_DOWN, startZiehen);
function startZiehen(e:MouseEvent):void {
e.target.startDrag(false);
startPosX = e.target.x;
startPosY = e.target.y;
if (e.target.hitTestObject(ziel)) {
hitTest = true;
} else {
hitTest = false;
}

}
this.addEventListener(MouseEvent.MOUSE_UP, stopZiehen);
function stopZiehen(e:MouseEvent):void {
e.target.stopDrag();
if (e.target.hitTestObject(ziel)) {
e.target.x = ziel.x;
e.target.y = ziel.y;
} else {
if (hitTest == false) {
e.target.x = startPosX;
e.target.y = startPosY;
}

}
}
 
 
Quellcode in der beigefügten zip-Datei:
dragDrop_back.fla
dragDrop_back1.fla

Ergänzende und vertiefende Module