Flash Drag and Drop

Creating drag and drop functionality in Flash CS3 is quite different than in older versions if you’re using the new ActionScript 3.0. While still relatively straightforward, the code can be a little more intimidating to users who are less familiar with ActionScript programming. If you’re like me, you’re here to try to keep your knowledge up-to-date, so let’s learn how to create a simple ActionScript 3.0 drag and drop game step-by-step. Download the FLA and follow along with these steps.

Setting up the Flash file

Open dragdrop.fla and review its organization. There are five layers in the file – one containing the “pegs” that we will drag and drop, one for the “targets” that we will drop the shapes onto, and one for the wooden box image. The text layer and the actions layer are currently empty. The pegs and the targets are movieclip symbols saved in the library. Press CTRL-L to view the library.

1. Create a dynamic text field to display the right or wrong responses on the text layer.

In order to provide the user with some feedback, we will display a message when the shapes are dropped, indicating whether or not they were placed successfully. Click frame 1 of the text layer. Use the Text tool to draw a text box underneath the peg shapes. Type “Put the shapes away!” to give the box an initial message.

Adding the dynamic text box.

Adding the dynamic text box.

In the Properties inspector, change the text box to a Dynamic Text box using the drop down menu. Set the font to Arial bold, the font color to #990000, and the size to 18pt. Give the text box an instance name of “reply_txt“. Use the Selection tool to position the text box if necessary.

Setting the properties of the dynamic text box.

Setting the properties of the dynamic text box.

2. Assign instance names to the peg and target movie clips.

In order to determine which target we drop our shapes over, we need to name them. Click the bright green pentagon target on the stage, and in the Properties inspector, give it an instance name of “targetpentagon_mc“. Repeat the process, giving the other three green targets instance names of “targetsquare_mc“, “targettriangle_mc“, and “targetflower_mc“. Take special note of the lowercase values – this will be important later.

Click the red square peg on the stage and give it an instance name of “square_mc“. Repeat the process, giving the other three colored pegs instance names of “flower_mc“, “triangle_mc“, and “pentagon_mc“.

Adding an instance name to the pentagon target.

Adding an instance name to the pentagon target.

Why are the targets so small?
The targets are smaller than the holes on the toy to provide a little more accuracy. Smaller targets mean that the shape has to be more closely lined up to register as a match.

3. Adjust the targets to make them invisible.

Since the appearance of bright green targets spoils the illusion of a child’s toy, we will make them transparent. Using the Selection tool, click the first green target. Then, holding down Shift on the keyboard, click to select the other three targets. In the Properties inspector, choose Alpha from the Color dropdown menu. Then set the Alpha value to 0, making the targets transparent.

Setting the alpha value of the targets to zero.

Setting the alpha value of the targets to zero.

Adding Drag and Drop functionality

Now it’s time to dive into the code. Since ActionScript 3.0 no longer uses onPress and onRelease events, we’ll need some new code to create the same effect.

4. Add ActionScript to make the red square dragable.

We’ll write some ActionScript to allow us to drag and drop the square peg. Select frame 1 of the actions layer, and open the Actions panel by pressing F9. Type in the following actions:

square_mc.addEventListener(MouseEvent.MOUSE_DOWN, pickUp);
square_mc.addEventListener(MouseEvent.MOUSE_UP, dropIt);
function pickUp(event:MouseEvent):void {
    event.target.startDrag(true);
}
function dropIt(event:MouseEvent):void {
    event.target.stopDrag();
}
square_mc.buttonMode = true;

Adding the drag and drop Actionscript.

Adding the drag and drop Actionscript.

This tells Flash to begin dragging the movie clip when the user presses the mouse button, and stop when the mouse is released. In ActionScript 3.0, this is created by setting an event listener for each event, MOUSE_DOWN and MOUSE_UP, and assigning event handler functions (here called pickUp and dropIt) to tell Flash what to do once the event is triggered. Within these event handlers, event.target refers to the object that initiated this event, which in this case will be square_mc. Using event.target instead of naming the object specifically will let us reuse this code for all four pegs in a few steps. The “true” parameter of the startDrag function causes the shape to be picked up from its center, which will make it easier to place later. To display the hand cursor when clicking movieclip symbols, we set the buttonMode property to true. Press CTRL-Enter to test the movie, and try dragging the square.

5. Add ActionScript to display a message in the text box when the peg is dropped.

