How to drag and drop in Flash
Author: Bill Trikojus
| |
 |
Document setup
|
| |
| |
OK here is a drag and drop tutorial for Flash MX. The finished movie should look like this -
Start by opening Flash. Make a new file and set the Frame rate to 21.
Draw a circle.
Select the circle and hit F8 to convert it to a Movie Clip (MC) - name it circle_mc.
Also give the circle_mc on the stage an instance name of circle_mc.
Make a new Layer and name it "actions"
On frame 1 of the actions layer put this -
circle_mc.onPress=function(){
startDrag(this);
}
circle_mc.onRelease=circle_mc.onReleaseOutside=function(){
stopDrag();
}
OK now save your movie as dragndrop.fla and go Control/Test Movie.
You should be able to drag your cicle around - if you can't then you've done something wrong.
|
| |
 |
Actions
|
| |
| |
OK underneath the action actions you already have on frame 1 add this - //the variables below will store the clips starting position
circle_mc.myHomeX=circle_mc._x;
circle_mc.myHomeY=circle_mc._y;
circle_mc.onMouseDown=function(){
//this variable tells us if the mouse is up or down
mousePressed=true;
}
circle_mc.onMouseUp=function(){
mousePressed=false;
}
circle_mc.onEnterFrame=function(){
//all these actions basically just say "if the mouse is up (in other words - the clip is not being dragged)
// then move the MC back to its original starting point (with a smooth motion)
if(mousePressed==false){
this._x-=(this._x-this.myHomeX)/5;
this._y-=(this._y-this.myHomeY)/5;
}
}
Paste this into flash and then have a read of the code comments.
OK test your movie again and you will see that you can drag your circle around but when you let go of the mouse the circle moves back to its starting position with a smooth motion.
|
| |
 |
