actionscript 3.0 drag and swap - actionscript-3

This is my code for dragging and dropping movie clips into their matching movie clip targets. I would like to make a jigsaw puzzle game where all the pieces are in some place, and when one piece is dragged onto another, they two pieces swap and if the piece matches the target it should lock into place and stay there with this code. Only problem is I don't know how to make the pieces swap locations. Any ideas?? Is this even possible?? Please help...
function pickupObject(event:MouseEvent):void {
event.target.startDrag(true);
event.target.parent.addChild(event.target);
objectoriginalX=event.target.x;
objectoriginalY=event.target.y;
}
function dropObject(event:MouseEvent):void {
event.target.stopDrag();
var matchingTargetName:String="target"+ event.target.name;
var matchingTarget:DisplayObject=getChildByName(matchingTargetName);
if(event.target.dropTarget != null && event.target.dropTarget.parent==matchingTarget) {
event.target.removeEventListener(MouseEvent.MOUSE_DOWN, pickupObject);
event.target.removeEventListener(MouseEvent.MOUSE_UP, dropObject);
event.target.buttonMode=false;
event.target.x=matchingTarget.x;
event.target.y=matchingTarget.y;
}
}

Store drag and drop objects in two different arrays and x and y positions also. Consider 3 drag and drop objects.
var drag:Array = new Array(drag0, drag1, drag2);
var drop:Array = new Array(drag0_target, drag1_target, drag2_target);
var points:Array = new Array({x:drag_0.x, y:drag_0.y},...);
//this regular expression will return a digit number from given string.
var pattern:RegExp = /\d/;
note: drop array object names should be start with drag object names. For matching purpose.
Add mouse listeners to the drag array objects.
MouseDownHandler()
e.target.startDrag();
MouseUpHandler()
//create a tmp variable for store the current drag object number;
tmp = e.target.name.match(pattern);
for(i=0;i<drop.length; i++){
//Check whether the hit occurred in the drop clips
if(MovieClip(e.target).hitTestObject(this.drop[i])){
//Check whether the object has been dropped in a right place.
if(drop[i].name.split("_")[0] == e.target.name){
e.target.x = drop[i].x;
e.target.y = drop[i].y;
}else{
//else place the drag object into the initial position.
e.target.x = points[tmp].x;
e.target.y = points[tmp].y;
}
}
}
Good luck.

Related

Flash AS3 - Drag and drop multiple objects to multiple targets