Here is where we determine where we release the peg, and provide feedback. Add the following code just below event.target.startDrag(true);

reply_txt.text = "";

Adding this code inside the pickUp event handler will force the text inside the dynamic text field to clear when we pick up the peg.

Add the following lines below event.target.stopDrag();

var myTargetName:String = "target" + event.target.name;
var myTarget:DisplayObject = getChildByName(myTargetName);
if (event.target.dropTarget != null && event.target.dropTarget.parent == myTarget){
    reply_txt.text = "Good Job!";
} else {
    reply_txt.text = "Try Again!";
}

Adding conditional logic to give a proper response.

Adding conditional logic to give a proper response.

The first new line creates a text string from the word “target” plus the name of the peg we just dropped, creating a name that matches one of our targets, such as “targetsquare_mc“. The next line looks through our document for an object with that name, and saves a reference to it in a variable called “myTarget“. The if statement checks to make sure that the dropTarget, or the item that is under our shape when we release the mouse button, is not null, or empty. It also checks to see if the dropTarget’s parent is our myTarget . In other words, if we release square_mc over the movie clip named “targetsquare_mc“, we receive a positive reply. If the peg is released anywhere else, we will receive a negative reply.

Test the movie by pressing CTRL-Enter. Try clicking the square and dragging it over an incorrect hole in the toy. Now, try dropping it over the correct hole. Check your code and fix any errors you encounter.

6. Use similar ActionScript to activate the other three pegs.

Copy the event listener lines from the Actions panel and paste them three more times. Change each reference of square_mc to flower_mc, triangle_mc, and pentagon_mc, respectively. Do the same for the buttonMode line for each of the pegs. Since the event handler functions use references to event.target, there is no need to modify any other sections for it to work with all four pegs.

Copying and pasting the event listeners for the other three pegs.

Copying and pasting the event listeners for the other three pegs.

Press CRTL-Enter to test the movie. Try dragging each of the pegs into both incorrect and correct places on the toy. You should receive the correct messages each time.

Bring the selected peg to the top

Currently, if you drag the yellow triangle, it passes over the square, but underneath the pentagon and flower shapes. That’s because they were added to the Flash document in a specific order, and the newest objects end up on top in the stacking order. ActionScript 3.0 no longer uses depths when placing objects, as the z-index is handled automatically. In order to change the item’s z-index, we’ll use the addChild() method.

7. Use addChild() to increase the peg’s stackin order

We want to set the peg’s depth higher each time we drag it so that it will drag above the others. Add the following code within the pickUp() event handler, after the line reply_txt.text = "";

event.target.parent.addChild(event.target);

In this line of code, event.target.parent refers to the main timeline. Using addChild(event.target) essentially adds the currently selected peg to the stage at the top of the stacking order, creating the appearance that we’ve picked it up above the others. Press CTRL-Enter to test the movie. As you drag each piece, it should always remain on top of the others.

Locking pegs that have been placed correctly

Once the user has placed a peg in the right hole, it is a good idea to “lock” it into place so that they can’t accidentally move it again. We’ll also make sure that the peg is perfectly positioned when it is released.

8. Remove the event listeners when a peg is correctly placed.

Once a peg is placed, the easiest way to ensure that we can’t move it again is to remove the event listeners, and set buttonMode back to false to remove the hand cursor. Add the following code within the dropIt() event handler, within the if statement, immediately after the line, reply_txt.text="Good Job!";

event.target.removeEventListener(MouseEvent.MOUSE_DOWN, pickUp);
event.target.removeEventListener(MouseEvent.MOUSE_UP, dropIt);
event.target.buttonMode = false;

Removing the event listeners and buttonMode.

Removing the event listeners and buttonMode.

When a peg is placed over the correct target, the if statement returns true, and that peg will be locked and no longer dragable. Test the movie with CTRL-Enter and see for yourself.

9. Adjust the peg’s position when it is correctly placed

We should also make sure that once a peg is placed, it fits perfectly over the target. Add the following code immediately under the code you just added:

event.target.x = myTarget.x;
event.target.y = myTarget.y;

This will set the dropped peg’s x and y coordinates to match those of the target movie clip. Note that in ActionScript 3.0, x and y properties no longer have an underscore. Test the movie with CTRL-Enter.

Resetting incorrectly placed pegs to their original position

