AS3 Easy Dynamic Movie Clip Buttons

Back in 2007 I posted a tutorial explaining how to dynamically create movie clip buttons using AS2. I received a lot of feedback on it including some great questions, like “How can I auto-select a button?” and “Can you do this in AS3?”. Like the Clickable Button in a Draggable Clip app that I re-coded in AS3, I felt that recoding this app could be a good exercise that would offer an introduction to some basic, frequently-used techniques for someone learning AS3.

Download the source

The first upgrade I made was to take the code out of the timeline and place into a Document class. The Document class is a class that will execute when your application starts. In most cases it extends the main timeline, which is a MovieClip. You define your Document class in the "Document Class" field of the Property Inspector when nothing is selected. It can also be defined in the ActionScript 3 Settings section of your Publish Settings ( File > Publish Settings > [Flash] > Settings > Document Class.

There are plenty of reasons to like the Document class but one of my favorites is that it allows me to code in the FlashDevelop IDE rather than in the confining embrace of the Flash IDE code editor. If you're a PC user and you've never seen FlashDevelop you should check it out.

A few things to remember about the Document class that differ from the timeline method:
1) The Document class is a Class like any other that must follow the correct syntax. You must include the package (folder) and define it as an extension of a Display Object ( public class CustomDocument extends MovieClip ).
2) You need to include the classes required to support the objects that you are using. For example, if you are using a TextField you must import flash.text.Textfield.
3) If you are referencing any objects that exist on the stage from your Document Class you must define a variable for that object. For example, because my application has a text field in the first frame with an instance name of fullMonth_txt, I must declare that variable in my Document class ( public var fullMonth_txt:TextField; )

If you don't think you're ready to start using a Document class, have no fear, I modified the code on the timeline too. Just uncomment it and remove the Document Class reference and you're good to go old-school!

When the application starts it stops the main timeline, then proceeds to loop through the array of months that I declared earlier:

private var month_array:Array = new Array ({month:"JAN",fullNm:"January"},{month:"FEB",fullNm:"February"},...;
...
for (var a:Number = 0; a < month_array.length; a++) {
	container_mc = new MovieClip();
	button_mc = new ButtonMC();
	addChild(container_mc);
	container_mc.addChild(button_mc);
	container_mc.x = nextX;
	container_mc.y = nextY;
	button_mc.month_txt.text = month_array[a].month;
	button_mc.monthName = month_array[a].fullNm;
	button_mc.mouseChildren = false;
	...

ButtonMC is a class that was created dynamically by Flash using the button_mc movie clip in the library. You can do this for any movie clip simply by going into its properties and clicking "Export for ActionScript."

For every month, a new instance of my button is placed on the stage. The month abbreviation is used to update the dynamic text field inside the button named month_txt. The full month name is stored as a dynamic property of the button. This will be used to populate the fullMonth_txt text field when the button is clicked.

"button_mc.mouseChildren = false;" tells the player to ignore any children of button_mc for mouse actions. Without this line the mouse events would not work if the user were to hover over the button text. This drove me batty for a while!

Next is the code that will set the current month's button to the selected state. If you don't want a button to be selected at startup just get rid of this code:

private var today:Date = new Date();
private var thisMonth:Number = today.getMonth();
...
if(a == thisMonth) {
	button_mc.gotoAndStop("selected");
	selectedButton = button_mc;
} else {
	button_mc.stop();
}
</code></pre>

When I declare the variable thisMonth above, I set it to the number of the current month. Because month numbering starts with 0, it will align perfectly with my loop through the months array. Therefore, when 'a' (the loop index) equals 'thisMonth', that button is set to the selected state.

Next I assign the mouse event listeners. This is how you code button functionality in AS3. The listeners will be responsible for calling the appropriate function when a mouse event takes place:

button_mc.addEventListener(MouseEvent.CLICK,buttonClick);
button_mc.addEventListener(MouseEvent.MOUSE_OVER,buttonOver);
button_mc.addEventListener(MouseEvent.MOUSE_OUT,buttonOut);
button_mc.addEventListener(MouseEvent.MOUSE_DOWN,buttonDown);

For example, when the mouse clicks button_mc it will fire the buttonClick function. The buttonClick function takes the event as a parameter and executes its code which populates the Month Name text field (fullMonth_txt), moves the previously selected button to the active state, moves itself to the selected state, and assigns itself as selectedButton.

private function buttonClick(evt:MouseEvent):void {
	fullMonth_txt.text = evt.target.monthName;
	if(selectedButton && (selectedButton != evt.target)) {
		selectedButton.gotoAndStop("active");
	}
	selectedButton = evt.target;
	evt.target.gotoAndStop("selected");
}

The selectedButton Movie Clip that I declared at the top of the Document class always holds a reference to the selected button. The target of the event (evt.target) is the object that was clicked. That's how one function can handle the changes for any button without having to poll all buttons for their states every time a new button is selected.

There's a little more in the actual code but those are most of the key points. If you find this post useful, be sure to check out my previous post, AS3 Clickable Button Inside a Draggable Movie Clip .

If you missed the link to the example above, you can download it here.

-Glenn

4 thoughts on “AS3 Easy Dynamic Movie Clip Buttons

  1. hi rabidgadfly. Thanks for this AS3 code which I have just used successfully in one of my projects.

    Any ideas how you would remove the dynamically generated buttons (button_mc) or (container_mc) which the reside in.

    I have tried removeChild(button_mc), but this does not work. Im guessing AS3 holds them under a different name in memory?

    Cheers

    Andrew

  2. Thanks a lot for this…
    I have been having issues with the “export to actionscript” feature and now I finally understand WTF is going on with it…
    Your example provided the key I needed to understand how to create dynamic items (versus pre-placing them directly on the stage).

    Kudoos to you.

Comments are closed.