< Day Day Up >
Dragging and Dropping Movie Clip Instances
In user interfaces, it's sometimes useful to add drag-and-drop behaviors to movie clip
instances—a term that refers to the process of clicking and dragging movie clip instances
around the stage, so that when they're released (dropped), they'll perform a set of actions
determined by the location where they're dropped. The easiest way to conceptualize this
type of behavior is by thinking of the trashcan icon on your computer desktop: If you
drag a file over the trashcan and let go of it, that file is deleted; however, if you're not
over the trashcan when you let go, you've simply moved the file icon.
The most common way to create drag-and-drop items in Flash is by using _droptarget or
hitTest(). Accessing the _droptarget property of a movie will return the path in slash
syntax to the highest movie clip instance that the currently dragged movie clip instance is
over. Using the hitTest() method, you can determine whether the bounding box of one
instance is touching the bounding box of another and take action accordingly. For more
on this topic, see Lesson 8
, "Using Conditional Logic." The hitTest() method is used
more frequently because it's more versatile than the _droptarget property.
In this exercise, you'll extend your project to dynamically create a row of icons—simple
graphical movie clip instances—that can be dragged and dropped onto the canvas_mc
movie clip instance using hitTest(). When dropped, a copy of the movie clip instance will
be created using duplicateMovieClip() and the original will be sent back to its initial
position.
1. Open draw3.fla.
This file is as you left it at the end of the preceding exercise. You will continue to
add ActionScript to the _root timeline in this exercise. You'll create a function that
creates the row of icons below the canvas_mc movie clip instance. Then you'll add
the ActionScript that makes them draggable and the ActionScript that detects
whether they were dropped onto canvas_mc.
2. With the Actions panel open, select Frame 1 of the Actions layer and add the
following function:
3.
4. function buildIconList() {
5.
6. var spacing:Number = 85;
7.
8. var iconY:Number = 360;
9.
10. var iconX:Number = 70;
11.
12. for (var i = 0; i < _root.icon_mc._totalframes; ++i) {
13.
14. var newName:String = "icon_mc" + i;
15.
16. var clip:MovieClip = _root.icon_mc.duplicateMovieClip(newName, 10000 + i);
17.
18. clip.gotoAndStop(i + 1);
19.
20. clip._x = iconX + i * spacing;
21.
22. clip._y = iconY;
23.
24. clip.homeX = clip._x;
25.
26. clip.homeY = clip._y;
27.
28. clip.icon_btn.onPress = function() {
29.
30. startDrag(this._parent);
31.
32. };
33.
34. clip.icon_btn.onRelease = function() {
35.
36. stopDrag();
37.
38. _root.iconReleased(this._parent);
39.
40. };
41.
42. }
43.
44. }
45.
Although this function is fairly large, there's nothing here that you haven't seen
before. The icon_mc movie clip instance contains a certain number of frames on
its timeline, each of which includes a different icon graphic. This script duplicates
the icon_mc clip once for every frame in that movie clip. It sends each duplicated
movie clip instance to a unique frame and aligns it along the bottom of the screen.
The result is a row of icons at the bottom of the screen. You can add or remove
icons (that is, add or remove frames) in the icon_mc movie clip instance, and this
loop will adapt based on the _totalframes property used in the for loop. The
spacing variable represents the vertical space between the duplicated icons. iconY
and iconX represent the coordinates of the first duplicate.
Each new movie clip instance stores the variables homeX and homeY. Those
variables represent the position on the stage where the movie clip instance is
initially placed when created and where it snaps back to after being dragged and
dropped.
The icon_mc movie clip instance as well as its duplicates contains a button
instance with a name of icon_btn. The last section of this function adds onPress
and onRelease event handlers to that button instance inside each of the duplicates.
The onPress event handler tells the movie clip instance that's holding the button to
begin dragging when the button is clicked. The onRelease event handler tells the
movie clip instance to stop being dragged, and calls the iconReleased() function
when the button is released. The iconReleased() function, which will be defined in
a moment, checks whether the movie clip instance was dragged onto the canvas. If
so, the function creates a duplicate of that instance on top of the canvas and then
places the original instance back at its original position. For the iconReleased()
function to know which icon instance to duplicate, it's passed a reference of the
instance that was just dragged and dropped.
3. Add this code at the bottom of the frame:
4.
5. buildIconList();
6.
This will call the function you created in Step 2 to create the icon list.
4. Add the following function at the end of Frame 1:
5.
6. function iconReleased(icon:MovieClip) {
7.
8. if (_root.canvas_mc.hitTest(_root._xmouse, _root._ymouse)) {
9.
10. ++iconDepth;
11.
12. var newName:String = "object" + iconDepth + "_mc";
13.
14. var clip:MovieClip = icon.duplicateMovieClip(newName,iconDepth);
15.
16. clip.gotoAndStop(icon._currentFrame);
17.
18. clip.icon_btn.enabled = false;
19.
20. clip._xscale = 250;
21.
22. clip._yscale = 250;
23.
24. }
25.
26. icon._x = icon.homeX;
27.
28. icon._y = icon.homeY;
29.
30. }
31.
This function is set up to receive one parameter, which is identified as icon. This
parameter is a reference to the icon movie clip instance that has just been dragged
and dropped. The value of this parameter plays an important role in how the rest of
the function works.
A conditional statement checks whether the mouse pointer is over the canvas_mc
movie clip instance when the function is called, indicating that the icon has
actually been dropped on the canvas. If the mouse pointer is over canvas_mc, a
copy of the movie clip instance that's dragged and dropped is created using
duplicateMovieClip(). The name given to the duplicate is derived by
concatenating "object" with the current value of iconDepth (which is defined in
the next step, and is incremented with each new duplicate created) and adding
"_mc" to the end. Based on this functionality, the current value of iconDepth will
always reflect the number of duplicate icons that have been dragged and dropped
onto the canvas—an important thing to remember for the next exercise.
After it's created, the duplicate is sent to the same frame as the original instance so
that the same icon that was dragged appears on the canvas. The next action is used
to disable the invisible button inside the duplicate named icon_btn. In addition, the
duplicate is scaled vertically and horizontally by 250 percent so that it will appear
on the canvas as a larger representation of the icon instance from which it was
created.
NOTE
A duplicated instance inherits the exact x and y positions of the original at the time
of its duplication; therefore, unless you use a simple script to move it, a
duplicate—upon its creation—is placed right on top of the original. This means
you won't be able to tell that a duplicate has been created because nothing will
have changed visually.
The last two lines of ActionScript in this function send the dragged movie clip
instance back to its original position, based on the values of homeX and homeY on
its timeline. Notice that these actions are placed outside the conditional statement,
meaning that they're executed regardless of whether the statement proves true and
a duplicate is created. If the user tries to drop an icon anywhere other than on top
of the canvas_mc movie clip instance, no duplicate will be created, and the icon
will simply snap back to its original position below the canvas.