Drag and drop is a very intuitive way of interaction from the user. It’s a control scheme that is very easy get used to, and using it you can create many very interesting mechanics. In this tutorial, you will learn how to create drag & drop functionality using Flash actionscript.
There are two sections in this tutorial. The first section explains the tutorial for those using Adobe Flash, the second section explains Drag and Drop for FlashDevelop users.
There are actually many ways to achieve the drag and drop effect, but there are two methods that are used the most commonly. The first one is to use Flash’s built in startDrag() function, and the second one is to set the object position to the same as the mouse position. The first method is a tad bit simpler, but the second one has more advantages.
Here is an overview of what we want to achieve:
When you convert the above logic to code, you will see that it’s actually very simple. Create a MovieClip in Flash (or dynamically generate one), and instance name is something. I’m going to draw Circle and name mine circle_mc.
import flash.events.MouseEvent;
circle_mc.addEventListener(MouseEvent.MOUSE_DOWN,downf); circle_mc.addEventListener(MouseEvent.MOUSE_UP,upf);
function downf(e:MouseEvent) { circle_mc.startDrag(); }
function upf(e:MouseEvent) { circle_mc.stopDrag(); } |
The above code is in fact very simple, when clicked, startDrag, when released, stopDrag.
This position is a little more complicated, since you need to save the offset everytime if you don’t want your mouse to always align with the origin of you shape. The idea is to check if you are dragging the shape or not, and use and enter frame function to move the object if you are dragging it.
import flash.events.MouseEvent; import flash.events.Event;
circle_mc.addEventListener(MouseEvent.MOUSE_DOWN,downf); circle_mc.addEventListener(MouseEvent.MOUSE_UP,upf);
addEventListener(Event.ENTER_FRAME, update);
var dragging:Boolean; var offSetX:int; var offSetY:int;
function downf(e:MouseEvent) { dragging = true; offSetX = mouseX - circle_mc.x; offSetY = mouseY - circle_mc.y; }
function upf(e:MouseEvent) { dragging = false;
}
function update(e:Event) { if(dragging) { circle_mc.x = mouseX - offSetX; circle_mc.y = mouseY - offSetY; } } |
Both of these methods can apply to any shape or interactive object, but they do have their differences. For example, you can try changing the starDrag method’s frame rate to one, and the circle will still follow the math at a decent speed. With the EnterFrame method, you can only reach the top frame rate.
Why would you use one method over the other? It depends on your specific needs. If you want something frame rate independent, you should use the first method. If you want something that gives you more flexibility, use the second one.
The below example shows one use of the “more complicated method”
Changing the code a little will give you a whole new effect :
import flash.events.MouseEvent; import flash.events.Event;
circle_mc.addEventListener(MouseEvent.MOUSE_DOWN,downf); stage.addEventListener(MouseEvent.MOUSE_UP,upf);
addEventListener(Event.ENTER_FRAME, update);
var dragging:Boolean; var offSetX:int; var offSetY:int;
function downf(e:MouseEvent) { dragging = true; offSetX = mouseX - circle_mc.x; offSetY = mouseY - circle_mc.y; }
function upf(e:MouseEvent) { dragging = false;
}
function update(e:Event) { if(dragging) { circle_mc.x += (mouseX - offSetX-circle_mc.x)/10; circle_mc.y += (mouseY - offSetY-circle_mc.y)/10; } } |
You can also make a snap to grid effect my making a few modifications:
import flash.events.MouseEvent; import flash.events.Event;
circle_mc.addEventListener(MouseEvent.MOUSE_DOWN,downf); stage.addEventListener(MouseEvent.MOUSE_UP,upf);
addEventListener(Event.ENTER_FRAME, update);
var dragging:Boolean; var offSetX:int; var offSetY:int;
function downf(e:MouseEvent) { dragging = true; offSetX = mouseX - circle_mc.x; offSetY = mouseY - circle_mc.y; }
function upf(e:MouseEvent) { dragging = false; }
function update(e:Event) { if(dragging) { circle_mc.x = mouseX - offSetX; circle_mc.y = mouseY - offSetY; } circle_mc.x = Math.round(circle_mc.x/50) * 50; circle_mc.y = Math.round(circle_mc.y/50) * 50; } |
The source files of all these example are included at the end of this tutorial.
If you have seen the tutorial about using FlashDevelop, you might be using that IDE now. This section of the tutorial will show you how to implement the exact effects with FlashDevelop code.
If you don’t know how to import graphics into FlashDevelop yet, then you will have to use some code generated graphics. The examples below uses code generated graphics, but is very simple, just to show you how to do a drag and drop effect using the FlashDevelop work flow.
After you create an AS3 project in FlashDevelop, your Main class should look like this:
package { import flash.display.Sprite; import flash.events.Event;
/** * ... */ public class Main extends Sprite {
public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); }
private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); // entry point }
}
} |
Because you need to reference your drag and drop object, you will have to declare the variable in the class, out of the Main constructor. You may, however, instantiate and assign an instance of the object in your constructor.
package { import flash.display.Sprite; import flash.events.Event;
/** * ... */ public class Main extends Sprite { private var dragObject:Sprite;
public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); }
private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); // entry point trace("hello world"); dragObject = new Sprite(); dragObject.graphics.beginFill(0); dragObject.graphics.drawCircle(0, 0, 100, 100); addChild(dragObject); }
}
} |
Next, add in your event listeners, and define the functions within the same scope as your init and Main function. Note that you can create a function automatically by typing its name and pressing CTRL + SHIFT + 1.
package { import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent;
/** * ... */ public class Main extends Sprite { private var dragObject:Sprite;
public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); }
private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); // entry point trace("hello world"); dragObject = new Sprite(); dragObject.graphics.beginFill(0); dragObject.graphics.drawCircle(0, 0, 100); addChild(dragObject);
dragObject.addEventListener(MouseEvent.MOUSE_DOWN, downf); stage.addEventListener(MouseEvent.MOUSE_UP, upf); }
private function downf(e:MouseEvent):void { dragObject.startDrag(); }
private function upf(e:MouseEvent):void { dragObject.stopDrag(); }
}
} |
As you can see, drag and drop effects are fairly easy for both coding IDEs.
You can find the source project and flas here.
No portion of these materials may be reproduced in any manner whatsoever, without the express written consent of Entheos. Any unauthorized use, sharing, reproduction or distribution of these materials by any means, electronic, mechanical, or otherwise is strictly prohibited.