Create a target
|
| |
| |
OK now we want to check where the circle is bring dropped. Start by creating a new layer and dragging the new layer below the layer that has the circle_mc on it. Now draw a big circle down the bottom right hand corner of the stage. Select the circle you have just drawn and convert it to a movie clip - name it target circle and give it an instance name of targetCircle. Double click on the target MC to go inside it. Put a stop action on both first and second frames. Create a new keyframe for the circle in frame 2 (hit F6) and give it a different fill colour.
Now go back to the main timeline and change the onRelease actions to this -
circle_mc.onRelease=circle_mc.onReleaseOutside=function(){
stopDrag();
if (this._droptarget == "/targetCircle") {
this.onTarget=true;
_root.targetCircle.gotoAndStop(2);
}else{
this.onTarget=false;
_root.targetCircle.gotoAndStop(1)
}
}
and the if statement in the enterFrame actions to this
if(mousePressed==false&&this.onTarget==false){
Still with me? Ok test the movie again and watch what happens when you drag the circle around - both on and off the target.
|
| |
 |
Positioning within a target
|
| |
| |
OK what else?? hmm maybe when we drag the circle on to any part of the target, we want the circle to move to the center of the target. Ok let's do that.
Change all the actions on frame 1 to this -
circle_mc.onPress = function() {
startDrag(this);
};
circle_mc.onRelease = circle_mc.onReleaseOutside=function () {
stopDrag();
if (this._droptarget == "/targetCircle") {
this.onTarget = true;
_root.targetCircle.gotoAndStop(2);
} else {
this.onTarget = false;
_root.targetCircle.gotoAndStop(1);
}
};
//the variables below will store the clips starting position
circle_mc.myHomeX=circle_mc._x;
circle_mc.myHomeY=circle_mc._y;
//the variables below will store the clips end position
circle_mc.myFinalX = targetCircle._x;
circle_mc.myFinalY = targetCircle._y;
circle_mc.onMouseDown = function() {
//this variable tells us if the mouse is up or down
mousePressed = true;
};
circle_mc.onMouseUp = function() {
mousePressed = false;
};
circle_mc.onEnterFrame = function() {
//all these actions basically just say "if the mouse is up (in other words - the clip is not being dragged)
// then move the MC back to its original starting point (with a smooth motion)"
if (mousePressed == false && this.onTarget == false) {
this._x -= (this._x-this.myHomeX)/5;
this._y -= (this._y-this.myHomeY)/5;
//if the circle is dropped on any part of the target it slides to the center of the target
} else if (mousePressed == false && this.onTarget == true) {
this._x -= (this._x-this.myFinalX)/5;
this._y -= (this._y-this.myFinalY)/5;
}
};
Test the movie again and watch what happens (or look away and cross your fingers - it's up to you...).
|
| |
 |
Drag multiple objects
|
| |
| |
Now the code above if fine if you just want to drag and drop one object, but things can get pretty messy if want to be able to drag multiple around. So, rather than just duplicate the code we already have for each mc, lets make a function that will give an mc the drag and drop functionality you have already seen. Copy the function below and replace all the code on frame 1 of your movie:
function dragSetup(clip, targ) {
clip.onPress = function() {
startDrag(this);
this.beingDragged=true;
};
clip.onRelease = clip.onReleaseOutside=function () {
stopDrag();
this.beingDragged=false;
if (eval(this._droptarget) == targ) {
this.onTarget = true;
_root.targ.gotoAndStop(2);
} else {
this.onTarget = false;
_root.targ.gotoAndStop(1);
}
};
//the variables below will store the clips starting position
clip.myHomeX = clip._x;
clip.myHomeY = clip._y;
//the variables below will store the clips end position
clip.myFinalX = targ._x;
clip.myFinalY = targ._y;
clip.onEnterFrame = function() {
//all these actions basically just say "if the mouse is up (in other words - the clip is not being dragged)
// then move the MC back to its original starting point (with a smooth motion)"
if (!this.beingDragged && !this.onTarget) {
this._x -= (this._x-this.myHomeX)/5;
this._y -= (this._y-this.myHomeY)/5;
//if the circle is dropped on any part of the target it slides to the center of the target
} else if (!this.beingDragged && this.onTarget) {
this._x -= (this._x-this.myFinalX)/5;
this._y -= (this._y-this.myFinalY)/5;
}
};
}
So now we have a function that we can call to setup as many dragable objects as we want. When you call the function you must provide 2 parameters - the clip that you want to be dragable and the target for that clip. Add this to the bottom of your code
dragSetup(circle_mc,targetCircle);
Using this function will keep your code much cleaner when dragging multiple objects. Option drag out a copy of targetCircle and circle_mc and change the copies instance names to targetCircle2 and circle2_mc. Now to give circle2_mc the same functionality as circle_mc, all you have to do is add this line of code
dragSetup(circle2_mc,targetCircle2);
Much cleaner than duplicating all that code!!
You can download the finished source files for this tutorial here.
You can also download the finished source file in Actionscript 3 here
To learn more about dragging and dropping in Actionscript 1.0 check out 'ActionScript for Flash MX: The Definitive Guide ' by Colin Moock.
|
Back
Share
Like this? Click a link below to share it...




Subscribe and Download
Comments
2008-04-12: Dustin Lafleur said:I am attempting to use this code in a multiple drag and drop situation. I would like to use the following section of this code but it does not seem to work when dealing with multiple objects.
if (eval(this._droptarget) == targ) {
this.onTarget = true;
_root.targ.gotoAndStop(2);
} else {
this.onTarget = false;
_root.targ.gotoAndStop(1);
}
2008-04-13: Bill Trikojus said:in the dragSetuo function try adding an extra line where the position variables are set
clip.targ=targ;
then in the if statement you posted above try
if (eval(this._droptarget) == this.targ) {
2008-04-24: Albert said:Hello, your tutorial is realy-realy great! Also your explanation of multiple drag and drop situation. But I have problem what I can't figure out. In my application what I trying to write you can drag and drop letters to 14 targets. But the letters must snap on the targets, not a big problem you will think. ;-) But you can drop each letter of one of the 14 targets. So you can drop the letter "E" on the first target but also on the second, third, and so on targets.
Still with me? ;-)
Do you know a sollution to my problem?
2008-04-24: Bill Trikojus said:You can snap a dragged object to the clip it is dropped on by checking the _droptarget
eg
someClip.onRelease=function(){
stopDrag();
theClipIWasDroppedOn=eval(this._droptarget);
this._x= theClipIWasDroppedOn._x;
this._y= theClipIWasDroppedOn._y;
}
Hope that helps
2008-04-25: Albert said:Wow that's great and just what I was looking for! Is there also a way to achive some smoothness, like the way you show in your example?
I have come up with this solution but that wouldn't work. :-P
letter_a.onRelease=function(){
stopDrag();
theClipIWasDroppedOn=eval(this._droptarget);
this._x= (theClipIWasDroppedOn._x)/5;
this._y= (theClipIWasDroppedOn._y)/5;
}
2008-04-25: Bill Trikojus said:on the right track but you need to start an enterframe script to make it ease to the target
eg
letter_a.onRelease=function(){
stopDrag();
theClipIWasDroppedOn=eval(this._droptarget);
this.onEnterFrame=function(){
this._x-= (this._x-theClipIWasDroppedOn._x)/5;
this._y-= (this._y-theClipIWasDroppedOn._y)/5;
}
}
If you are using Flash 8 or 9 check out the Tweener class - makes easing easier
cheers
2008-05-08: Dustin Lafleur said:Thanks Bill,
Your help was very useful.
I do have another question though. Is it possible to re purpose this code so that a single movie clip can have dual targets.
2008-05-08: Bill Trikojus said:Sure. Just add another parameter to the function
function dragSetup(clip, targ1,targ2) {
then check both targets when you drop the clip
if (eval(this._droptarget) == targ1 || eval(this._droptarget) == targ2) {
|| means OR
cheers
2008-05-20: curtis redden said:This is really good, but how do i make it so that when the correct target is chosen it can play a movie clip once object is dropped?
Like when the user drops the object onto the wrong target it will explode or something like that. how do i do this
2008-05-20: Bill Trikojus said:Well in the onRelease you have
if (eval(this._droptarget) == targ) {
this.onTarget = true;
_root.targ.gotoAndStop(2);
} else {
this.onTarget = false;
_root.targ.gotoAndStop(1);
}
just add another gotoAndPlay in there. Assuming that the movieclip you want to play is the one being dragged, and assuming that you have a couple of frame labels set up inside that movieclip, it would be something like
if (eval(this._droptarget) == targ) {
this.onTarget = true;
_root.targ.gotoAndStop(2);
this.gotoAndPlay('correct');
} else {
this.onTarget = false;
_root.targ.gotoAndStop(1);
this.gotoAndPlay('incorrect');
}
cheers
2008-05-21: Dave said:Hi,
I use this AS in a clip and it wasn't dropped on my target. I put this lines:
clip.targ=targ;
if (eval(this._droptarget) == this.targ)
It targets but now the circle doesn't move back. This is my code:
clip.targ=target;
case_gratuit_mc.onPress = function() {
startDrag(this);
case_gratuit_mc.gotoAndPlay(2);
};
case_gratuit_mc.onRelease = case_gratuit_mc.onReleaseOutside=function () {
stopDrag();
case_gratuit_mc.gotoAndPlay(1);
if (this._droptarget == this.targ) {
this.targ = true;
case_gratuit_mc.gotoAndPlay(3);
//targetCircle.gotoAndStop(2);
} else {
this.targ = false;
//targetCircle.gotoAndStop(1);
}
};
//the variables below will store the clips starting position
case_gratuit_mc.myHomeX=case_gratuit_mc._x;
case_gratuit_mc.myHomeY=case_gratuit_mc._y;
//the variables below will store the clips end position
//circle_mc.myFinalX = 443;
//circle_mc.myFinalY = 294;
case_gratuit_mc.onMouseDown = function() {
//this variable tells us if the mouse is up or down
mousePressed = true;
};
case_gratuit_mc.onMouseUp = function() {
mousePressed = false;
};
case_gratuit_mc.onEnterFrame = function() {
//all these actions basically just say "if the mouse is up (in other words - the clip is not being dragged)
// then move the MC back to its original starting point (with a smooth motion)"
if (mousePressed == false && this.onTarget == false) {
this._x -= (this._x-this.myHomeX)/5;
this._y -= (this._y-this.myHomeY)/5;
//if the circle is dropped on any part of the target it slides to the center of the target
} else if (mousePressed == false && this.onTarget == true) {
this._x -= (this._x-this.myFinalX)/5;
this._y -= (this._y-this.myFinalY)/5;
}
};
Thx for some help.
2008-05-21: Bill Trikojus said:not sure what you are trying to do that is different to the tutorial but there is definately issues with your targ variable - at one point it is a movieclip and another it is a boolean (true or false);
trace targ in your on release
case_gratuit_mc.onRelease = case_gratuit_mc.onReleaseOutside=function () {
stopDrag();
trace(this.targ)
trace(this._droptarget);
case_gratuit_mc.gotoAndPlay(1);
//here the targ var is a movieclip
if (this._droptarget == this.targ) {
//and here it is a boolean - so which is it? Should this be onTarget?
this.targ = true;
case_gratuit_mc.gotoAndPlay(3);
//targetCircle.gotoAndStop(2);
} else {
this.targ = false;
//targetCircle.gotoAndStop(1);
}
};
If you can't get it working please post it on
actionscript.org .
2008-05-24: Monte said:This is a GREAT tutorial. Exactly what I was looking for. My question is about integrating a Tween class into this code.
I usually use TweenLite, but I was going to test with the included Macromedia Tween class and got a syntax error just trying to import it into the code.
I want to use the Tween class to send the clip back to starting position with an Elastic or Back ease, and the successfully dragged clip will Alpha to zero and move off screen (say, _x:1000).
How would this work and what code to replace?
Thanks again!
2008-05-24: Bill Trikojus said:well I'm I'm not sure why you are getting that syntax error but you should check out the new
easing tutorial I just made.
The code to integrate the Tween class would look like this
import mx.transitions.Tween;
import mx.transitions.easing.*;
function dragSetup(clip, targ) {
clip.onPress = function() {
startDrag(this);
};
clip.onRelease = clip.onReleaseOutside=function () {
stopDrag();
if (eval(this._droptarget) == targ) {
var tx:Tween=new Tween(this,'_x',Elastic.easeOut,this._x,this.myFinalX,1,true);
var ty:Tween=new Tween(this,'_y',Elastic.easeOut,this._y,this.myFinalY,1,true);
targ.gotoAndStop(2);
} else {
var tx:Tween=new Tween(this,'_x',Elastic.easeOut,this._x,this.myHomeX,1,true);
var ty:Tween=new Tween(this,'_y',Elastic.easeOut,this._y,this.myHomeY,1,true);
targ.gotoAndStop(1);
}
};
//the variables below will store the clips starting position
clip.myHomeX = clip._x;
clip.myHomeY = clip._y;
//the variables below will store the clips end position
clip.myFinalX = targ._x;
clip.myFinalY = targ._y;
}
dragSetup(circle_mc,target_mc)
Also see attached
drag and drop with tween class example.
cheers
2008-05-29: Laura Sullivan said:Thanks Bill, Thats been really helpful.
My problem is kind of complicated, i have applied the tutorial to parts of my animation and it has worked a treat! thanks!
my problem comes in two parts
the target needs to be the result of a movie clip, which is activated on press of the item to be dragged.
so i've got the item moving, i just cant work out how to get it to activate the movie clip and target
the other part is the same, except that the item to be dragged is revealed at the end of another movie clip being played.
i have the item appearing fine, and it shows an active link when rolled over but i cant get the code to apply to it..
is such a request feasible or should i just simplify the scene?
2008-05-29: Bill Trikojus said:Hi Laura
I'm not sure I understand the issue here but to activate the 'drag-ability' of one movieclip when another is clicked and drag you could do something like this
movieclip1_mc.onPress=function(){
this.startDrag();
dragSetup(movieclip2_mc,target_mc)
}
Does that make sense? You just delay calling the dragSetup function until the first movieclip is clicked
cheers
2008-06-06: Gerald Kaute said:Hi. I can't see my post here so I´ll repeat it.
I copied the code into the root and most stuff works BUT the target bit doesn't - ie: Doesn't stop dragging.
//onClipEvent (enterFrame) {
stop();
dragSetup(_root.hamburger2,_root.box1);
dragSetup(_root.hamburger1,_root.box1);
function dragSetup(clip, targ) {
clip.onPress = function() {
startDrag(this);
this.beingDragged=true;
};
clip.onRelease = clip.onReleaseOutside=function () {
stopDrag();
this.beingDragged=false;
if (eval(this._droptarget) == targ) {
this.onTarget = true;
gotoAndPlay(2);
} else {
this.onTarget = false;
trace(failure);
}
};
//the variables below will store the clips starting position
clip.myHomeX = clip._x;
clip.myHomeY = clip._y;
//the variables below will store the clips end position
clip.myFinalX = targ._x;
clip.myFinalY = targ._y;
clip.onEnterFrame = function() {
//all these actions basically just say "if the mouse is up (in other words - the clip is not being dragged)
// then move the MC back to its original starting point (with a smooth motion)"
if (!this.beingDragged && !this.onTarget) {
this._x -= (this._x-this.myHomeX)/5;
this._y -= (this._y-this.myHomeY)/5;
//if the circle is dropped on any part of the target it slides to the center of the target
} else if (!this.beingDragged && this.onTarget) {
this._x -= (this._x-this.myFinalX)/5;
this._y -= (this._y-this.myFinalY)/5;
}
};
}
2008-06-06: Bill Trikojus said:Code looks fine. You may have a depth issue that is preventing the onRelease from firing when you have dragged over the target
2008-06-11: Chris said:hey, this is really nice, but what I need to do is the following:
I have a true false quiz with five questions. Next to each question is a box. Off to the side are two draggable boxes, one labeled true, the other false. How do I use multiple instances of the same boxes so that the user can drag the corrosponding answer to the correct box next to each question??? I'm also looking for some kind of feed back that gives the user two attempts at the question.
Thanks in advance for your help.
2008-06-11: Bill Trikojus said:The dragSetup function is designed to exactly what you are describing in the first part of your question - that is assign drag and drop to multiple instances (can be instances of the same movieclip) and assign them different targets. So you should just be able to say
dragSetup(true1_mc,target1_mc);
dragSetup(false1_mc,target1_mc);
dragSetup(true2_mc,target2_mc);
dragSetup(false2_mc,target2_mc);
//etc
regarding the 2 chances (which seems a little strange given that this is a true or false quiz but anyway) you could create a counter in each target that tracks how many attempts have been made. I would need to see all your quiz code but it would be something like
function dragSetup(clip, targ) {
//start counter
targ.numAttempts=0;
clip.onPress = function() {
startDrag(this);
this.beingDragged=true;
};
clip.onRelease = clip.onReleaseOutside=function () {
stopDrag();
this.beingDragged=false;
if (eval(this._droptarget) == targ) {
//you need your own code here to determine if answer was correct or not
if(answerCorrect && targ.numAttempts<2){
this.onTarget = true;
_root.targ.gotoAndStop(2);
}else{
targ.numAttempts++
}
} else {
this.onTarget = false;
_root.targ.gotoAndStop(1);
}
};
//the variables below will store the clips starting position
clip.myHomeX = clip._x;
clip.myHomeY = clip._y;
//the variables below will store the clips end position
clip.myFinalX = targ._x;
clip.myFinalY = targ._y;
clip.onEnterFrame = function() {
//all these actions basically just say "if the mouse is up (in other words - the clip is not being dragged)
// then move the MC back to its original starting point (with a smooth motion)"
if (!this.beingDragged && !this.onTarget) {
this._x -= (this._x-this.myHomeX)/5;
this._y -= (this._y-this.myHomeY)/5;
//if the circle is dropped on any part of the target it slides to the center of the target
} else if (!this.beingDragged && this.onTarget) {
this._x -= (this._x-this.myFinalX)/5;
this._y -= (this._y-this.myFinalY)/5;
}
};
}
cheers
2008-06-24: Gerald Kaute said:All works well on its own but NOT when loaded into another movieclip.
trace(eval(this._droptarget)); is undefined when I load this into an emptymovieclip called container_mc2
stop();
fscommand ("fullscreen", "true");
fscommand ("showmenu", "false");
fscommand ("allowscale", "TRUE");
this._lockroot = true;
_root.createEmptyMovieClip("Background_mc", _root.getNextHighestDepth());
_root.soundBG = new Sound(Background_mc);
_root.soundBG.loadSound("BGmusic.mp3" , true);
_root.soundBG.start(0, 999999);
_root.soundBG.setVolume(30);
dragSetup(_root.cat_mc,_root.catShadow_mc);
dragSetup(_root.dog_mc,_root.dogShadow_mc);
dragSetup(_root.bird_mc,_root.birdShadow_mc);
dragSetup(_root.cow_mc,_root.cowShadow_mc);
// dragSetup(_root.circle2,_root.box1);
// dragSetup(_root.hamburger1,_root.box2);
function dragSetup(clip, targ) {
clip.onPress = function() {
startDrag(this);
//_root.createEmptyMovieClip("objectSound_mc");
//_root.objectSound = new Sound(objectSound_mc);
//var sound:String = clip;
//var aFile:String = "/sounds/" + sound + ".mp3";
//_root.objectSound.loadSound( aFile, 0 );
//trace(aFile);
//_root.objectSound.loadSound("/sounds/cat_mc.mp3" , true);
//_root.objectSound.start(0, 999999);
//_root.objectSound.setVolume(100);
//_root.createEmptyMovieClip("objectSound_mc",-1)
this.beingDragged=true;
};
clip.onRelease = clip.onReleaseOutside=function () {
stopDrag();
this.beingDragged=false;
trace(eval(this._droptarget));
trace(targ);
if (eval(this._droptarget) == targ) {
this.onTarget = true;
trace("yeah");
}
}
clip.myHomeX = clip._x;
clip.myHomeY = clip._y;
//the variables below will store the clips end position
clip.myFinalX = targ._x;
clip.myFinalY = targ._y;
clip.onEnterFrame = function() {
//all these actions basically just say "if the mouse is up (in other words - the clip is not being dragged)
// then move the MC back to its original starting point (with a smooth motion)"
if (!this.beingDragged && !this.onTarget) {
this._x -= (this._x-this.myHomeX)/5;
this._y -= (this._y-this.myHomeY)/5;
//if the circle is dropped on any part of the target it slides to the center of the target
} else if (!this.beingDragged && this.onTarget) {
this._x -= (this._x-this.myFinalX)/5;
this._y -= (this._y-this.myFinalY)/5;
}
}
}
var mouseListener:Object = new Object();
mouseListener.onMouseMove = function(){
crosshair._x = _xmouse;
crosshair._y = _ymouse;
};
Mouse.hide();
Mouse.addListener(mouseListener);
2008-06-24: geraldkaute said:Yes, I forgot to say that somebody mentioned lockroot - but that doesn't solve the prob although its supposed to. Also something about _parent.
I can't make it work.
2008-06-24: Bill Trikojus said:Yes lockroot should fix it. What version of flash are you publishing as? In any case, it is better to fix the actual problem which is the absolute paths - these need to be made relative (straight to the object you are targeting).
eg
//absolute path
dragSetup(_root.cat_mc,_root.catShadow_mc);
//relative path
dragSetup(cat_mc,catShadow_mc);
//relative path
dragSetup(_parent.cat_mc, _parent.catShadow_mc);
not sure which relative path is correct (if either) but the point is you need to provide the path directly from the location of the code to the object you wish to target
hope that helps
cheers
2008-07-01: Silverkrown said:Thanks for the code. How would I change it so there is no color change just the drop target. I want them to be able to drag the image and if it isn't in the correct area snap back but if it is in the correct drop area just stay there? Sorry if this doesn't make sense but I am new to flash. Also it has to be relative, I can't call the root.
2008-07-01: Bill Trikojus said:to remove the colour change jusr get rid of
_root.targ.gotoAndStop(2);
to make that relative just get rid of _root
Lots of tutes available on paths - couple of good ones on actionscrpt.org
cheers
2008-08-05: loop said:I want a button with onRelease and if clip = dropped on targ1 , punten_txt++ How do I do that?
2008-08-20: Oliver Allen said:Hi. Really awesome tutorial!
I have been trying to acheive the same as Dustin Lafleur in regards to multiple targets. I would like to be able to drag an object across the stage and have it move to the centre of whatever target it is currently over (like in the tutorial) but with multiple target areas. (I hope you understand what I mean).
I tried using: doing what you mentioned:
"Sure. Just add another parameter to the function
function dragSetup(clip, targ1,targ2) {
then check both targets when you drop the clip
if (eval(this._droptarget) == targ1 || eval(this._droptarget) == targ2) {"
..but unfortunately it doesn't seem to work at all.
Can you suggest what I may be doing wrong.
Much thanks and appreciation.
Ollie
2008-08-20: Bill Trikojus said:I have uploaded a
drag and drop with multiple targets example - I hope it helps
cheers
2008-08-20: Oliver Allen said:Thanks Bill, that's great.
Unfortunately I am now having yet another problem: The objects I am dragging are large. I would rather that; if the objects position is within the target when the mouse is released (instead of the mouse release being within the target) then this is when the object will align to the target.
I hope you understand what I mean.
To explain myself further; the targets in my flash file are off the stage therefore a mouse release canot be detected. This is why I need the object's position (on mouse release) to determine which target it is in and will align to.
Many thanks.
Ollie
2008-08-20: Bill Trikojus said:I'm afraid I don't understand. _droptarget does return the object that the dropped object is touching - it doesn't have anything to do with where the mouse is released. If your targets are all off the stage, I don't see how you can see "if the objects position is within the target when the mouse is released ...then this is when the object will align to the target.". It sounds like you might need to use hitTest() instead of _droptarget
I hope that helps
2008-09-08: Durogista said:hi bill,
im new to flash and im currently using flash 8 pro. and im having a problem regarding the the object to be dragged. i want the object to be locked inside the target and then create a reset button for it. can u show me how to code it?
thanks in advance bill
Durogista
2008-09-08: Bill Trikojus said:Hi Durogista
Topics that are quite different to the tutorial should probably be discussed at a forum like actionscript.org because you can upload example files etc. BAsically you need to set some extra parameters in the call to startDrag() that defines the area that the object can be dragged with
All the best
2008-09-20: kay said:Hi, your tutorials on drag & drop scenarios has been beneficial. However I’m having difficulties trying to reset the dragable objects to there original positions.
Do I need to write a reset function? Can you shed some light on how I do this.
I’ve attached the source code below.
function dragSetup(clip, targ) {
clip.onPress = function() {
startDrag(this);
this.beingDragged=true;
};
clip.onRelease = clip.onReleaseOutside=function () {
stopDrag();
this.beingDragged=false;
if (eval(this._droptarget) == targ) {
this.onTarget = true;
_root.targ.gotoAndStop(2);
} else {
this.onTarget = false;
_root.targ.gotoAndStop(1);
}
};
clip.myHomeX = clip._x;
clip.myHomeY = clip._y;
//the variables below will store the clips end position
clip.myFinalX = targ._x;
clip.myFinalY = targ._y;
clip.onEnterFrame = function() {
if (!this.beingDragged && !this.onTarget) {
this._x -= (this._x-this.myHomeX)/5;
this._y -= (this._y-this.myHomeY)/5;
//if the circle is dropped on any part of the target it slides to the center of the target
} else if (!this.beingDragged && this.onTarget) {
this._x -= (this._x-this.myFinalX)/5;
this._y -= (this._y-this.myFinalY)/5;
}
};
}
dragSetup(circle_mc,targetCircle);
dragSetup(circle2_mc,targetCircle2);
reset1.onRelease = function (){
circle_mc._x = circle_mc.myHomex;
circle_mc._y = circle_mc.myHomey;
}
stop();
Any help I will be greatly appreciated.
2008-09-20: Bill Trikojus said:You have typos on the var names
eg
circle_mc.myHomex
should be
circle_mc.myHomeX
cheers
2008-09-21: kay said:Thanks for the swift response, it now works.
What i like to know is, how easy is it to start a animation within the movie clips once it has been drop onto the target.
2008-09-21: Bill Trikojus said:Kay for some reason your comments are posting multiple times. Please don't refresh the window after posting.
What you want to do is pretty simple. In the dragSetup function, when you have detected that you have dropped on the target, tell the clip taht was just dropped to gotoAndPlay something
eg
if (eval(this._droptarget) == targ) {
this.onTarget = true;
_root.targ.gotoAndStop(2);
this.gotoAndPlay(2);
} else {
this.onTarget = false;
_root.targ.gotoAndStop(1);
}
cheers
2008-09-23: kay said:Sorry about that, thanks for the information it works, another question. What if I want to target a few more draggable Movie clips, to gotoAndPlay frame 2 without effect the other movie clips frames.
2008-09-24: Bill Trikojus said:hi Kay
I would need more info such as whether or not you want to target the same clips whenever an object is dropped. Probably best if you post this on a flash forum such as actionscript.org
Cheers
2008-09-26: ziotoo4 said:Hi Bill!
I have a problem with this script. I see you already gave an answer to my same question, but, since i am a real newbie, i can't get a grip on the solution.
I am trying to make a draggable slider, with 3 stations: Low, medium, and high.
Like this: Low---Med---High.
I have a movie clip that can be moved only on the x axis (horizontally). So far, no problems. But how can i make the slider move to the nearest station when i drop it?
Basically, i managed to understand your code for single target/single MC or N targets/N movie clips...but how can i change it to N targets/1 movie clip? What lines should i change? why?
Please be as clear as you can, cause, as i said before, i'm only 15 Y.O. and therefore i'm a newbie ;-)
Thanks! Fede, from Italy
2008-09-26: Bill Trikojus said:Hi Fede from Italy
Probably easiest to just check out this
drag and drop with snap example.
Hope it helps
cheers
2008-09-26: fede said:Thanks Bill!
This is perfect, but it has an issue: The moving of the green bar is not smooth: it just skips back to the station. I was able to do so; but the problem was the smooth move....
How can i do to add the tween?
Thanks! Fede
2008-09-26: Bill Trikojus said:No problem. Check out the easing with actionscript tutorial - should be quite simple to apply the concepts in that to get the bar easing to the target rather than snapping.
Cheers
2008-09-27: Fede said:Hi Bill; still me. I tried to modify your code because the file you gave me wasn't really what i was looking for.
Now, I have 3 MC: Circle_mc, targetcircle1 and targetcircle2. The code is like this:
circle_mc.onPress = function() {
startDrag(this);
};
circle_mc.onRelease = circle_mc.onReleaseOutside=function () {
stopDrag();
if (this._droptarget == "/targetCircle1") {
this.onTarget = true;
_root.targetCircle1.gotoAndStop(2);
}
else if (this._droptarget == "/targetCircle2") {
this.onTarget2 = true;
_root.targetCircle2.gotoAndStop(2);
} else {
this.onTarget = false;
_root.targetCircle.gotoAndStop(1);
}
};
//the variables below will store the clips starting position
circle_mc.myHomeX = circle_mc._x;
circle_mc.myHomeY = circle_mc._y;
//the variables below will store the clips end position
circle_mc.myFinalX = 450;
circle_mc.myFinalY = 250;
circle_mc.myFinalX2 = 110;
circle_mc.myFinalY2 = 286;
circle_mc.onMouseDown = function() {
//this variable tells us if the mouse is up or down
mousePressed = true;
};
circle_mc.onMouseUp = function() {
mousePressed = false;
};
circle_mc.onEnterFrame = function() {
//all these actions basically just say "if the mouse is up (in other words - the clip is not being dragged)
// then move the MC back to its original starting point (with a smooth motion)"
if (mousePressed == false && this.onTarget == false) {
this._x -= (this._x-this.myHomeX)/5;
this._y -= (this._y-this.myHomeY)/5;
//if the circle is dropped on any part of the target it slides to the center of the target
} else if (mousePressed == false && this.onTarget == true) {
this._x -= (this._x-this.myFinalX)/5;
this._y -= (this._y-this.myFinalY)/5;
}
else if (mousePressed == false && this.onTarget2 == false) {
this._x -= (this._x-this.myHomeX)/5;
this._y -= (this._y-this.myHomeY)/5;
//if the circle is dropped on any part of the target it slides to the center of the target
}
else if (mousePressed == false && this.onTarget2 == true) {
this._x -= (this._x-this.myFinalX2)/5;
this._y -= (this._y-this.myFinalY2)/5;
}
};
Now, i can drop the circle on each target, and if i drag it away it will go back to it's starting position. But if i put in, let's say, on targetcircle1, then i won't be able to drag it on targetcircle2. Why? I assume the error to be in the second part of the code...but...what's the problem? Sorry for being such a bad student---
Thanks in advance,
Fede
2008-09-27: Bill Trikojus said:Hi Fede
this question should probably be posted on a forum as it is difficult to work through more complex issues in this comments area, but I'll have one more guess. I think when you detect that you have dropped on target1, for example, you need to make sure that you set the onTarget2 variable back to false
eg
circle_mc.onRelease = circle_mc.onReleaseOutside=function () {
stopDrag();
if (this._droptarget == "/targetCircle1") {
this.onTarget = true;
this.onTarget2 = false;
_root.targetCircle1.gotoAndStop(2);
}
else if (this._droptarget == "/targetCircle2") {
this.onTarget2 = true;
this.onTarget = false;
_root.targetCircle2.gotoAndStop(2);
} else {
this.onTarget = false;
this.onTarget2 = false;
_root.targetCircle.gotoAndStop(1);
}
};
give that a shot
cheers
2008-09-27: fede said:Thanks bill, you are a genius!
The problem was: Since there was no chance for onTarget2 to be false, the circle would never switch back to his starting pos after being dragged on target1...
The code, if anyone needs it, is:
circle_mc.onPress = function() {
startDrag(this);
};
circle_mc.onRelease = circle_mc.onReleaseOutside=function () {
stopDrag();
if (this._droptarget == "/targetCircle1") {
this.onTarget = true;
_root.targetCircle1.gotoAndStop(2);
} else if (this._droptarget == "/targetCircle2") {
this.onTarget2 = true;
_root.targetCircle2.gotoAndStop(2);
} else {
this.onTarget = false;
this.onTarget2 = false;
_root.targetCircle.gotoAndStop(1);
}
};
//the variables below will store the clips starting position
circle_mc.myHomeX = circle_mc._x;
circle_mc.myHomeY = circle_mc._y;
//the variables below will store the clips end position
circle_mc.myFinalX = 450;
circle_mc.myFinalY = 250;
circle_mc.myFinalX2 = 110;
circle_mc.myFinalY2 = 286;
circle_mc.onMouseDown = function() {
//this variable tells us if the mouse is up or down
mousePressed = true;
};
circle_mc.onMouseUp = function() {
mousePressed = false;
};
circle_mc.onEnterFrame = function() {
//all these actions basically just say "if the mouse is up (in other words - the clip is not being dragged)
// then move the MC back to its original starting point (with a smooth motion)"
if (mousePressed == false && this.onTarget == false && this.onTarget2 == false) {
this._x -= (this._x-this.myHomeX)/5;
this._y -= (this._y-this.myHomeY)/5;
//if the circle is dropped on any part of the target it slides to the center of the target
} else if (mousePressed == false && this.onTarget == true) {
this._x -= (this._x-this.myFinalX)/5;
this._y -= (this._y-this.myFinalY)/5;
} else if (mousePressed == false && this.onTarget2 == true) {
this._x -= (this._x-this.myFinalX2)/5;
this._y -= (this._y-this.myFinalY2)/5;
}
};
Thanks again Bill!
fede
2008-10-14: Erik said:Thank you for the great tutorial Bill. I copied your code and I can drag and drop multiple movie clips. My problem is when circle_mc is dropped on targetCircle it doesn’t play frame 2 of the targetCircle movie clip. I’m trying to make it when circle_mc is dropped on targetCircle, targetCircle will play a movie clip. Does this make sense?
2008-10-24: Volker said:Hello,
im happy to found this page and the drag an drop function (i used the multiple targets function) works pretty well, but:
How do i get this work in AS3?
'Cause i want to implement the code in another Flash-project written in AS3!
Unfortunatly its very important for me to get this work in AS3. Need help please.
Here is my code:
var theClipIWasDroppedOn:String;
function dragSetup(clip, targ1, targ2) {
clip.onPress = function() {
startDrag(this);
this.beingDragged=true;
};
clip.onRelease = clip.onReleaseOutside=function () {
stopDrag();
this.beingDragged=false;
if ((eval(this._droptarget) == targ1) || (eval(this._droptarget) == targ2)) {
this.onTarget = true;
theClipIWasDroppedOn = eval(this._droptarget);
theClipIWasDroppedOn.gotoAndStop(2);
} else {
this.onTarget = false;
targ1.gotoAndStop(1);
targ2.gotoAndStop(1);
}
};
//the variables below will store the clips starting position
clip.myHomeX = clip._x;
clip.myHomeY = clip._y;
//the variables below will store the clips end position
clip.myFinalX = theClipIWasDroppedOn._x;
clip.myFinalY = theClipIWasDroppedOn._y;
clip.onEnterFrame = function() {
//all these actions basically just say "if the mouse is up (in other words - the clip is not being dragged)
// then move the MC back to its original starting point (with a smooth motion)"
if (!this.beingDragged && !this.onTarget) {
this._x -= (this._x - this.myHomeX)/5;
this._y -= (this._y - this.myHomeY)/5;
//if the circle is dropped on any part of the target it slides to the center of the target
} else if (!this.beingDragged && this.onTarget) {
this._x-= (this._x - this.myFinalX._x)/5;
this._y-= (this._y - this.myFinalY._y)/5;
}
};
}
dragSetup(circle_mc,targetCircle1,targetCircle2);
dragSetup(circle2_mc,targetCircle1,targetCircle2);
___________________
And thats the Error message in AS3:
TypeError: Error #1009: Der Zugriff auf eine Eigenschaft oder eine Methode eines null-Objektverweises ist nicht möglich.
at drag_n_drop_multiple_fla::MainTimeline/dragSetup()
at drag_n_drop_multiple_fla::MainTimeline/frame1()
_______________________
My starting point was some kind of EventListener, but how do i realize it?
greetings
volker
2008-10-24: Volker said:hello,
second state:
i rewrote the code to validate in AS3. But there's a problem with the "dropTarget" method.
i have two instances (targetCircle1 and 2) on stage an the two dragable circles. The dropTarget method doesnt correctly handle the instancces underneath the dragable circles... my two instances are recognized from dropTarget as "instance1" and "instance2", not as described above. Additionally the x and y value of thes instances are 0, not the same as the real circle instances... im really confused...
here the new code:
______________
import flash.display.*;
import flash.events.*;
//VARIABLES
var dropZone;
var actObjectClicked:MovieClip;
var myHomeX:Number;
var myHomeY:Number;
initialize();
// EVENT LISTENERS
circle_mc.addEventListener(MouseEvent.MOUSE_DOWN, clipMouseDown);
circle2_mc.addEventListener(MouseEvent.MOUSE_DOWN, clipMouseDown);
circle_mc.addEventListener(MouseEvent.MOUSE_UP, clipMouseUp);
circle2_mc.addEventListener(MouseEvent.MOUSE_UP, clipMouseUp);
circle_mc.buttonMode = true;
circle2_mc.buttonMode = true;
function initialize()
{
//store initial positions
circle_mc.myHomeX = circle_mc.x;
circle_mc.myHomeY = circle_mc.y;
circle2_mc.myHomeX = circle2_mc.x;
circle2_mc.myHomeY = circle2_mc.y;
}
function clipMouseDown(e:MouseEvent):void{
actObjectClicked = MovieClip(e.target);
actObjectClicked.startDrag();
}
function clipMouseUp(e:MouseEvent):void
{
stopDrag();
dropZone = actObjectClicked.dropTarget;
if ((dropZone == targetCircle1) || (dropZone == targetCircle2)) {
trace("Hit");
//dropZone.gotoAndStop(2);
actObjectClicked.x -= (actObjectClicked.x - actObjectClicked.dropTarget.x);
actObjectClicked.y -= (actObjectClicked.y - actObjectClicked.dropTarget.y);
} else {
targetCircle1.gotoAndStop(1);
targetCircle2.gotoAndStop(1);
actObjectClicked.x -= (actObjectClicked.x - actObjectClicked.myHomeX);
actObjectClicked.y -= (actObjectClicked.y - actObjectClicked.myHomeY);
//if the circle is dropped on any part of the target it slides to the center of the target
}
}
______________
greetings
volker
2008-10-24: Bill Trikojus said:Hi Volker
I've added an as3 version to the downloads at the end of the tute. You might also be interested in checking out this tute
Building a flash game in actionscript 3
cheers
2008-10-24: Volker said:Hi Bill,
thanks a lot for the hint, i must have been blind... the as3 file solves my problem and also clears the dropTarget issue, i had. (the small but important ".parent" is the solution)
And thanks for the link, think the tute will prove useful...
greetings from germany.
Volker
2008-10-24: Volker said:i forgot to mention some other requirements / issues:
1. all targets shall be valid targets for both drag-objects.
2. id like to delete the enterframe function, i want to handle the clips-behaviour directly from the stopDragging function inside the if-case.
Or do you have an other idea? (I need to call functions from there)
This is important because i need access to the targets name it was dropped . It doesnt help me to specifiy the final position of the clip only to 1 target. It needs to be dynamically.
greetings
2008-10-27: Bill Trikojus said:Hi Volker
Time to post this on a forum I think. Check out
actionscript.org
cheers
2008-11-08: Claudio Bueno said:Hi Bill!
Very nice work on this tutorial, really cool.
I'm trying to adjust it to this quiz I'm working on where I can drag one objet and drop to any target and it will tell if it is correct or not.
My knowledge at AS is very poor I tried a couple of things but none worked.
IntAct 302g - Place the continent names...
Example I saw at this url:
http://www.webwasp.co.uk/tutorials/A_IntAct-02-drag-drop/index.php
See below the AS:
function dragSetup(clip, targ) {
clip.onPress = function() {
startDrag(this);
this.beingDragged=true;
};
clip.onRelease = clip.onReleaseOutside=function () {
stopDrag();
this.beingDragged=false;
if (eval(this._droptarget) == targ) {
this.onTarget = true;
_root.targ.gotoAndStop(2);
this.gotoAndPlay(2);
} else {
this.onTarget = false;
_root.targ.gotoAndStop(1);
}
};
//the variables below will store the clips starting position
clip.myHomeX = clip._x;
clip.myHomeY = clip._y;
//the variables below will store the clips end position
clip.myFinalX = targ._x;
clip.myFinalY = targ._y;
clip.onEnterFrame = function() {
//all these actions basically just say "if the mouse is up (in other words - the clip is not being dragged)
// then move the MC back to its original starting point (with a smooth motion)"
if (!this.beingDragged && !this.onTarget) {
this._x -= (this._x-this.myHomeX)/5;
this._y -= (this._y-this.myHomeY)/5;
//if the circle is dropped on any part of the target it slides to the center of the target
} else if (!this.beingDragged && this.onTarget) {
this._x -= (this._x-this.myFinalX)/5;
this._y -= (this._y-this.myFinalY)/5;
}
};
}
dragSetup(fax,alvo_fax);
dragSetup(sonorizacao,alvo_som);
dragSetup(microfone,alvo_microfone);
dragSetup(notebook,alvo_notebook);
dragSetup(projetor,alvo_projetor);
dragSetup(ar,alvo_ar);
dragSetup(telao,alvo_telao);
dragSetup(caneta,alvo_caneta);
2008-11-08: Bill Trikojus said:You need to pass an array of targets to the setup function and then loop through that array when the drag item is dropped to see if you are on any of the targets. In each of the targets store a variable such as
alvo_caneta.correctClip=caneta
alvo_telao.correctClip=telao
//etc
so when an item is dropped on a target, you check of the var inside that target is equal to the clip that was dropped, and if it was then the answer was correct
You loop through an array with a for loop
cheers
2008-11-15: JD said:Fantastic Tutorial Bill. Thank you. It has really been a great help in learning flash interactivity.
Could you tell me how I might be able to have it make duplicates of itself as you drag from the original position?
In other words, when you drag it, there is a dragible duplicate at the origin
I am trying to do it with attachMovie, and (or)duplicateMovie.
function dragSetup(clip, targArray) {
clip.onPress = function() {
startDrag(this);
this.beingDragged = true;
duplicateMovieClip(clip, "clip"+1, 1);
};
2008-11-15: JD said:Fantastic Tutorial Bill. Thank you. It has really been a great help in learning flash interactivity.
Could you tell me how I might be able to have it make duplicates of itself as you drag from the original position?
In other words, when you drag it, there is a dragible duplicate at the origin
I am trying to do it with attachMovie, and (or)duplicateMovie.
function dragSetup(clip, targArray) {
clip.onPress = function() {
startDrag(this);
this.beingDragged = true;
duplicateMovieClip(clip, "clip"+1, 1);
};
2008-11-23: nikmauro said:I am trying to drag multiple items to many target but and one item to one specific target and the items with many target need lock the target from other item in the array
function dragSetup(clip, targArray) {
clip.onPress = function() {
startDrag(this);
this.beingDragged = true;
};
clip.onRelease = clip.onReleaseOutside=function () {
stopDrag();
this.beingDragged = false;
for (i=0; i
targ = targArray[i];
if (eval(this._droptarget) == targ) {
this.myFinalX=targ._x
this.myFinalY=targ._y
this.onTarget = true;
_root.targ.gotoAndStop(2);
break;
} else {
this.onTarget = false;
_root.targ.gotoAndStop(1);
}
}
};
//the variables below will store the clips starting position
clip.myHomeX = clip._x;
clip.myHomeY = clip._y;
clip.myFinalX = 0;
clip.myFinalY = 0;
clip.onEnterFrame = function() {
//all these actions basically just say "if the mouse is up (in other words - the clip is not being dragged)
// then move the MC back to its original starting point (with a smooth motion)"
if (!this.beingDragged && !this.onTarget) {
this._x -= (this._x-this.myHomeX)/5;
this._y -= (this._y-this.myHomeY)/5;
//if the circle is dropped on any part of the target it slides to the center of the target
} else if (!this.beingDragged && this.onTarget) {
this._x -= (this._x-this.myFinalX)/5;
this._y -= (this._y-this.myFinalY)/5;
}
};
}
allTargets = new Array(targetCircle1, targetCircle2, targetCircle3);
dragSetup(circle1_mc,allTargets);
dragSetup(circle2_mc,allTargets);
dragSetup(circle3_mc,allTargets);
dragSetup(circle4_mc,targetCircle4);
2008-11-23: Bill Trikojus said:Sorry nikmauro but I have no idea what you are asking. You might want to post your question on a Flash forum.
cheers
2008-11-23: Bill Trikojus said:JD - not exactly sure how you want it to function, but the following code will create a copy of the original clip when it is pressed and then call drag setup on the copy. An extra parameter is added to the function to ensure copies are dragged when pressed and originals are copied.
Hope it helps
import mx.transitions.Tween;
import mx.transitions.easing.*;
function dragSetup(clip, targ, original) {
clip.original = original;
clip.onPress = function() {
if (this.original) {
copy = this.duplicateMovieClip('copy'+_root.getNextHighestDepth(), _root.getNextHighestDepth());
dragSetup(copy,targ,false);
copy.onPress();
} else {
startDrag(this);
}
};
clip.onRelease = clip.onReleaseOutside=function () {
stopDrag();
if (eval(this._droptarget) == targ) {
var tx:Tween = new Tween(this, '_x', Elastic.easeOut, this._x, this.myFinalX, 1, true);
var ty:Tween = new Tween(this, '_y', Elastic.easeOut, this._y, this.myFinalY, 1, true);
targ.gotoAndStop(2);
} else {
var tx:Tween = new Tween(this, '_x', Elastic.easeOut, this._x, this.myHomeX, 1, true);
var ty:Tween = new Tween(this, '_y', Elastic.easeOut, this._y, this.myHomeY, 1, true);
targ.gotoAndStop(1);
}
};
//the variables below will store the clips starting position
clip.myHomeX = clip._x;
clip.myHomeY = clip._y;
//the variables below will store the clips end position
clip.myFinalX = targ._x;
clip.myFinalY = targ._y;
}
dragSetup(circle_mc,target_mc,true);
2008-11-23: Bill Trikojus said:In hindsight it would have be easier and cleaner to set up a separate function for setting up the original clip's onPress and just leaving the dragSetup function as it was
Like this
import mx.transitions.Tween;
import mx.transitions.easing.*;
function dragSetup(clip, targ) {
clip.onPress = function() {
startDrag(this);
};
clip.onRelease = clip.onReleaseOutside=function () {
stopDrag();
if (eval(this._droptarget) == targ) {
var tx:Tween = new Tween(this, '_x', Elastic.easeOut, this._x, this.myFinalX, 1, true);
var ty:Tween = new Tween(this, '_y', Elastic.easeOut, this._y, this.myFinalY, 1, true);
targ.gotoAndStop(2);
} else {
var tx:Tween = new Tween(this, '_x', Elastic.easeOut, this._x, this.myHomeX, 1, true);
var ty:Tween = new Tween(this, '_y', Elastic.easeOut, this._y, this.myHomeY, 1, true);
targ.gotoAndStop(1);
}
};
//the variables below will store the clips starting position
clip.myHomeX = clip._x;
clip.myHomeY = clip._y;
//the variables below will store the clips end position
clip.myFinalX = targ._x;
clip.myFinalY = targ._y;
}
function origSetup(clip, targ) {
clip.onPress = function() {
copy = this.duplicateMovieClip('copy'+_root.getNextHighestDepth(), _root.getNextHighestDepth());
dragSetup(copy,targ);
copy.onPress();
};
}
origSetup(circle_mc,target_mc);
2008-11-24: JD said:Bill, that's brilliant. Thank very much. I apologize for not being completely specific. I in fact want to do exactly this, but with an array of targets. I have 27 clips, and 23 targets. I am trying to work your array code into this newest version.
If you could throw me a hint, I would be very appreciative.
Also, something else which has me frustrated, is that I can not seem to set a blendMode for the new clip. The images I am using are bitmaps with a white background. The original movieclips are set to "multiply", but when I drag them, I can see the white background.
I tried using:
this.blendMode = 3;
I also tried
copy.blendMode = 3;
But, it didn't seem to have any effect. Here is where I put it.
clip.onPress = function() {
copy = this.duplicateMovieClip('copy'+_root.getNextHighestDepth(), _root.getNextHighestDepth());
this.blendMode = 3;
dragSetup(copy,targ);
Thank you again :)
2008-11-26: RudyC said:Hey love the AS2 samples provided. I'm looking to use the multi-D&D code and would like to keep track of the successful drops using a hit counter so that I can show a running count of the good matches and when all items are matched to give a congratulation message. I can add and increment the hit counter when there is a match but how do I know when a successful match is removed from the valid target to reduce the hit by one to keep to count current. Or, how do I prevent a drag item from being moved out once on target. I've played with AS3 D&D code samples that do this with event listeners, but I'm looking for a AS2 solution (Flash8) that preferably is adapted to the sample code here.
2008-12-09: DO said:Bill,
This tutorial has bee a great help! Thank you for your sharing!
I have a question similar to JD's regarding multiple copies to drag. I've used the code you provided to him to make a copy of the clip when you drag it. However when i click to drag another copy the new copy replaces the first copy. How could i change the code so that it will keep creating new copies each time it is dragged without replacing the other copies? Or is there a way to specify that it will make 10 copies but no more? Any help or hints would be greatly appreciated as I am somewhat new to AS. I am using Flash 8 and AS2.
Thank you ahead of time for you help!
2008-12-09: Bill Trikojus said:On my mobile so I can't view the code but I think you just to make sure the depth param for duplicateMovieClip is always unique. Check out
_root.getNextHighestDepth()
2008-12-09: DO said:Bill,
Here's the code I am currently using. For the most part it is the code you posted for JD to use. For some reason it isn't dropping on release, I have to click to get it to release. But either way it's still making one copy and then replacing it each time I click on the original. I think I have the depth set right but I'm wondering if it has something to do with an onRelease command in the second function? Any help would be great! Thank you for you expertise!
import mx.transitions.Tween;
import mx.transitions.easing.*;
function dragSetup(clip, targ) {
clip.onPress = function() {
startDrag(this);
};
clip.onRelease = clip.onReleaseOutside=function () {
stopDrag();
//I want the dragged item to stay where it's dropped so I left "if" empty
if (eval(this._droptarget) == targ) {
}
else {
var tx:Tween = new Tween(this, '_x', Elastic.easeOut, this._x, this.myHomeX, 1, true);
var ty:Tween = new Tween(this, '_y', Elastic.easeOut, this._y, this.myHomeY, 1, true);
}
};
clip.myHomeX = clip._x;
clip.myHomeY = clip._y;
clip.myFinalX = targ._x;
clip.myFinalY = targ._y;
}
function origSetup(clip, targ) {
clip.onPress = function() {
copy = this.duplicateMovieClip('copy'+_root.getNextHighestDepth, _root.getNextHighestDepth());
dragSetup(copy,targ);
copy.onPress();
};
}
origSetup(test_orn,targetTree);
2008-12-09: Bill Trikojus said:and this code is on _root?
You are missing () after the first getNextHighestDepth - see if that is the problem.
2008-12-10: DO said:This code is on _root on the first frame of the top layer. I added the () but still the same thing. It won't drop on release (only on another click) and when i try to drag another one the first one is replaced. I'm just not seeing where the problem lies... Everything seems to be in order...
2008-12-10: Bill Trikojus said:I just used your exact code and it made a new copy each time so I'm not sure what you're doing wrong there. Regarding the need to click twice to get it to go home initially, add an onMouseUp event
import mx.transitions.Tween;
import mx.transitions.easing.*;
function dragSetup(clip, targ) {
clip.onPress = function() {
startDrag(this);
};
clip.onRelease = clip.onReleaseOutside=clip.onMouseUp=function () {
stopDrag();
//I want the dragged item to stay where it's dropped so I left "if" empty
if (eval(this._droptarget) == targ) {
}
else {
var tx:Tween = new Tween(this, '_x', Elastic.easeOut, this._x, this.myHomeX, 1, true);
var ty:Tween = new Tween(this, '_y', Elastic.easeOut, this._y, this.myHomeY, 1, true);
}
};
clip.myHomeX = clip._x;
clip.myHomeY = clip._y;
clip.myFinalX = targ._x;
clip.myFinalY = targ._y;
}
function origSetup(clip, targ) {
clip.onPress = function() {
copy = this.duplicateMovieClip('copy'+_root.getNextHighestDepth(), _root.getNextHighestDepth());
dragSetup(copy,targ);
copy.onPress()
};
}
origSetup(test_orn,targetTree);
cheers
2008-12-10: DO said:Bill,
You are a life saver! the onMouseUp event was exactly what i needed. I must confess my beginner's lack of knowledge was what got me. I had forgotten that i was publishing to a Flash 6 document. I feel very bad for wasting your time with all that when all I needed was to publish to 7 or later. I sincerely apologize! however I never would have figured this out without your help.
So thank you very much for you expertise and willingness to help! You are greatly appreciated!
Thank you a million times!
Daniel
2008-12-10: Bill Trikojus said:ah of course. getNextHighestDepth() wasn't added until v7. Anyway, glad you got it sorted.
All the best
Bill
2008-12-11: Nick Court said:Dear Bill
I have been using your fab script for a while now ... and it has made me also appear fantastic!
However I have encountered a conundrum that I hope you might help me solve.
I have created a couple of swfs with the script as normal ... but I now have to import into Powerpoint for further export via Presenter/Adobe Connect. When viewed in Powerpoint all is well ... but in Connect things drag but do not drop.
Here are examples of the dysfuntional connect version, the working ppt and the script in question.
http://www.le.ac.uk/sc/njc6/connect/index.htm
http://www.le.ac.uk/sc/njc6/connect/dra … roblem.ppt
http://www.le.ac.uk/sc/njc6/connect/draganddrop.txt
Bringing the swf into Connect involves the file being loaded into an unknown level/relationship within the main connect file. So my question is ... is there a way to address the target so that the swf works completely independently of any movie it is loaded into??
2008-12-11: Bill Trikojus said:Hi Nick,
I'm afraid I don't have any experience displaying flash in powerpoint so I can't help there but regarding your paths, you need to ensure that all paths are 'relative'. If you refer to _root anywhere, the path will break when the movie is loaded into the another movie. All the paths in the tute are relative with the exception of these lines
_root.targ.gotoAndStop(2);
that can just be changed to
targ.gotoAndStop(2);
and it should all work fine.
Hope that helps
2008-12-11: Nick Court said:Thanks for your reply Bob ... much appreciated ... this must be your lifes work!!
I had got rid of all _root references ..
Hey .. it's only work... I think I can use a cheesier script .. or, of course, encourage people not to use Connect!
Thanks again
Nick
2008-12-14: Kasia said:Hello Bob, I have problem in quiz file when I want him to be played in another file (.exe projector from fla) I have put this._lockroot=true; to quiz and it helps but I still have problem with drag and drop question
here you find file with this problematic question
http://www.speedyshare.com/601646842.html
when you run it it works ok but when you want him to be played in another swf for example, it doesnt :(
correct positions for letters is: V L W M
2008-12-17: Sandra said:Hi Bill,
thanks for that great tutorial! I'm completely new to Flash but it (almost) worked out fine. Only problem I have is that my circles don't change color in the multiple version. I copied your code and have no idea why it's not working. I use Flash MX.
Thanks
Sandra
2008-12-17: Bill Trikojus said:Hi Sandra
Hard to know without seeing some code or the file. If you can upload it somewhere and post a link I'll take a look.
Is everything on _root? You could try getting rid of _root from the code and just say
targ.gotoAndStop(2);
cheers
2008-12-18: Sandra said:Hi Bill,
thank you for your really fast answer!! When I just looked at my file again I noticed that at some point the second frame within my target mc got lost. Of course it works fine now. I really thought I had checked that before.
Thanks anyway!
2009-01-30: Matt said:This works great on the root, but I am loading into level500.
I think this needs to be changed,
if (this._droptarget == "/targetCircle") {
Thoughts?
2009-01-30: Bill Trikojus said:If you trace the droptarget you should be able to get the full path
trace(eval(this._droptarget))
should end up with something like
if (eval(this._droptarget) == _level500.targetCircle) {
cheers
2009-02-05: Yoma said:Thank you so much - this is a life saver!!!
2009-02-12: David said:Thanks for the tutorial Bill. Fantastic.
Im relatively new to flash, and have everything you had in your tutorial working fine. My problem is that once I have ALL the circles on their targets, I want it to give the person feedback, but not until all are in correct position. Do you have something to help with this? Im guessing that i need to tell it to move to frame 3, but am unsure how to do this, and also unsure on how to tell it to wait till all are correct. I havent made any changes from your original code.
Thanks in advance.
2009-02-14: Andy said:Great tutorial!
I have made a "reset button" as
reset1.onRelease = function () {
circle_mc._x = circle_mc.myHomeX;
circle_mc._y = circle_mc.myHomeY;
}
How can i add a smooth motion to move circle_mc into the start position?
Thanks in advance.
2009-02-28: brendan said:what an awesome tutorial, and you are so helpful and patient. I think it's amzing how you replied to, and answered all the questions people posted. Your knowledge is very impressive, where can I find more lessons you've created?
2009-03-04: Bill Trikojus said:Hi Brendan
Just click the Flash link in the menu on the left for many more tutorials.
cheers
2009-03-06: Adrian said:Hi Bill !
Excellent tutorial , really .. But i don´t know what part of the code i must to change to create three targets and two dragable MC, where the MCclips has been a correct and incorrect answers (go to and play other scenes when the two MCclips has been drag) and most be dragables on three targets.
Mi code is this but not work ..
function dragSetup(clip, targ, targ1) {
clip.onPress = function() {
startDrag(this);
this.beingDragged=true;
};
clip.onRelease = clip.onReleaseOutside=function () {
stopDrag();
this.beingDragged=false;
if (eval(this._droptarget) == targ || eval(this._droptarget) == targ1) {
this.onTarget = true;
_root.targ.gotoAndStop(2);
} else {
this.onTarget = false;
_root.targ.gotoAndStop(1);
}
};
clip.myHomeX = clip._x;
clip.myHomeY = clip._y;
clip.myFinalX = targ._x;
clip.myFinalY = targ._y;
clip.onEnterFrame = function() {
if (!this.beingDragged && !this.onTarget) {
this._x -= (this._x-this.myHomeX)/5;
this._y -= (this._y-this.myHomeY)/5;
} else if (!this.beingDragged && this.onTarget) {
this._x -= (this._x-this.myFinalX)/5;
this._y -= (this._y-this.myFinalY)/5;
}
};
}
dragSetup(circle_mc,targetCircle);
dragSetup(circle2_mc,targetCircle2);
Note * The last lines of code i put :
1 .- (circle_mc,targetCircle, targetCircle2, TargetCircle3);
2.- (circle_mc,targetCircle);
(circle_mc,targetCircle2);
(circle_mc,targetCircle3);
and use ...
(circle_mc,targetCircle and targetCircle2);
and ,,
(circle_mc,targetCircle or targetcircle2);
but any of two MC is drag into target 3.
Thank for your help
2009-03-06: Bill Trikojus said:Hi Adrian
there are too many issues to work through in this forum. You need to post it on a proper Flash forum such as actionscript.org where there are thousands of users and the ability to upload files.
cheers
2009-03-09: David said:Thanks for the tutorial Bill. Fantastic.
Im relatively new to flash, and have everything you had in your tutorial working fine. My problem is that once I have ALL the circles on their targets, I want it to give the person feedback, but not until all are in correct position. Do you have something to help with this? Im guessing that i need to tell it to move to frame 3, but am unsure how to do this, and also unsure on how to tell it to wait till all are correct. I havent made any changes from your original code.
Thanks in advance.
2009-03-12: Adrian said:Hi again Bill ...
I tryed to fix my code but i can´t. I read all the post many times to understand in the correct way.
I have 2 Drag MC and 3 targets ... but still don´t work.
And i want to my 2 MC`s can drag on any of my 3 targets.
But in the movie when i take the MC 1 or 2 to put in the target 1 ,2 or 3 ... The MC´s drop down only in the target 1 , and the targets 2 and 3 will return the MC´s to target 1....
Why ???
This my code ...
i follow your explains.
function dragSetup(clip,targ,targ1,targ2) {
clip.onPress = function() {
startDrag(this);
this.beingDragged=true;
};
clip.onRelease = clip.onReleaseOutside=function () {
stopDrag();
this.beingDragged=false;
if (eval(this._droptarget) == targ || eval(this._droptarget) == targ1 || eval(this._droptarget) == targ2) {
this.onTarget = true;
_root.targ.gotoAndStop(2);
} else {
this.onTarget = false;
_root.targ.gotoAndStop(1);
}
};
clip.myHomeX = clip._x;
clip.myHomeY = clip._y;
clip.myFinalX = targ._x;
clip.myFinalY = targ._y;
clip.onEnterFrame = function() {
if (!this.beingDragged && !this.onTarget) {
this._x -= (this._x-this.myHomeX)/5;
this._y -= (this._y-this.myHomeY)/5;
} else if (!this.beingDragged && this.onTarget) {
this._x -= (this._x-this.myFinalX)/5;
this._y -= (this._y-this.myFinalY)/5;
}
};
}
dragSetup(circle_mc,targetCircle,targetCircle2,targetCircle3);
dragSetup(circle2_mc,targetCircle,targetCircle2,targetCircle3);
Thnks for your time.
2009-03-12: Bill Trikojus said:Like I said - this would be better dealt with on a proper forum.
You have hard coded the finalX and Y positions as the first targets x and y - I assume you want the dropped clip to ease to the middle of the target it was actually dropped on? Also when you drop on any target you are telling the first target to go to frame 2 - I doubt this is what you want. Try this
function dragSetup(clip,targ,targ1,targ2) {
clip.onPress = function() {
startDrag(this);
this.beingDragged=true;
};
clip.onRelease = clip.onReleaseOutside=function () {
stopDrag();
this.beingDragged=false;
theDrop=eval(this._droptarget);
if ( theDrop == targ || theDrop == targ1 || theDrop == targ2) {
this.onTarget = true;
theDrop.gotoAndStop(2);
//ease to middle of clip it was dropped on
this.myFinalX = theDrop._x;
this.myFinalY = theDrop._y;
} else {
this.onTarget = false;
//I'll let you figure out which clips need to be reset
_root.targ.gotoAndStop(1);
}
};
clip.myHomeX = clip._x;
clip.myHomeY = clip._y;
clip.onEnterFrame = function() {
if (!this.beingDragged && !this.onTarget) {
this._x -= (this._x-this.myHomeX)/5;
this._y -= (this._y-this.myHomeY)/5;
} else if (!this.beingDragged && this.onTarget) {
this._x -= (this._x-this.myFinalX)/5;
this._y -= (this._y-this.myFinalY)/5;
}
};
}
dragSetup(circle_mc,targetCircle,targetCircle2,targetCircle3);
dragSetup(circle2_mc,targetCircle,targetCircle2,targetCircle3);
cheers
2009-03-13: Adrian said:Wow .... This like i need ... Thank you very much
: D !!!
2009-03-31: Miranda said:The multiple drag & drop was exactly what I needed! Thx a lot!
2009-04-01: Kev said:Hi Bill, thanks for the great tutorial! It's been a life saver with this game I'm making. I have just one small problem though, I'm using the multiple target method and can't figure out for the life of me how to get the timeline to go to the next frame for a completion page when all the objects are in their correct place. Any help is much appreciated! Thanks again!
2009-04-03: Richard Watson said:Hi
I stumbled upon this tutorial. I'm looking for a developer, but the software must run as 3D rather than 2D. You obviously have 2D skills, have you ever dealt with 3D and importing/exporting results.
2009-04-03: Bill Trikojus said:I'm not currently looking for any freelance work.
thanks anyway
2009-04-03: Miranda said:Kev
I also struggled but figuredit out: the code to go to a next frame on completion should go into the code below. I used a counter to see if they had all correct. I also added a notice telling them 'correct' on each good hit.
if (eval(this._droptarget) == eval(("/"+targ))) {
this.onTarget = true;
feedback_txt.setTextFormat(correctFormat);
feedback_txt.htmlText = "Correct!";
myCounter = myCounter+1;
if (myCounter == your number of objects){
gotoAndPlay(2);
}
Hope this makes sense:-)
2009-04-06: David said:Thank you Miranda.
Exactly what I have been looking for. just had to add:
var myCounter:Number=0
on the top line to get it to work :)
2009-04-22: Bryan said:The tutorial is great, is there anyway to make it so that both draggable objects can be placed in any of the drop targets? Please let me know, i've been trying but no luck.
2009-05-08: Will said:Did anybody have any luck getting the movie to play in an Exe file? I have tried all of the _root.lockroot = true; and this.lockroot = true; methods.
Thanks
2009-05-15: Shaun Sleeman said:Hi Bill,
I saw your tutorial briefly and thought it was brilliant. I am a year 12 student at St Brendan's College, Yeppoon, Queensland, and I am studying Information Technology Systems. For our assignment we are creating flash games using design view and action script 2. But I have a problem. For my assignment I wanted to have drag and drop, But the drag and drop was going to be for the answer. I was wandering if there is anyway I could make it that if the box was dropped in a certain place then the answer is correct?
Thanks,
Shaun
2009-05-15: Bill Trikojus said:Hi Shaun,
Did you read through all the comments? Pretty sure this question has already been answered.
2009-05-17: teode said:Hi Bill, great tutorial!
I have various movie clips that can be dragged around and placed anywhere on the stage.
Now, what i need is to give the user the option of dragging any of these movie clips into a "trash bin" and, as an obvious consequence, the movie clip disappears from stage. Any ideas?
Thanks!
2009-05-17: Jackson McG said:Hi Bill,
This is a very excellent tutorial I'd like to thank you for making my game easier to create! I am using your script from the drag and drop multiple objects zip:
function dragSetup(clip, targArray) {
clip.onPress = function() {
startDrag(this);
this.beingDragged = true;
};
clip.onRelease = clip.onReleaseOutside=function () {
stopDrag();
this.beingDragged = false;
for (i=0; i
targ = targArray[i];
if (eval(this._droptarget) == targ) {
this.myFinalX = targ._x;
this.myFinalY = targ._y;
this.onTarget = true;
_root.targ.gotoAndStop(2);
break;
} else {
this.onTarget = false;
_root.targ.gotoAndStop(1);
}
}
};
//the variables below will store the clips starting position
clip.myHomeX = clip._x;
clip.myHomeY = clip._y;
clip.myFinalX = 0;
clip.myFinalY = 0;
clip.onEnterFrame = function() {
//all these actions basically just say "if the mouse is up (in other words - the clip is not being dragged)
// then move the MC back to its original starting point (with a smooth motion)"
if (!this.beingDragged && !this.onTarget) {
this._x -= (this._x-this.myHomeX)/2;
this._y -= (this._y-this.myHomeY)/2;
//if the circle is dropped on any part of the target it slides to the center of the target
} else if (!this.beingDragged && this.onTarget) {
this._x -= (this._x-this.myFinalX)/2;
this._y -= (this._y-this.myFinalY)/2;
}
};
}
allTargets = new Array(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31, s32, s33, s34, s35, s36, s37, s38, s39, s40, s41, s42, s43, s44, s45, s46, s47, s48, s49, s50, s51, s52, s53, s54, s55, s56, s57, s58, s59, s60);
dragSetup(k1, allTargets);
dragSetup(k2, allTargets);
reset.onPress = function() {
k1._x = k1.myHomeX;
k1._y = k1.myHomeY;
k2._x = k2.myHomeX;
k2._y = k2.myHomeY;
};
And it works but I am curious as to how I could make a copy of say K1 when i begin to drag it so that a copy will be in its original place that is also draggable. Thanks!
2009-05-17: Daniel W said:Hello Bill,
with reference to the 'drag and drop with multiple targets' FLA, I sincerely seek assistance on how to edit its actionscript to accomplish the following:
[B]Scenario[/B]
Flash has a classroom scene - three slides (or draggable objects), a slide projector (droptarget) and a screen on the wall. All three objects share the same droptarget.
A movieclip (info_mc) with four labels (each containing different information for the corresponding slide dragged onto droptarget) - 'reset', 'slide1info', 'slide2info' and 'slide3info' is positioned at the screen area. Default to 'reset' since nothing has been dragged to the droptarget when the swf loads.
If the user drags an slide1 onto the droptarget, the movieclip at the screen area will jump to the corresponding frame label
info_mc.gotoAndStop("slide1info");
But the droptarget can only accomodate one object at a time. When the user drags slide2 over the droptarget where slide1 already resides, slide1 will move back to its original position.
And if the user drags a slide out of the droptarget (i.e. nothing at the droptarget), info_mc will gotoAndStop ("reset").
Any insight will be greatly appreciated.
Rgds,
Dan
2009-05-17: Bill Trikojus said:teode,
When you detect that the clip has been dropped on the trash, just say
this._visible=false;
cheers
2009-05-17: Bill Trikojus said:Jackson,
this question has been answered in the comments above - do a search for "JD"
cheers
2009-05-17: Bill Trikojus said:Daniel,
You can get the instance name of the movieclip with this._name . So to get the info_mc to go to the right frame it would be something like
if (eval(this._droptarget) == targ) {
this.onTarget = true;
info_mc.gotoAndStop(this._name+"info");
}
To only allow one item on the target at a time, you could just set the onTarget var to false for all the clips before setting it to true for the one that was dropped
if (eval(this._droptarget) == targ) {
slide1.onTarget=false;
slide2.onTarget=false;
//etc
this.onTarget = true;
info_mc.gotoAndStop(this._name+"info");
}
for the final problem, whenever a clip is dropped and you detect that it wasn't dropped on the target, check if onTarget is true for any of then and if not reset the info clip. So at the moment you might have
//from my original function
} else {
this.onTarget = false;
//check all the clips
//! MEANS FALSE
if(!slide1.onTarget && !slide2.onTarget && !another_mc.onTarget){
info_mc.gotoAndStop("reset");
}
_root.targ.gotoAndStop(1);
}
cheers
2009-05-18: Daniel W said:Thank you very much for the assistance, Bill. It's greatly appreciated.
Just one last bit to tweak.
But if slide1 already resides at the droptarget and I want it to return to its original position when I drag slide2 to the droptarget, how do I go about it?
Right now, the script doesn't allow me to drag another clip to the droptarget when it's already occupied. I have to drag out slide1, leave the droptarget empty before I can drag slide2 in.
The current actionscript with your edit:
function dragSetup(clip, targ) {
clip.onPress = function() {
startDrag(this);
this.beingDragged=true;
};
clip.onRelease = clip.onReleaseOutside=function () {
stopDrag();
this.beingDragged=false;
if (eval(this._droptarget) == targ) {
slide1.onTarget = false;
slide2.onTarget = false;
//etc
this.onTarget = true;
info_mc.gotoAndStop(this._name+"info");
} else {
this.onTarget = false;
//check all the clips
//! MEANS FALSE
if(!slide1.onTarget && !slide2.onTarget){
info_mc.gotoAndStop("reset");
}
}
};
//the variables below will store the clips starting position
clip.myHomeX = clip._x;
clip.myHomeY = clip._y;
//the variables below will store the clips end position
clip.myFinalX = targ._x;
clip.myFinalY = targ._y;
clip.onEnterFrame = function() {
//all these actions basically just say "if the mouse is up (in other words - the clip is not being dragged)
// then move the MC back to its original starting point (with a smooth motion)"
if (!this.beingDragged && !this.onTarget) {
this._x -= (this._x-this.myHomeX)/5;
this._y -= (this._y-this.myHomeY)/5;
//if the circle is dropped on any part of the target it slides to the center of the target
} else if (!this.beingDragged && this.onTarget) {
this._x -= (this._x-this.myFinalX)/5;
this._y -= (this._y-this.myFinalY)/5;
}
};
}
dragSetup(slide1,dropzone);
dragSetup(slide2,dropzone);
Please advise.
Rgds,
Dan
2009-05-18: Bill Trikojus said:When you drag another object on, you set onTarget to salse for all the other clips, so this should send the clip that is already on the target home. This is the bit that should do it
if (!this.beingDragged && !this.onTarget) {
this._x -= (this._x-this.myHomeX)/5;
this._y -= (this._y-this.myHomeY)/5;
2009-05-18: Daniel W said:Thank you for the prompt response, Bill.
I follow the logic on setting onTarget to false for all other clips so only the one that is dragged over the droptarget is 'true' but the bug persists.
If slide1 is already at the droptarget, I can't drag slide2 over it (by virtue slide2.onTarget = false; as long as slide1 is at the droptarget). I have to drag out slide1 then I can drag slide2 into the droptarget.
Any insight is greatly appreciated. Thanks for your time once again.
Rgds,
Dan
2009-05-18: Shaun Sleeman said:Hi Bill,
Thank you for your help. I will try to incorporate this code into my assignment. I will make sure this site has been referenced. Once again, I thank you for your help and thanks for the help that you are giving lots of people.
Regards,
Shaun
2009-05-18: Bill Trikojus said:Is it possible that you are dropping slide2 on to slide1? The would cause a different _droptarget to be returned which would cause your bug. Try tracing the _droptarget when you drop an item.
2009-05-18: Daniel W said:Hello Bill,
in all honesty, I'm an actionscript newbie hence I'm somewhat lost when you tell me to trace the droptarget. My sincere apologies and many thanks for your patience.
If I want to drag slide2 over to the droptarget while it's already occupied by slide1, then in a way I'm 'dropping slide2 over slide1'.
I just need slide1 to vacate from the droptarget as soon slide2 is dragged onto the droptarget and have slide1 return to its original position.
I seek your kind assistance once again.
Rgds,
Dan
2009-05-18: Daniel W said:Hello Bill,
I found a solution to the problem! :)
I moved the droptarget layer higher than the layer containing the slides and it works. Not the developer's way of solving the problem but at least it works.
Thanks for your kind assistance and patience.
Have a pleasant week ahead.
Best rgds,
Dan
2009-05-18: Bill Trikojus said:that's an adequate solution if your drop area is invisible.
Glad you got it sorted.
2009-05-24: nicky said:Hi Bill,
great tutorial. perfect for what i'm doing, just need a little help, I have 2 movieclips that have the same target, however if one is dragged to the target then you want to drag the other one (to see a different outcome) i want the first one to return to it's home position when second one is clicked on so they're not both on the target at the same time and can't go on top of each other.
Hope this makes sense. Thanks again.
Nicky
2009-05-24: Sobella said:Hi Bill,
Just wanted to let you know that in my Flash 8, "_root.targ.gotoAndStop(2);" worked fine in the single click and drag movie but not multiple. However, when I removed the _root from both the 1st and 2nd frames, it worked fine.
Also, I don't know if someone else has asked this before (since I didn't have time to go through all the above posts) and I want to know how to make the movie clips stop moving once they've been dropped on their targets. I'm trying to create a spelling quiz for kids and would like to display a 'congrats' message once all the letters are in their place!
Thanks in advance!
2009-05-24: Bill Trikojus said:Nicky and Sobella,
I believe both of those questions have already been answered in the comments above
cheers
2009-05-26: Jesse said:HI,
I have flash cs4. However,I cant open the drag_n_drop_multiple.fla file, but I can open drag_n_dropMX.fla.....any idea why??
Thanks,
Jesse
2009-05-27: Jesse said:How can I trace the following:
dragSetup(circle_mc,targetCircle);
2009-05-27: Bill Trikojus said:what exactly are you trying to output?
2009-05-29: Jesse said:I'm trying to change: "targetCircle" on MOUSE_OVER.
Ideally I would like to change its state once the circle_mc is hovered over top of it - so that it shows that you've entered and it is ready to drop off.
I would like to trace when it is hit instead of dropped.
Thanks,
Jesse
2009-05-29: Bill Trikojus said:ok in AS3 when you start dragging the object, start an ENTER_FRAME event that is running a hitTestObject over and over between the dragged object and the target. When hitTestObject returns true, change the state of the target.
cheers
2009-05-30: Jesse said:Hi Bill,
Thanks for the feedback.
I tired this but i only get a 'false' when I start dragging. I can get it to return 'true', but only when it is dropped.
IS this where I should be placing the ENTER_FRAME?
function startDragging(e:MouseEvent):void {
e.target.startDrag();
e.target.beingDragged=true;
trace(targ.hitTestObject(e.target));
Tweener.addTween(e.target.dash_mc, {alpha:0, time:0.4, transition:"linear"});
//Assign highest depth to circle
setChildIndex(e.target, numChildren - 1);
trace("highest");
//Trace Hit test
e.target.addEventListener(MouseEvent.ENTER_FRAME, HitTarg);
function HitTarg(event:MouseEvent):void {
trace(e.target.hitTestObject(targ));
}
}
Thanks again,
Jesse
2009-05-30: Bill Trikojus said:ENTER_FRAME is not a MouseEvent
you want Event.ENTER_FRAME
cheers
2009-06-01: Jesse said:Awesome, thanks for the help.
Jesse
2009-06-07: Brian said:Great Tut. Just wondering I have made a reset button as
reset1.onRelease = function () {
slope_mc._x = slope_mc.myHomeX;
slope_mc._y = slope_mc.myHomeY;
}
when button is pressed it goes to original position but then flys back to target. How can I stop this?
2009-06-07: Bill Trikojus said:sounds like you also need to set onTarget back to false
reset1.onRelease = function () {
slope.onTarget=false;
slope_mc._x = slope_mc.myHomeX;
slope_mc._y = slope_mc.myHomeY;
}
2009-06-07: Brian said:I tried this Bill but no go.Would it make difference how many variables there are?
2009-06-07: Brian said:Sorry Bill, can see now should be slope_mc.onTarget= false; Thanks for that. I think I might watch the easing tut to see how to ease them back to original position.
2009-06-15: Darren said:Hi Bill.
I'm creating a website that use the letters of the alphabet that can be dragged onto different targets in order to spell out the user's name. I stumbled across your code and I have now managed to achieve what I wanted. My question is to do with duplicating the letters in case more than one of the same kind is required.
The code that I used of yours (and slightly modified) is as follows:
function dragSetup(clip, targArray) {
clip.onPress = function() {
startDrag(this);
this._x -= this._width/5;
this._y -= this._height/5;
this._xscale = 375;
this._yscale = 375;
this.beingDragged = true;
};
clip.onRelease = clip.onReleaseOutside=function () {
stopDrag();
this.beingDragged = false;
for (i=0; i
targ = targArray[i];
if (eval(this._droptarget) == targ) {
this.myFinalX = targ._x;
this.myFinalY = targ._y;
this.onTarget = true;
this._xscale = 375;
this._yscale = 375;
_root.targ.gotoAndPlay(2);
break;
} else {
this.onTarget = false;
_root.targ.gotoAndStop(1);
this._xscale = 100;
this._yscale = 100;
}
}
};
//the variables below will store the clips starting position
clip.myHomeX = clip._x;
clip.myHomeY = clip._y;
clip.myFinalX = 0;
clip.myFinalY = 0;
clip.onEnterFrame = function() {
//all these actions basically just say "if the mouse is up (in other words - the clip is not being dragged)
// then move the MC back to its original starting point (with a smooth motion)"
if (!this.beingDragged && !this.onTarget) {
this._x -= (this._x-this.myHomeX)/5;
this._y -= (this._y-this.myHomeY)/5;
//if the circle is dropped on any part of the target it slides to the center of the target
} else if (!this.beingDragged && this.onTarget) {
this._x -= (this._x-this.myFinalX)/5;
this._y -= (this._y-this.myFinalY)/5;
}
};
}
allTargets = new Array(circle1, circle2, circle3, circle4, circle5, circle6, circle7, circle8);
dragSetup(letterA,allTargets);
dragSetup(letterB,allTargets);
dragSetup(letterC,allTargets);
dragSetup(letterD,allTargets);
dragSetup(letterE,allTargets);
dragSetup(letterF,allTargets);
dragSetup(letterG,allTargets);
dragSetup(letterH,allTargets);
dragSetup(letterI,allTargets);
dragSetup(letterJ,allTargets);
dragSetup(letterK,allTargets);
dragSetup(letterL,allTargets);
dragSetup(letterM,allTargets);
dragSetup(letterN,allTargets);
dragSetup(letterO,allTargets);
dragSetup(letterP,allTargets);
dragSetup(letterQ,allTargets);
dragSetup(letterR,allTargets);
dragSetup(letterS,allTargets);
dragSetup(letterT,allTargets);
dragSetup(letterU,allTargets);
dragSetup(letterV,allTargets);
dragSetup(letterW,allTargets);
dragSetup(letterX,allTargets);
dragSetup(letterY,allTargets);
dragSetup(letterZ,allTargets);
dragSetup(letterAmpersand,allTargets);
Is there any code to duplicate the movieclips that can be inserted into the above actionscript?
I would really appriciate and help that you may be able to offer me.
2009-06-15: Bill Trikojus said:Hi Darren,
I have already answered that one for JD up above.
cheers
2009-06-15: Darren said:Hi Bill
Thanks for that and the quick response. I tried pasting the code that you gave to JD and it worked fine but it won't go to the targets as it did before.
Do you know why? Many thanks.
2009-06-16: Jon said:Hi Bill
I'm hoping to add a reveal button and a reset button that would reset everything but also randomise the start position of the drags (i Have six drags). Could you advise on this?
Thanks in advance :-)
JJ
2009-06-17: Stan said:hi, i was wondering how i would make it so that when the circle gets to the target it can no longer be dragged out again
2009-06-18: Bill Trikojus said:Stan - turn events off by setting them to null
eg
this.onPress=null;
JJ - I don't know what you want to reset but the random position is easy
function reset(){
drag1_mc._x=Math.random()*Stage.width;
drag1_mc._y=Math.random()*Stage.height;
//other stuff
}
cheers
2009-06-24: Darren said:Hi Bill
Further to my earlier posting, other that my movieclips of the letters not snapping to the targets, if the movieclips are returned to their original position you can't then move them again. They just go back to the start position. Any ideas?
Post a comment
Garbage posts and SPAM will be deleted.