I have multiple objects to drag to multiple targets.
I have a code without error.
I am using multiple functions. But I wonder if I pass the objects and the specific target with one function like dropIt since I have more objects and duplicated functions.
This picture is what I want to implement.
and the code is as follows.
Thanks in advance.
var obj1:Array = [obj_1, obj_10];
var obj2:Array = [obj_2, obj_20];
for each(var redsMC:MovieClip in reds)
{
obj1MC.buttonMode = true;
obj1MC.addEventListener(MouseEvent.MOUSE_DOWN, pickUp);
obj1MC.addEventListener(MouseEvent.MOUSE_UP, dropIt);
obj1MC.startX = obj1MC.x;
obj1MC.startY = obj1MC.y;
}
for each(var orangesMC:MovieClip in oranges)
{
obj2MC.buttonMode = true;
obj2MC.addEventListener(MouseEvent.MOUSE_DOWN, pickUp);
obj2MC.addEventListener(MouseEvent.MOUSE_UP, dropIt1);
obj2MC.startX = obj2MC.x;
obj2MC.startY = obj2MC.y;
}
function pickUp(event:MouseEvent):void
{
event.target.startDrag(true);
event.target.parent.addChild(event.target);
}
function dropIt(event:MouseEvent):void
{
event.target.stopDrag();
if(event.target.hitTestObject(target1)){
event.target.buttonMode = false;
event.target.x = target1.x;
event.target.y = target1.y;
}else if(event.target.hitTestObject(target10)){
event.target.buttonMode = false;
event.target.x = target10.x;
event.target.y = target10.y;
}
else
{
event.target.x = event.target.startX;
event.target.y = event.target.startY;
event.target.buttonMode = true;
}
}
function dropIt1(event:MouseEvent):void
{
event.target.stopDrag();
if(event.target.hitTestObject(target2)){
event.target.buttonMode = false;
event.target.x = target2.x;
event.target.y = target2.y;
}else if(event.target.hitTestObject(target20)){
event.target.buttonMode = false;
event.target.x = target20.x;
event.target.y = target20.y;
}
else
{
event.target.x = event.target.startX;
event.target.y = event.target.startY;
event.target.buttonMode = true;
}
}
You should somehow make your draggable objects know their targets, thus when your SWF registers an end drag event, the object that was being dragged would check against its target and if not colliding, then float/jump back. Since your objects derive from MovieClips, it's possible to add custom properties to them without doing any declarations, but be sure to check if there is something in a custom property before using it. Let's say you have assigned each draggable object a desiredTarget as whatever target you need them to be dragged. Then, you can do like this:
function dropIt(e:MouseEvent):void {
var desiredTarget:MovieClip=e.target.desiredTarget as MovieClip; // get where this should be placed
e.target.stopDrag(); // we still need to release the dragged object
if (!desiredTarget) return; // no target - nothing to do (also helps with debug)
if (e.target.hitTestObject(desiredTarget)) {
e.target.buttonMode=false;
e.target.x=desiredTarget.x;
e.target.y=desiredTarget.y;
} else {
// move dragged object back to starting position
e.target.x=e.target.startX;
e.target.y=e.target.startY;
}
}
Despite the fact Vesper's answer is already accepted, I think it to be far too brief and insufficient, on top of that it doesn't actually answer how to design a system where any number of objects could be dropped to any number of targets, without substantial changes to the code.
// Unlike the Object class, that allows String keys only
// the Dictionary class allows you to store and
// access data by the object instance.
var theValids:Dictionary = new Dictionary;
// We'll store the original (x,y) coordinates here.
var theOrigin:Point = new Point;
// The Sprite class is the superclass of MovieClip, furthermore,
// the startDrag method defined for Sprite class, so unless you
// create your own dragging code, you are bound to use Sprites,
// while you cannot drag SimpleButtons and TextFields this way.
// We'll store the current dragged object here.
var theObject:Sprite;
// This first argument is the object you want to be draggable.
// The "...targets:Array" means you can call this method with
// any number of arguments, the first one is mandatory, the
// rest will be passed in a form of Array (empty Array if you
// call this method with a single argument).
function setupDraggable(source:Sprite, ...targets:Array):void
{
// Make the object draggable.
source.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
source.mouseChildren = false;
source.mouseEnabled = true;
source.buttonMode = true;
// Keep the list of the object's targets so it can be
// retrieved later by the key of the object itself.
theValids[source] = targets;
}
// Ok, let's setup the objects and link them to their designated
// targets. The whole point of the rest of the code is to make
// this one part as simple as it possible: you just edit
// these lines to tell which one objects go where.
// This object can be dropped to a single target.
setupDraggable(obj_1 , target1);
// These objects can go to two targets each.
setupDraggable(obj_10, target1, target10);
setupDraggable(obj_2 , target2, target20);
// This one object can be dropped to any of targets.
setupDraggable(obj_20, target1, target10, target2, target20);
// The MOUSE_DOWN event handler.
function onDown(e:MouseEvent):void
{
// Get the reference to the object under the mouse.
theObject = e.currentTarget as Sprite;
// Keep the object's initial position.
theOrigin.x = theObject.x;
theOrigin.y = theObject.y;
// Put the dragged object on top of anything else.
// We are operating in the parent context of all these
// objects here so there's no need to address anObj.parent.
setChildIndex(theObject, numChildren - 1);
// Start dragging.
theObject.startDrag(true);
// Listen to the MOUSE_UP event, which could happen offstage
// and out of the dragged object, so the only reliable
// way is to listen it from the Stage. That's why we
// are keeping theObject reference as an additional
// variable, without relying on event's data.
stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
}
// The MOUSE_UP event handler.
function onUp(e:MouseEvent):void
{
// Unsubscribe the MOUSE_UP event handler.
stage.removeEventListener(MouseEvent.MOUSE_UP, onUp);
// Stop the dragging process.
theObject.stopDrag();
// Let's assume there could be more than a single collision.
// We need to figure the one target that is closest.
var theTarget:DisplayObject;
var theDistance:int = 100000;
// Store the dragged object position so we can
// measure distances to the valid collisions, if any.
var thePlace:Point = theObject.localToGlobal(new Point);
// Now, the magic. Lets browse through the
// valid targets and see if there's a collision.
for each (var aTarget:DisplayObject in theValids[theObject])
{
if (theObject.hitTestObject(aTarget))
{
// Let's see if the current collision is closer
// to the dragged object, than the previous one
// (if any, that's what initial 100000 for).
var aPlace:Point = aTarget.localToGlobal(new Point);
var aDistance:int = Point.distance(aPlace, thePlace);
if (aDistance < theDistance)
{
theTarget = aTarget;
theDistance = aDistance;
}
}
}
// If there's at least one collision,
// this variable will not be empty.
if (theTarget)
{
// Make the object non-interactive.
theObject.removeEventListener(MouseEvent.MOUSE_DOWN, onDown);
theObject.mouseEnabled = false;
theObject.buttonMode = false;
// Glue the dragged object to the center of the target.
theObject.x = theTarget.x;
theObject.y = theTarget.y;
}
else
{
// If we're here, that means there was no valid collisions,
// lets return the object to its designated place.
theObject.x = theOrigin.x;
theObject.y = theOrigin.y;
}
// Clean-up. Remove the reference, the object is no longer
// being dragged, so you won't need to keep it.
theObject = null;
}
P.S. I didn't test it, but I think I put enough comments to explain the whole idea.

