0

I am trying to make a small drag and drop application in flash , i have been able to achieve the following -

1)Drag the movie clips

2)Make sure that two movieclips do not interchange positions when put over each other

3)Make sure the MC that is being dragged stays on top of other movieclips ..

4)Make the movieclip stay when its dropped at designated position

However there is one very important thing i am unable to achieve , when the cursor moves out of stage , the movie clips gets stuck to the cursor , i want that the moment the user goes out of stage the clip that is being dragged goes back to its original position ...

I have tried using the mouse_leave option for this but it does not work...

I am adding the code for drag and drop as below , please guide me here -

Drag Code -

Array to hold the target instances, the drop instances, and the start positions of the drop instances.

var hitArray:Array = new Array(hitTarget1,hitTarget2,hitTarget3);
var dropArray:Array = new Array(drop1,drop2,drop3);
var positionsArray:Array = new Array();

This adds the mouse down and up listener to the drop instances and add the starting x and y positions of the drop instances into the array.

 for (var i:int = 0; i < dropArray.length; i++) {
    dropArray[i].buttonMode = true;
    dropArray[i].addEventListener(MouseEvent.MOUSE_DOWN, mdown);
    dropArray[i].addEventListener(MouseEvent.MOUSE_UP, mUp);
    positionsArray.push({xPos:dropArray[i].x, yPos:dropArray[i].y});
    }

This drags the object that has been selected and moves it to the top of the display list. This means you can't drag this object underneath anything.

function mdown(e:MouseEvent):void {
e.currentTarget.startDrag();
setChildIndex(MovieClip(e.currentTarget), numChildren - 1);
}

And here is the drop code

This stops the dragging of the selected object when the mouse is released. If the object is dropped on the corresponding target then it get set to the x and y position of the target. Otherwise it returns to the original position.

 function mUp(e:MouseEvent):void {
    var dropIndex:int = dropArray.indexOf(e.currentTarget);
    var target:MovieClip = e.currentTarget as MovieClip;
    target.stopDrag();
    if (target.hitTestObject(hitArray[dropIndex])) {
    target.x = hitArray[dropIndex].x;
    target.y = hitArray[dropIndex].y;
    }else{
    target.x = positionsArray[dropIndex].xPos;
    target.y = positionsArray[dropIndex].yPos;
    }
    }

Please tell me how to use mouse_leave here and make the snap back, used it in the both drag and drop section like this below

stage.addEventListener(Event.MOUSE_LEAVE, mouseLeave);

but always get some error like stage does not support property x etc. i add some code like equating the x and y but it does not work .. please guide

Jin