Currently, if you drag and drop a peg to either the wrong place or an empty area of the screen, it just stays there until you drag it again, which can be a little confusing. Let’s make each peg snap back to its original spot if it’s placed incorrectly.

10. When clicked, record the peg’s starting position

Since we’ll need this information within two event handlers, let’s set up a pair of variables. Add the following code to above all the rest in the Actions panel:

var startX:Number;
var startY:Number;

This creates two variables, startX and startY, that will contain our starting position. For now, they’re empty. When we pick up the shape, we’ll record its coordinates. Add this next code within the pickUp() event handler:

startX = event.target.x;
startY = event.target.y;

11. If the peg is released outside of its target, reset its x and y position

Now that the starting position is recorded, we can use those values to reset the peg when we miss the target. Add the following code within the dropIt() handler, within the else statement:

event.target.x = startX;
event.target.y = startY;

Recording and resetting the peg's starting position.

Recording and resetting the peg’s starting position.

This will reset the x and y properties to their original values, but only when we release the shape outside of its target. Test your movie with CTRL-Enter, and drag the square to an incorrect space. It should snap back to its starting position.

Using a counter to determine when the user is finished

Let’s add a congratulatory message that tells the user that all pegs have been placed correctly. We’ll need to keep a count of each correct peg drop, and when the count reaches four, we’ll change the text message.

12. Create a global counter variable

Since the counter will keep track of all four pegs, we will create a variable in the actions layer. Add the following code above all of the other code in the actions panel:

var counter:Number = 0;

13. Increment the counter variable each time a peg is correctly placed

We will add one to the counter variable each time we release a peg over the right target. Add the following line of code within the dropIt() event handler, within the if statement:

counter++;

Adding the counter increment to the dropIt() event handler.

Adding the counter increment to the dropIt() event handler.

This will add one to the value of the counter variable when the square peg is placed correctly.

14. Check the counter and update the text when it reaches four

Add the following code within the dropIt() event handler, making sure that it comes after the else statement:

if(counter == 4){
    reply_txt.text = "Congrats, you're finished!";
}

Checking the counter variable, and congratulating the user.

Checking the counter variable, and congratulating the user.

This checks the counter variable’s value, and if it equals 4, it will change the text in the dynamic text field to read, “Congrats, you’re finished!”.

If you have JavaScript enabled, you will see the completed project here.


Here’s a look at the completed code.

var counter:Number = 0;
var startX:Number;
var startY:Number;
 
square_mc.addEventListener(MouseEvent.MOUSE_DOWN, pickUp);
square_mc.addEventListener(MouseEvent.MOUSE_UP, dropIt);
triangle_mc.addEventListener(MouseEvent.MOUSE_DOWN, pickUp);
triangle_mc.addEventListener(MouseEvent.MOUSE_UP, dropIt);
flower_mc.addEventListener(MouseEvent.MOUSE_DOWN, pickUp);
flower_mc.addEventListener(MouseEvent.MOUSE_UP, dropIt);
pentagon_mc.addEventListener(MouseEvent.MOUSE_DOWN, pickUp);
pentagon_mc.addEventListener(MouseEvent.MOUSE_UP, dropIt);
 
function pickUp(event:MouseEvent):void {
    event.target.startDrag(true);
    reply_txt.text = "";
    event.target.parent.addChild(event.target);
    startX = event.target.x;
    startY = event.target.y;
}
function dropIt(event:MouseEvent):void {
    event.target.stopDrag();
    var myTargetName:String = "target" + event.target.name;
    var myTarget:DisplayObject = getChildByName(myTargetName);
    if (event.target.dropTarget != null && event.target.dropTarget.parent == myTarget){
        reply_txt.text = "Good Job!";
        event.target.removeEventListener(MouseEvent.MOUSE_DOWN, pickUp);
        event.target.removeEventListener(MouseEvent.MOUSE_UP, dropIt);
        event.target.buttonMode = false;
        event.target.x = myTarget.x;
        event.target.y = myTarget.y;
        counter++;
    } else {
        reply_txt.text = "Try Again!";
        event.target.x = startX;
        event.target.y = startY;
    }
    if(counter == 4){
        reply_txt.text = "Congrats, you're finished!";
    }
}
 
square_mc.buttonMode = true;
flower_mc.buttonMode = true;
triangle_mc.buttonMode = true;
pentagon_mc.buttonMode = true;

Download the source FLA.

Categories

Upcoming Classes