How to drag movie clips using Adobe Flash and ActionScript 2.0

Project Critique

For our first project critique, I would like you to pair up with someone else in the class and spend some time playing their game, then fill out the project critique sheet that I have provided. You will be expected to introduce the game to the class, then comment on three things that your project partner did well and three things that you think could be improved. We will also be voting on who the class believes the best project belongs to (You will be voting on which projects you think are first, second and third place). If there is an odd number of folks turning in projects, then someone will have to be in a group of three.

Character Dressup Game

Our next project will be technically less of a challenge, but creatively more complicated. We're going to be creating a character dressup game, which can be done in two ways. You can create a character that you dress up with different clothes or you can create a Mr. Potato type game where the character has different body parts.

Take a look at this elephant dressup mini-game:

You'll notice that you can drag the t-shirts and move them on top of the elephant.You can either draw your own character or use photographs. To use photographs, you'll have to save the photos as transparent .pngs so that the photos don't have a white background. If you decide to go that route, let me know and I'll help you do this in Photoshop.

Let's look at the code in Flash for dragging a movie clip. Open up Flash and create a simple movie clip. Click on the movie clip and insert the following code:

on(press)
{
    startDrag(this);
}

Test your movie clip and you'll see that if you click on the clip it will follow the mouse. startDrag takes the parameter (this) becauseThat works great, but we need a way to make drop the movie clip. We'll need to add another event handler for this:

on(release)
{
     stopDrag();
}

Notice that the startDrag() method requires at least one parameter which tells it which clip you want to start dragging, but the stopDrag() method requires no parameters. You can only drag one item at a time in Flash, so the stopDrag method doesn't need to know which clip you want to stop moving, it simply stops dragging any clip that is currently being dragged.

Multiple Items

Now draw a second object on the screen and make that into a second movie clip. Copy the code from the first movie clip into the movie and test the movie. You should be able to drag both movie clips aroudn on the screen. But you'll notice that one movie clip always remains on top of the other movie clip.

Flash Depths

We need to find a way to switch the layer order of the movie clips. To do that, we can use the swapDepths command. Change both of the movie clips code to the following.

on(press)
{
    this.swapDepths(100);
    startDrag(this);
}
on(release)
{
    stopDrag();
}

Flash places all items that are drawn on a certain invisible layer system that is like a deck of cards.Each movie clip and item that Flash draws gets assigned a depth number. Higher positions appear on top of lower positions. You can find out what the depth of any movie clip is by using the getDepth() method like this.

onClipEvent(load)
{
    trace(this.getDepth());
}

If you do that on one of the movie clips, you'll notice that you'll probably get a negative number, I got something like -16383. The depth can be an integer between -16383 and 1048575. Depths above -1 are reserved for dynamically generated content (which you'll learn soon enough when you load movie clips into Flash). Depths below -1 are generally reserved for content that Flash creates itself.

The swapDepths command forces an object to a specific depth. Only one object can be in a specific depth at the same time, so if you tell a new object to swapDepths() to a depth that already has an object in it, the old object will swap depths with the new object. In our example above, we assign a level of 100 to the two objects we drew whenever someone clicks on them. If one of the objects is already at depth 100, we swap the new object's depth with it. This has the effect of bringing any object we press on to the front of the other object.

It's critical to understand depths when working with Flash because they are essential to loading dynamically generated content.

Loading an object into a specfic layer

If you go back to my little elephant example, you'll notice that the trunk and the tusks of the elephant always remain in the front. This was accomplished by using the swapDepths command on an onLoad handler. I created one movie clip for the body of the elephant, one movie clip for the trunk and tusk and added this script on the trunk/tusk combo:

onClipEvent(load)
{
this.swapDepths(2000);
}

Now when the trunk/tusk combo movie clip loads, Flash puts it in layer 2000. I'm not putting anything else in layer 2000, so it should be pretty safe to put it there. Keep this in mind when you're building the game because there might be some items that you want in front of others.

Using the _droptarget property

You can use the _droptarget property to figure out if an item has been dropped on top of another one. Think of it as a version of the hitTest. In my example, I've used it make the t-shirts snap back into place when they are not dropped on top of the elephant.

Change the code on your movie to this:

on(press)
{
     this.swapDepths(100);
     startDrag(this);
}
on(release)
{
     trace(this._droptarget);
     stopDrag();
}

Now test the movie and drag one of the items on top of the other one. When you drop the item, you should see the instance name of what you dropped the movie on in the output window. You'll notice that the name has a slash "/" at the beginning of it. This is what's known as slash notation. It's an older type of notation used in earlier versions of flash.

Flash considers the registration point of the movie clip as the test for wether one clip was dropped on top of another one. Because of this it might be convenient to modify the startDrag command to automatically position the movie's registration point in the mouse location. To do this, we simply add true to the startDrag command like this:

on(press)
{
this.swapDepths(100);
startDrag(this,true);
}
on(release)
{
trace(this._droptarget);
stopDrag();
}

In order to snap an item back to it's original position, we'll need to keep track of the original position this item was loaded in. For that we'll need an onClipEvent (load) like this:

onClipEvent(load)
{
    originalx=this._x;
    originaly=this._y;
}
on(press)
{
    this.swapDepths(100);
    startDrag(this,true);
}
on(release)
{
    trace(this._droptarget);
    stopDrag();
}

Now we can check with an if then statement to see if this item was dropped on top of another item, if it wasn't, we can reset it's position to the original settings.

onClipEvent(load)
{
    originalx=this._x;
    originaly=this._y;
}

on(press)
{
     this.swapDepths(100);
    startDrag(this,true);

}

on(release)
{
     if (_droptarget<>"/circle")
        {
            this._x=originalx;
            this._y=originaly;
        }
    stopDrag();
}

Other Stuff

You'll notice on my game, I've made the t-shirts change size when they are being dragged. I accomplished that with the _xscale and _yscale properties of the movie clips. See if you can figure out how it was done.

Review

The test will have about 20 questions, multiple choice, fill in the blank and true/false. You will be expected to write code and interpret it properly.

blog comments powered by Disqus