multiverse
  • 425
  • 3
  • 13
  • try `stage.addEventListener(MouseEvent.MOUSE_OUT)` instead. Event.MOUSE_LEAVE doesn't exist. –  Aug 03 '14 at 15:31
  • possible duplicate of [Detect Mouse leave stage while dragging in Actionscript 3](http://stackoverflow.com/questions/1563434/detect-mouse-leave-stage-while-dragging-in-actionscript-3) – Anil Aug 03 '14 at 16:42
  • @SlyRaskal -thanks, i tried that code earlier and it does work in the sense that it detects when the moves leaves the stage but for some reason it does not snap the MC back to original and also keeps the MC attached to mouse i tried using the original x,y coordinates but it does not work ...@DodgerThud thanks , i will try mouse out as well , but it seems mouse_leave does exist ... – multiverse Aug 03 '14 at 18:13

1 Answers1

1

MOUSE_LEAVE shows if we are in or out of the stage, but doesn't detect the position of the mouse. You have to collect mouse's data on MOUSE_DOWN, to restrict the instance into the limits.

const LL:uint = 0;
const LT:uint = 0;
const LR:uint = stage.stageWidth;
const LB:uint = stage.stageHeight;

function EnterFrame(e:Event):void {
    e.target.x = mouseX;
    e.target.y = mouseY;
    if (mouseX < LL) {e.target.x = LL;} else if (mouseX > LR) {e.target.x = LR;}
    if (mouseY < LT) {e.target.y = LT;} else if (mouseY > LB) {e.target.y = LB;}
}

In your function 'mdown':

e.currentTarget.addEventListener(Event.ENTER_FRAME, EnterFrame);

In your function 'mUp':

target.removeEventListener(Event.ENTER_FRAME, EnterFrame);

General method

Here is the way this can be done. On MOUSE_UP outside the limits, the target is [object stage]. So you have to create a variable __last that will make you recognize the instance (p1 or another) clicked on MOUSE_DOWN. StartDrag() isn't needed:

const LL:uint = 0;
const LT:uint = 0;
const LR:uint = stage.stageWidth;
const LB:uint = stage.stageHeight;

function EnterFrame(e:Event):void {
    e.target.x = mouseX;
    e.target.y = mouseY;
    if (mouseX < LL) {e.target.x = LL;} else if (mouseX > LR) {e.target.x = LR;}
    if (mouseY < LT) {e.target.y = LT;} else if (mouseY > LB) {e.target.y = LB;}
}

var __last:*;

p1.addEventListener(MouseEvent.MOUSE_DOWN, OnMouseDown);
function OnMouseDown(e:MouseEvent):void {
    __last = MovieClip(e.target);
    __last.addEventListener(Event.ENTER_FRAME, EnterFrame);
}

this.stage.addEventListener(MouseEvent.MOUSE_UP, OnMouseUp);
function OnMouseUp(e:MouseEvent):void {
    if(__last) __last.removeEventListener(Event.ENTER_FRAME, EnterFrame);
}

To snap it back to original position

const LL:uint = 0;
const LT:uint = 0;
const LR:uint = stage.stageWidth;
const LB:uint = stage.stageHeight;

var __last:*;
var dropIndex:int;

function EnterFrame(e:Event):void {
    if (mouseX < LL || mouseX > LR || mouseY < LT || mouseY > LB) {
        __last.x = positionsArray[dropIndex].xPos;
        __last.y = positionsArray[dropIndex].yPos;
        __last.stopDrag();
    }
}

var hitArray:Array = new Array(hitTarget1, hitTarget2, hitTarget3);
var dropArray:Array = new Array(drop1, drop2, drop3);
var positionsArray:Array = [];

for (var i:int = 0; i < dropArray.length; i++) {
    dropArray[i].buttonMode = true;
    dropArray[i].addEventListener(MouseEvent.MOUSE_DOWN, mdown);
    dropArray[i].addEventListener(MouseEvent.MOUSE_UP, mUp);
    positionsArray.push({xPos:dropArray[i].x, yPos:dropArray[i].y});
}

function mdown(e:MouseEvent):void {
    __last = e.currentTarget;
    dropIndex = dropArray.indexOf(__last);
    setChildIndex(MovieClip(__last), numChildren - 1);
    __last.startDrag();
    addEventListener(Event.ENTER_FRAME, EnterFrame);
}

function mUp(e:MouseEvent):void {
    if (__last.hitTestObject(hitArray[dropIndex])) {
        __last.x = hitArray[dropIndex].x;
        __last.y = hitArray[dropIndex].y;
    } else {
        __last.x = positionsArray[dropIndex].xPos;
        __last.y = positionsArray[dropIndex].yPos;
    }
    __last.stopDrag();
    removeEventListener(Event.ENTER_FRAME, EnterFrame);
}
helloflash
  • 2,457
  • 2
  • 15
  • 19
  • -thanks, i tried the first method its not working , sadly its the same thing it can detect the mouse out but does not snap it back to original position ... – multiverse Aug 04 '14 at 06:30
  • @multiverse: save the position when an item starts being moved and store it like "_originalPosition = mc. – Daniel MesSer Aug 04 '14 at 06:59
  • @DanielMesSer - tried that using -startXZ = event.target.x; startYZ = event.target.y; stage.addEventListener(Event.MOUSE_LEAVE, mouseLeaveA); function mouseLeaveA(e:Event) :void { event.target.stopDrag(); event.target.x = startXZ; event.target.y = startYZ; stage.removeEventListener(Event.MOUSE_LEAVE, mouseLeaveA); } but it messes up all the positions , like it does snap them back when out of stage but then all objects just overlap over one another when taken out of stage ....can you please guide – multiverse Aug 04 '14 at 07:24
  • @helloflash - thanks a lot , i will try and get back to you , thanks again for the time and patience with me here ... – multiverse Aug 04 '14 at 16:28
  • @helloflash -thanks a ton, this is just perfect , there is just one small help i need , i created a timer to make the user put objects in right place in say 10 seconds , now it all works well but when the timer is over , i send the control to a failed frame but there , the movie clips that are moved appear on top as the set index is -1 , when i come back to the original frame they are stacked over one another and then when i move them due to duplicate values they give error , how can i make the set index to normal - – multiverse Aug 05 '14 at 07:41
  • here is the timer - var myTimerA:Timer = new Timer(1000,61); // every second for 60 seconds myTimerA.addEventListener(TimerEvent.TIMER, onTimerA); myTimerA.addEventListener(TimerEvent.TIMER_COMPLETE, onCompleteA); myTimerA.start(); function onTimerA(e: TimerEvent):void { timer_txtA.text = String(myTimerA.repeatCount - myTimerA.currentCount); } function onCompleteA(e: TimerEvent):void{ removeEventListener(Event.ENTER_FRAME, EnterFrame); myTimerA.removeEventListener(TimerEvent.TIMER_COMPLETE, onCompleteA); myTimerA.stop(); myTimer.stop(); gotoAndStop("failed1"); } – multiverse Aug 05 '14 at 07:42