remove drag and drop objects when exit frame on button click

i want to make flash application that allowed users to match picture with the box containing its first letter of the word. the method is drag and drop with target. i'm really new to this.
drag and drop target is working so far but my problem is when i exit the frame after moving the object, the drag and drop object still visible.
how can i remove this object when leaving frame?
here is what i got:
import flash.events.MouseEvent;
import flash.display.DisplayObject;
var objectoriginalX:Number;
var objectoriginalY:Number;
a.buttonMode = true;
a.addEventListener(MouseEvent.MOUSE_DOWN, pickupObject);
a.addEventListener(MouseEvent.MOUSE_UP, dropObject);
function pickupObject(event:MouseEvent):void
{
event.target.startDrag();
event.target.parent.addChild(event.target);
objectoriginalX = event.target.x;
objectoriginalY = event.target.y;
}
function dropObject(event:MouseEvent):void
{
event.target.stopDrag();
var matchingTargetName:String = "target" + event.target.name;
var matchingTarget:DisplayObject = getChildByName(matchingTargetName);
if(event.target.dropTarget != null && event.target.dropTarget.parent == matchingTarget)
{
event.target.removeEventListener(MouseEvent.MOUSE_DOWN, pickupObject);
event.target.removeEventListener(MouseEvent.MOUSE_UP, dropObject);
event.target.buttonMode = false;
event.target.x = matchingTarget.x;
event.target.y = matchingTarget.y;
}
else
{
event.target.x = objectoriginalX;
event.target.y = objectoriginalY;
}
}
thanks before, any suggestion will be appreciated
edited: this is the code i use to move to other scene
HOME1.addEventListener(MouseEvent.CLICK, fl_ClickToGoToScene_15);
function fl_ClickToGoToScene_15(event:MouseEvent):void
{
MovieClip(this.root).gotoAndStop(2, "Scene 1");
}
When through code you do something to a timeline object that causes the parentage to change, that timeline object will no longer be controlled by the timeline.
So when you do this:
event.target.parent.addChild(event.target);
(presumably to bring the item being dragged to the front), you are inadvertently telling Flash that this object is controlled by code now.
The solution, is to manually remove the object(s) by code when done with them. This can be done with removeChild(childObject).
Since you are likely dealing with multiple objects that can be dragged around, it would likely be easiest to just clear all children manually prior to going to the next frame:
removeChildren(); //remove all children of the current context (timeline)
nextFrame(); //go to the next frame, or play(); or whatever you want to do
If you are targeting an older version of flash (less than 11 doesn't support the removeChildren method), you can do this in it's place:
var i:int = numChildren;
while(i--){
removeChildAt(i);
}
Alternatively, if you don't desire to clear all children of the current timeline, you could just keep track of what's being dragged around and remove those object:
var draggedObjs:Array = [];
function pickupObject(event:MouseEvent):void
{
draggedObjs.push(event.target);
...rest of code
Then do this when ready to move on:
for each(obj in draggedObjs){
removeChild(obj);
}
draggedObjs = [];
nextFrame(); //or whatever
Another option, would be to duplicate the item clicked, add it to stage, then drag the duplicate and match the originals position to it on mouse move. When the drag is done, remove the duplicate from stage.

AS3 shuffling movieclips

I've added the basic targets and applying drag and drop for my puzzle pieces, now Im having trouble making the shuffling aspect. As in, after the player completes or opens up the fla, each time will start the puzzle pieces in random places of the stage. I understand using arrays for shuffling somehow but Im not sure exactly how to achieve this. I've stored the instance of my 19 puzzle pieces inside the array but now I have no idea what to do with this array. Other tutorials were abit out of my league and leaves my head scratching.
Just started doing coding for flash professional so yeah, any help with the shuffling movie clips ie the puzzles pieces would be greatly appreciated.
Heres's my code, Im not posting the whole thing since from P1 to P19 is basically copy pasting:
import flash.events.Event;
stage.addEventListener(Event.ENTER_FRAME, EntFrame)
function EntFrame(e: Event) : void
{
P1.addEventListener(MouseEvent.MOUSE_DOWN, fl_ClickToDrag);
function fl_ClickToDrag(event:MouseEvent):void
{
P1.startDrag();
}
stage.addEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop);
function fl_ReleaseToDrop(event:MouseEvent):void
{
P1.stopDrag();
}
if (T1.hitTestObject(P1.Tar1))
{
P1.x = 313.15;
P1.y = 242.75;
}
P19.addEventListener(MouseEvent.MOUSE_DOWN, fl_ClickToDrag_19);
function fl_ClickToDrag_19(event:MouseEvent):void
{
P19.startDrag();
}
stage.addEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop_19);
function fl_ReleaseToDrop_19(event:MouseEvent):void
{
P19.stopDrag();
}
if (T19.hitTestObject(P19.Tar19))
{
P19.x = 624.35;
P19.y = 455.60;
}
}
Here is what I hope is more holistic answer.
First, ditch those inline functions. Right now you make an ENTER_FRAME listener and inside that function you have inline function defined. This means every frame tick (which is tied to your frame rate, not the main timeline), those functions are going to get created again, and since you are adding them as handlers for listeners, they will stay in memory forever.
Here is a way you code this, showing ways to reduce redundancy and get rid of those memory leaks. This assumes the following:
You have 19 objects on the stage called T1 - T19, that represent the possible locations the pieces can go.
You have 19 pieces on the stage called P1 - P19, that, and the numbers correlate to the T locations as per the correct location of the piece.
//let's create a function to randomize the piece location
function seedPieces() {
//create an array consisting of the integers 1 - 19
var unusedSpaces:Vector.<int> = new Vector.<int>;
var i:int;
for (i = 1; i <= 19; i++) {
//populate that array
unusedSpaces.push(i);
}
var curLocation:DisplayObject; //helper var for the loop below
var curPiece:Sprite; //helper var for the loop below
//loop 19 times (from 1 - 19) - one iteration for each piece
for (i = 1; i <= 19; i++) {
curPiece = this["P" + i] as Sprite; //you can get the piece this way, or use an array if you've made one, like `pieces[i];`
trace(curPiece.name);
//splice removes and returns the item at the specified index (in this case a random number between 0 and arrays length less 1) - the second parameter is amount of items to remove (just 1 for this case)
curLocation = this["T" + unusedSpaces.splice(int(Math.random() * unusedSpaces.length), 1)] as DisplayObject;
trace(" ",curLocation.name);
//move the piece to the random location:
curPiece.x = curLocation.x;
curPiece.y = curLocation.y;
}
}
//NOW, as an aside, you should use a loop to add all your listeners for the sake of sanity - if you have them in an array, loop through that, or use the sloppy way like this:
for (var i:int = 1; i <= 19; i++) {
Sprite(this["P" + i]).addEventListener(MouseEvent.MOUSE_DOWN, fl_ClickToDrag);
}
//create a var to hold any piece that is currently being dragged, so you know which piece to stop drag on later
var currentDraggingItem:Sprite;
seedPieces();
function fl_ClickToDrag(event:MouseEvent):void
{
//assign this clicked item to the currentDraggingItem var
currentDraggingItem = event.currentTarget as Sprite;
//bring this one to the front
currentDraggingItem.parent.addChild(currentDraggingItem);
//you can use this one click handler for all pieces
//the piece that was actually clicked, is referenced by event.currentTarget
currentDraggingItem.startDrag();
//add the mouse up listener now that the mouse is currently DOWN
stage.addEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop);
//listen every frame while dragging
stage.addEventListener(Event.ENTER_FRAME, EntFrame);
}
function fl_ReleaseToDrop(event:MouseEvent):void
{
//if currentDraggingItem has a value, stop drag it
if (currentDraggingItem) {
currentDraggingItem.stopDrag();
//send to the back
currentDraggingItem.parent.addChildAt(currentDraggingItem,0);
}
//remove the mouse up and enter frame listener now that the mouse is UP
stage.removeEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop);
stage.removeEventListener(Event.ENTER_FRAME, EntFrame);
if(checkComplete()){
//game over, do something
}
}
function EntFrame(e: Event) : void
{
//this will snap the peice to the correct spot when the mouse is touching the correct spot
if(currentDraggingItem){
if (this[currentDraggingItem.name.replace("P","T")].hitTestPoint(mouseX,mouseY))
{
currentDraggingItem.x = this[currentDraggingItem.name.replace("P","T")].x;
currentDraggingItem.y = this[currentDraggingItem.name.replace("P","T")].y;
}
}
}
function checkComplete():Boolean {
//use a loop to go through all your pieces and check if they are in the right spot. Again, you could have them in an array, or do it the lazy way
for (var i:int = 1; i <= 19; i++) {
if (!this["T"+i].hitTestObject(this["P"+i]))
{
return false;
}
}
return true;
}
Well, in general you can shuffle with the following code:
var shuffledVector:Vector.<someClass> = new Vector.<someClass>;
while (originalVector.length > 0) {
shuffledVector.push(originalVector.splice(Math.random() * originalVector.length, 1)[0]);
}
Longer, explained version:
var shuffledVector:Vector.<someClass> = new Vector.<someClass>; //We will store our shuffled vector in here
var randomIndex:int; //Random index from the originalVector
var resultVector:Vector.<someClass>; //result from the originalVector.splice(...) function
var randomElement:someClass; //Random element from the originalVector
while (originalVector.length > 0) { //We will reduce the size of the originalVector until the originalVector is empty.
randomIndex = Math.random() * originalVector.length; //Calculate a random index within the range of the originalVector from 0 to originalVector.lenght-1 (note that the range decreases by one on every loop)
randomVector = originalVector.splice(randomIndex, 1); //Use splice to remove one element at the randomly choosen index, we will receive a vector with the removed element...
randomElement = randomVector[0]; //...so we need to access the element
shuffledVector.push(randomElement); //Add the randomly choosen element to our shuffled vector
}
I've written the code for a vector as i suggest to use a vector instead of an array, but the principle behind it is the same for an array.
In your case the originalVector is a vector filled with your P1-P19 Movieclips and someClass would be MovieClip. The originalVector is empty at the end and could be replaced with the shuffled one and of course it would make a lot more sense if you put the code in a seperate function like this:
function Shuffle(originalVector:Vector.<someClass>) : void {
var shuffledVector:Vector.<someClass> = new Vector.<someClass>;
while (originalVector.length > 0) {
shuffledVector.push(originalVector.splice(Math.random() * originalVector.length, 1)[0]);
}
originalVector = shuffledVector;
}
Offtopic, but important for further coding: Someone else already mentioned, that it is not good to add EventListeners on every frame, because it is absolutely unnecessary. You only need to add the Listeners once. Your code is very repetitive, you should use a function which accepts a MovieClip, x and y then call that function 19 times.
e.g.:
function setUpMovieClip(MC:MovieClip, x:int, y:int) : {
MC.addEventListener(MouseEvent.MOUSE_DOWN, clickToDrag);
//more code...
}
within the clickToDrag function you can access the MovieClip which was clicked via the event.target property:
function clickToDrag(e:MouseEvent) : {
e.target.startDrag();
//more code...
}
I hope you get the idea.

