30 votes, average: 4.73 out of 530 votes, average: 4.73 out of 530 votes, average: 4.73 out of 530 votes, average: 4.73 out of 530 votes, average: 4.73 out of 5
Loading ... Loading ...

Drag and Drop - Part Two

by Greg Lunn - February 11, 2007

I’ve decided to continue the Flash Drag and Drop tutorial and show several ways that you can improve on that example. Although the end product of the previous tutorial was functional, it lacked the polish necessary to use it in a real-world project. This tutorial will take a look at several techniques, including the swapDepths() method, and using the enabled property to lock dragable items. I’ll also show you a way to reset dragged items that are not placed successfully, and how to count correct answers with the purpose of displaying a congratulatory message.

If you haven’t already, please take a look at the previous tutorial. When you finish that example, you may continue with the same Flash file through the next steps here. You can also download the example files from this tutorial to pick up where the previous example leaves off.

Note: This tutorial is written in Actionscript 2.0 for Flash MX and up.
If you are using Actionscript 3.0 and Flash CS3, take a look at the updated version of this tutorial.

Using swapDepths() to bring each peg to the front

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. Dragging the objects simply moves them around on the x and y axes, so we’ll use the swapDepths() method to change their z-depth.

If you’re following along from the previous example, you’ll remember that we copied the code for the square and pasted it three times for the other pegs. Since the code for each peg is very similar, I’m only going to make the additions here to the code for the square movieclip. You’ll also want to copy and paste the same new code for the other three blocks.

1. Use swapDepths() to increase the peg’s stacking order

We want to set the peg’s depth higher each time we drag it so that it will drag above the others. Select frame 1 of the actions layer and press F9 to open the Actions panel. Add the following code within the square_mc.onPress() handler , after the line reply_txt.text = "";

this.swapDepths(this.getNextHighestDepth());

Adding the swapDepths() function in the Actions panel.

Adding the swapDepths() function in the Actions panel.

The swapDepths() function changes the peg’s z-index, and it expects a value. Rather than pass it a high number, however, we pass it this.getNextHighestDepth(), which is a Flash function that automatically returns the index of the highest element on the stage, plus one. As a result, the peg is dragged above the others.

Paste the same line of code in the same place within the blocks of code for the other pegs, and 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 use the movie clip’s enabled property to handle the task.

2. Set the peg’s enabled property to false when it is correctly placed

This one’s easy. All clickable items can be turned “on” or “off” by switching a property called enabled to “true” or “false”. When set to false, this property makes it impossible to click or drag the object. It even removes the hand cursor when you mouse over the shape.

Add this line of code within the square_mc.onRelease() handler, within the if statement, immediately after the line, reply_txt.text="...";

this.enabled = false;

That’s it! When the peg is placed over the correct target, the if statement is true, and the square will be disabled. Test the movie with CTRL-Enter and see for yourself. Afterwards, add the same line of code to the other pegs’ code blocks in the same location.

Reset incorrectly placed pegs to their original location

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 it’s original spot if it’s placed incorrectly.

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

First we need to know where the peg comes from, so we can send it back to the same spot. We’ll record the peg’s x and y coordinates in variables when we first click the object. Add the following code within the square_mc.onPress() handler:

xstart = this._x;
ystart = this._y;

This sets two variables, xstart and ystart, and assigns them the numerical coordinates of the peg at the moment that we click it.

4. 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 square_mc.onRelease() handler, within the else statement:

this._x = xstart;
this._y = ystart;

More code added to the actions of the red square movieclip.

More code added to the actions of the red square movieclip.

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. Repeat the same code again on all three other peg shapes.

Using a counter to determine when the user is finished

The last part we will add is 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.

5. 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;

6. Check the counter repeatedly and update the text when it reaches four

This movie has only one frame, but the Flash player actually repeats this same frame 12 times per second. We can use this to write a short function to check the counter variable each time, and adjust the text box when the counter reaches four. Add the following code in the Actions panel, below the variable you just created:

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

Actionscript on frame 1 of the Actions layer.

Actionscript on frame 1 of the Actions layer.

This creates a function that will run on every frame, or in this case, 12 times a second. The function 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!”.

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

Finally, 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 square_mc.onRelease() handler, within the if statement:

counter++;

Adding the counter increment to the Actions of the red square movieclip.

Adding the counter increment to the Actions of the red square movieclip.

This will add one to the value of the counter variable when the square peg is placed correctly. Add the same code to the other three pegs in the same place, and test your movie by pressing CTRL-Enter. When you complete the placement of all four pegs, you should see the “Congrats” message.

Adding sounds to the pegs

Extra credit time! Let’s add a cute sound to the pegs when they are properly placed. Begin by choosing a sound to use, in a format like .wav or .mp3. I’ve included my woodblock.wav in the example files.

8. Import the sound into Flash

Choose File > Import > Import To Library… Browse to and select woodblock.wav, and click Open.

9. Give the sound file an Actionscript linkage identifier

Open the library by pressing CTRL-L, if necessary. Find woodblock.wav, right-click it and choose Linkage… Check the box for “Export to Actionscript“, and give the item a linkage identifier of woodblock. This will let us call the sound with Actionscript, instead of placing it in the timeline.

Adding a linkage identifier to the sound clip.

Adding a linkage identifier to the sound clip.

11. Create a new Sound object, and play the sound at the right time

Add the following code in the Actions panel to frame 1, below the line var counter:Number = 0;

var woodSound:Sound = new Sound();
woodSound.attachSound("woodblock");

This code tells Flash that we would like to create a new sound object in memory, and attach the woodblock item from the library to that object. Now we can tell the sound object to play at the right moment.

Add the following line of code within the square_mc.onRelease() handler, within the if statement, after the line, counter++;

woodSound.start(0,1);

The start function takes two variables. The first tells Flash where to start playing the sound in seconds (zero means play from the beginning) and the second how many times to loop the sound. Press CTRL-Enter to test the movie. If the sound works when you drop the square, copy and paste the same line of code to the other three shapes. Remember to paste the same code into the Actions for the other pegs as well.

Good luck!

Download the source FLA.

Rate this tutorial

1 Star2 Stars3 Stars4 Stars5 Stars (30 votes, 4.73 out of 5)
Loading ... Loading ...