Easy Button States for Movie Clip Buttons

Flash ActionScript 2.0

You may have heard that movie clip symbols can be “turned into buttons,” or made to act like buttons, and they certainly can.  In the most basic sense, all it takes is a few lines of ActionScript to handle the mouse-related events supported by the MovieClip class; namely, onPress, onRelease, onRollOver, and the like — just like the Button class. 

// a button symbol
myButton.onRelease = function() {
  // something that occurs when the button is released
}

// a movie clip symbol
myMovieClip.onRelease = function() {
  // something that occurs when a movie clip “button”
  // is released
}

But what’s the point?  Why would someone want to use movie clip symbols as buttons?  After all, buttons have those special “state” frames, Up, Over, Down, which automatically change the button visually in response to mouse interaction, and also the Hit frame, which determines the surface area available to the mouse. 

True enough, movie clips don’t have that.

But then, buttons don’t have nearly the number of properties, methods, or events that movie clips do.  You can’t programmatically send a button to one of its own frames (think MovieClip.gotoAndStop() or MovieClip.gotoAndPlay()), so those four special state frames could be argued as a limitation, rather than a benefit.  For example, if you wanted to create a Toggled state (a custom fifth frame), a button symbol provides no way to direct the playhead of its timeline.  You can’t run MovieClip.hitTest() on a button — which tests for an overlap, or “collision,” with another movie clip or some geometric point, such as the coordinates of the mouse — because the button class doesn’t feature a hitTest() method.

Frankly, these limitations may not bother you.  There’s certainly nothing wrong with button symbols.  I use them all the time, because they’re quick and easy.  But if you’re interested in pushing the boundaries, Flash provides a simple means to give movie clips three of the four button hit states.

In the timeline of your movie clip “button,” create three distinct keyframes, then use the following frame labels for each:  _up, _down, and _over (note the underscores).  Your movie clip can have these labels in a layer of their own or combined with the artwork.  Put a stop() action in frame 1, also in its own layer (or not), and you’re good to go.  Your movie clip will respond visually — assuming each frame has its own artwork — just like a button.  Actually, there’s one more requirement:  to kick this frame label approach into gear, you do have to handle at least one mouse-related event (onRelease, for example, as shown above).  Buttons respond without being wired up, but movie clips need the instruction.

Movie clip 'button'

To add the equivalent of a button’s Hit frame, add a new layer inside the movie clip’s timeline and place a movie clip in that layer.  This new movie clip represents the clickable surface area you would have placed into the Hit frame of a button symbol.  Whatever shape this second movie clip has, and wherever it’s placed, determines what area of your movie clip “button” is responsive to the mouse.

In button symbols, artwork in the Hit frame is never seen, so you’ll have to hide the new “hit area” movie clip inside your movie clip “button.”  Give it an instance name — hit will do — and supplement the existing stop() action with …

hit._visible = false;
this.hitArea = hit;

That first line sets the MovieClip._visible property to false for the hit clip, and the second line sets the MovieClip.hitArea property to the hit clip.

Movie clip 'button' with hit area

In the figure, the square is the “hit area” clip, and its instance name is hit (though you may call it what you like; just make sure to update the ActionScript, if you do).  Now you have an object with all the functionality of the MovieClip class that behaves visually like a button symbol, complete with a custom hit area.

9 Responses to “Easy Button States for Movie Clip Buttons”

  1. josh Says:

    I am curious about nesting a button inside of a move clip. The movie clip has an onRollOver event action on it. Which tells the playhead to go to a frame label. Once that frame label is played there is a button on that timline….as you may guess my mouse never sees the button inside the mc.

    I have seen tutorials that are for me very confusing. Would you be willing to assist me? I can send you the fla if you could help I would be grateful.

    Josh

  2. David Stiller Says:

    Josh,

    You’re running into a limitation of mouse-related events in ActionScript 2.0. If your movie clip already has an onRollOver event in place, then you can imagine a kind of “force field” on that movie clip. Since that button is inside the movie clip — under that force field, so to speak — mouse-related events for the button never make it to the surface.

    There are a number of ways to work around this limitation, but the easiest I can think of is to get rid of that onRollOver event on the parent movie clip. Instead, put a new movie clip or button inside that parent in frame 1 of its timeline. Handle the onRollOver even on that inner movie clip/button. That way the parent movie clip won’t overshadow the events handled on that later button.

  3. Scott Says:

    I’m having a similar problem as Josh, I have a dynamic text field contained within the movie clip which has htmlText enabled - unfortunately, I can’t click on any of the links because of the “force field” you mentioned.

    Due to what I need the flash program to do, I can’t put the onrollover inside the movie clip. Is there a way to disable this “force field” without causing the rollover/rollout functions to stop working?

  4. David Stiller Says:

    Scott,

    I hope this force field metaphor doesn’t catch on, because it possibly obscures what’s really happening. ;) There is a way to enable and disable mouse events (in fact, any events) for objects that support them. If you’re using on() or onClipEvent(), you’ll have to ditch those in favor of the event handling mechanism introduced back in Flash MX (see my “Museum Pieces” article for details).

    When you’re handling events with dot notation, you can simply toggle that movie clip’s enabled property or even use delete to get rid of its event handler function altogether, then set it back again later. You’ll see an example of that sort of think the article I linked to.

  5. Scott Says:

    Hi David,

    I have been using the “.onRollOver = function()” functions for this flash item - it’s really starting to annoy me now! I’ve uploaded the source code to : http://www.kdwebserver.co.uk/~sericaen/preview/src/fla/map.fla

    If you could have a quick look at it I’d be extremely grateful! At the moment the links are in the last frame in the popupTop movie clip. If possible, could you send a reply to the email address that I posted this message with?

    Thanks in advance!

    Scott

  6. nidhi Says:

    hi
    i have attached a movieclip on rollover of another movieclip.i want to make that attachment moveable as i move over the movie clip same as we can do in button in the over state.

    thanks in advance

  7. David Stiller Says:

    nidhi,

    The basic approach I would use is this. Create an onRollOver event handler for the stationary movie clip that does the following: a) attaches the other movie clip and b) assigns an onMouseMove event handler to the attached movie clip. The onMouseMove event should set the attached clip’s _x and _y properties to the _xmouse and _ymouse properties of the main timeline (_root would be fine). If you need the attached movie clip to later go away, I would create an onRollOut event handler for the stationary movie clip that cancels the onMouseMove then removes that clip.

    The exact syntax would, of course, depend on your usage of AS2 or AS3. If you wanted to get fancy, you could even attach the new clip once, then leave it attached and toggle it between visible and invisible in order to avoid having to re-attach it later.

  8. Gary Says:

    Is there a way to have the button go to another scene, but also play an animation?? I have the action script calling the frame label that I want but it’s not letting me go to the scene that i want it to go to. Again any help or suggestions will be appreciated. I also find your site to be very helpful thank you for having this site.

  9. David Stiller Says:

    Gary,

    I’m not 100% sure I understand your question. For sake of clarity, it’s not a button, per se, that causes an animation to play; it’s the playhead itself. If you’re sending the main timeline to a Scene and that Scene has animation, the animation will play, as long as you used gotoAndPlay(). I wonder if you’re running into the issue discussed in “Why Doesn’t _root.gotoAndPlay() work with Scenes“? Have you tried forgoing Scene names in favor of unique frame labels (unique globally, across all Scenes)?

Leave a Reply