AS3 - Drag using If statement to Next Scene.

I am making an interactive game - and I have this code so far. Where drop1 is a coin and the user drops it into target1 (box) and once they have done they they are able to watch the video play in the next scene. AS you can see when drop1 (coin) is dropped onto the box the coin then disappears
//Array to hold the target instances, the drop instances,
//and the start positions of the drop instances.
var hitArray:Array = new Array(hitTarget1);
var dropArray:Array = new Array(drop1);
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);
}
//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;
drop1.visible = false;
}else{
target.x = positionsArray[dropIndex].xPos;
target.y = positionsArray[dropIndex].yPos;
}
}
NOW... I want the code to know when the user has dropped the coin in the box and IF the user has they can then watch the video but can only watch the video if they drop the coin in box. How can i code this?
please help.
thank you
If you're still struggling you can always try reading the MANUAL..? I suspect this is why you've had no answer so far. Travelling between frames/scenes requires either gotoAndPlay or gotoAndStop. Check: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/MovieClip.html#gotoAndPlay()
Look at example two for scene jumping code. Where it says "intro" (frame label) it's okay to just use a number but scenes must have names.. e.g:
mc1.gotoAndPlay("intro", "Scene 12");
or in your case something like below (assuming you have named it as scene_video)
if (target.hitTestObject(hitArray[dropIndex])) {
target.x = hitArray[dropIndex].x;
target.y = hitArray[dropIndex].y;
drop1.visible = false;
gotoAndStop(1, "scene_video"); }
Again I'm assuming your video player is on frame 1 of that scene so stopping there allows users a chance to watch the video player.

Flash AS3 - Drag and Drop multiple objects to one target?

Title is more or less self-explanatory, I’ve been working through many different tutorials and I’m not exactly too good with AS3 to be perfectly honest. (Image above shows what I'm aiming for)
Anyway, what I notice in most of the online tutorials I see, the drag and drop tutorials are either based on one object to one target or multiple objects to multiple targets, so I was wondering if someone is kind enough to help me and explaining how I can get multiple objects to connect to one target.
And, if possible making it switchable, as in for example, if object 1 is already in place on the target when I drag object 2 over, then object 1 returns to its original position and object two takes its place.
A easier way to explain this is to say that I'm trying to create a game where there are three statues and the user can pick one of the three to place in a set target zone.
I apologies if what I say doesn't make much sense, will clear up anything if that causes confusion. Here's the AS3 code I'm using at the moment.
var startX:int;
var startY:int;
circle1_mc.addEventListener(MouseEvent.MOUSE_DOWN, pickUp);
circle1_mc.addEventListener(MouseEvent.MOUSE_UP, dropIt);
circle2_mc.addEventListener(MouseEvent.MOUSE_DOWN, pickUp);
circle2_mc.addEventListener(MouseEvent.MOUSE_UP, dropIt);
circle3_mc.addEventListener(MouseEvent.MOUSE_DOWN, pickUp);
circle3_mc.addEventListener(MouseEvent.MOUSE_UP, dropIt);
function pickUp(event:MouseEvent):void {
startX = event.target.x;
startY = event.target.y;
event.target.startDrag(true);
event.target.parent.addChild(event.target);
}
function dropIt(event:MouseEvent):void {
event.target.stopDrag();
var theTargetName:String = "target" + event.target.name;
var theTarget:DisplayObject = getChildByName(theTargetName);
if (event.target.dropTarget != null && event.target.dropTarget.parent == theTarget){
event.target.buttonMode = false;
event.target.x = theTarget.x;
event.target.y = theTarget.y;
}
else{
event.target.x = startX;
event.target.y = startY;
circle1_mc.buttonMode = true;
circle2_mc.buttonMode = true;
circle3_mc.buttonMode = true;
Instead of checking the dropTarget, you can use hitTestObject to see if the dropped object is "touching" theTarget. Otherwise, any other item that has already been dropped onto theTarget may be reported as the dropTarget.
Also, since MovieClip is dynamic, you can store the startX and startY values in each instance.
The following modified code will use a single target_mc as a drop target. When one item is dropped on it, any other items will be moved back to their original spot:
// create an array as #David suggested to keep track of your draggable items
var circles:Array = [circle1_mc, circle2_mc, circle3_mc];
for each(var circleMC:MovieClip in circles)
{
circleMC.addEventListener(MouseEvent.MOUSE_DOWN, pickUp);
circleMC.addEventListener(MouseEvent.MOUSE_UP, dropIt);
circleMC.startX = circleMC.x;
circleMC.startY = circleMC.y;
}
function pickUp(event:MouseEvent):void
{
// no longer need to keep track of startX & startY here because that's already been done up above
event.target.startDrag(true);
event.target.parent.addChild(event.target);
}
function dropIt(event:MouseEvent):void
{
event.target.stopDrag();
// check to see if the event target is touching target_mc using hitTestObject
if(event.target.hitTestObject(target_mc)){
event.target.buttonMode = false;
event.target.x = target_mc.x;
event.target.y = target_mc.y;
// move all circles OTHER than the current target back to their original positions
for each(var circleMC:MovieClip in circles)
{
if(event.target != circleMC)
{
circleMC.x = circleMC.startX;
circleMC.y = circleMC.startY;
}
}
}
else
{
// only need to move the event target back if it was dropped outside of target_mc
event.target.x = event.target.startX;
event.target.y = event.target.startY;
event.target.buttonMode = true;
}
}