At the bottom of the event handler page, we looked at several examples of movieclip controls ("buttons") -- some with one frame and actionscript to control the look of the content in that frame on rollOver and rollOut, and some with multiple frames, each defining a different mouse state (up, over, down). Now we'll look at how to make a movieclip that not only changes on rollOver and rollOut, but looks different depending on which of two states it's in (on/off, play/pause, go/stop, etc).
If we're designing a control that can have two states, we need to keep track of which state it's in at any given time. The easiest way to do that is with a Boolean (true/false) variable. It can either be a variable on the main timeline (if we want to track the state globally), or a property of the control, or a property of the thing being controlled.
We also need to indicate to the user the state the control is in currently. This can be done with a one-frame control whose state is changed via actionscript (as in examples 1 and 2 below), or with a two-keyframe control whose state is changed via actionscript to gotoAndStop (or gotoAndPlay) the corresponding keyframe, as in example 3.
We'll look first at an example of the first way (variable on the main timeline). Get a copy of beegame_start.fla if you don't have one already (free download link at right). Delete bee2_mc from the stage. Rename bee1_mc to bee_mc. Add a control layer and drag a copy of beecontrol onto the stage and call it control_mc. That is the control that will change color to indicate which state the movie is currently in, like so:
This is what the code will need to contain:
/********* DECLARE AND INITIALIZE VARIABLES **************************/
var flying:Boolean = true;
var controlcolor:Color = new Color(control_mc);
/********* DEFINE FUNCTIONS, INCLUDING INIT FOR MOVIE SETUP **********/
// handler for bee1 control on rollover
function growImmediate() {
// expand to 120% of original size
this._xscale = 120;
this._yscale = 120;
}
// handler for bee1 control on rollout
function shrinkImmediate() {
// return to original size
this._xscale = 100;
this._yscale = 100;
}
// handler for bee1 control click
function stopStartBee() {
// check to see if the bee is flying or stopped
if (flying) {
// if it's flying, stop it
bee_mc.stop();
// tell the program the bee is stopped
flying = false;
// change the color of the control to green
controlcolor.setRGB(0x0FE50F);
} else {
// if it's stopped, start it up again
bee_mc.play();
// tell the program the bee is flying
flying = true;
// change the color of the control back to pink
controlcolor.setRGB(0xFFD4FF);
}
}
// startup code for movie (event property assignments)
function init() {
control_mc.onRollOver = growImmediate;
control_mc.onRollOut = shrinkImmediate;
control_mc.onRelease = stopStartBee;
}
/********* CALL THE INIT FUNCTION TO START THE MOVIE *****************/
init();
Here's another example, where text on the control changes to indicate what it will do:
Now our control is a movieclip that contains a rectangle on one layer and a dynamic text field on the layer above it. In the textfield, the text is set to be unselectable by "unchecking" the little Ab button in the Properties panel, so it won't interfere with the operation of the movieclip. The text should also be embedded (click Embed and either shift-click Uppercase and Lowercase, or enter the exact characters in your button, eg PLAYSTOP, into the "Include these characters" box). Give the textfield an instance name playstop_txt. The code structure is identical to that above. The only changes are to remove the color instance, make the rollOver action a little smaller, and have the if/else part of the stopStartBee function change the text in the control rather than changing its color. This is that function:
function stopStartBee() {
if (flying) {
bee_mc.stop();
flying = false;
this.playstop_txt.text = "PLAY";
} else {
bee_mc.play();
flying = true;
this.playstop_txt.text = "STOP";
}
}
The state of the bee (flying or not flying) can be tracked as we did above with a variable on the main timeline. Alternately, as mentioned above, it can be tracked with a property of the bee movieclip itself, as we'll do in the bee game example, or with a built-in property, like _currentframe, which we'll use below.
In this example, in which a short 9-second videoclip embedded in a swf (with stop actions in its first and last frames) is loaded and can be played with the play button, we've included keyframes in the play/pause control and the sound on/off control to display the visual state change. When the movie is playing, a pause button is displayed; when it is stopped, a play button shows. The sound button works in the opposite way, with the displayed state indicating the current state of the sound (off with a red line through it, on without). You should choose a display state which you think corresponds to one your user would expect.
Since each control has two keyframes built into it, we'll use the _currentframe property of the movieclip to keep track of which state it (and the movie) is in. That is, when playpause_btn._currentframe is 1, we know the movie is currently paused (its start-up state). If it's not 1, the movie is playing. If you download tv_movie1.swf (a swf with a video embedded in frame 1, and stop actions in the first and last frames), and tv_movieplayer_start.fla (from the download link at right, subscription required), you can follow along with the instructions below. Look in tv_movieclip.fla to see the final code.
The first thing we'll look at is the event handlers for the controls. Each control needs to have a function assigned to its onRelease event property, and those functions, according to the framework discussed on the code structure page, go into section 4 of our code. So initially, our code will look like this:
/************ 1. DOCUMENT MOVIE, AUTHOR, HISTORY ***************************/
// put your documentation here
/************ 2. IMPORT CLASSES ********************************************/
// don't need these for this movie
/************ 3. DECLARE AND INITIALIZE VARIABLES **************************/
// we'll get to this later
/************ 4. DEFINE FUNCTIONS, INCLUDING INIT FOR MOVIE SETUP ***********/
// define a handler function for the play pause button
// remember that "this" in this function will refer to the play pause control
// because the function will be "attached" to that control (by assignment to its
// onRelease property)
function playPause() {
// assumes frame 1 contains an indicator that the movie is currently PAUSED
if (this._currentframe == 1) {
this.gotoAndStop("playing");
movie_mc.play();
} else {
this.gotoAndStop("paused");
movie_mc.stop();
}
}
// define a handler function for the rewind button
function rewind() {
// assumes frame 1 contains an indicator that the movie is currently PAUSED
if (playpause_mc._currentframe == 1) {
// if movie is paused, rewind sends playhead to beginning to wait
movie_mc.gotoAndStop(1);
} else {
// if movie is not paused, rewind sends playhead to beginning and plays
// goto frame 2 because frame 1 has a stop in it
movie_mc.gotoAndPlay(2);
}
}
// define a handler function for the sound on/off button
function soundOnOff() {
// assumes frame 1 contains indicator of sound currently ON
if (this._currentframe == 1) {
this.gotoAndStop("off");
so.setVolume(0);
} else {
this.gotoAndStop("on");
so.setVolume(100);
}
}
/************ 5. CALL THE INIT FUNCTION TO START THE MOVIE ******************/
// assume that we will define an init function later
init();
Notice that the soundOnOff function refers to a variable so, which is an instance of the Sound class that we'll set up to control the sound in the movie. Thus, we need to create a variable of type Sound in our variable initialization section. We'll also create a variable vloader that we'll use to control the loading of the swf. Section 3 of your code should be modified accordingly:
/**************** 3. DECLARE AND INITIALIZE VARIABLES ******************/ // create sound object to control all sound in movie var so:Sound = new Sound(this); // create video loader object to load video swf var vloader:MovieClipLoader = new MovieClipLoader();
The last thing we need to do, now that variables have been initialized and functions defined, is to think about what needs to happen when the movie starts up. We have our requisite variables in place, and we have the requisite functions in place. What we don't have is any assignment of those functions to the event properties of the corresponding controls. We'll put those assignments inside an init function, so add this to the section 4 code:
function init() {
// set up play/pause (toggle) button to play or stop movie
// by assigning the playPause function to the button's onRelease property
playpause_mc.onRelease = playPause;
// set up rewind to restart the movie
// by assigning the rewind function to the button's onRelease property
rewind_mc.onRelease = rewind;
// set up sound button to toggle sound on/off
// by assigning the soundOnOff function to the button's onRelease property
sound_mc.onRelease = soundOnOff;
}
One other thing we need to do at the beginning of the movie is to assign a function to the channel 1 control to make it load a swf when it's clicked. Sticking with our method of first defining event handling functions, we'll add this code to section 4:
function onChannel1Click() {
vloader.loadClip("tv_movie1.swf", "movie_mc");
}
and then assign that function inside the init function, which will now look like this (also in section 4):
function init() {
// set up play/pause (toggle) button to play or stop movie
// by assigning the playPause function to the button's onRelease property
playpause_mc.onRelease = playPause;
// set up rewind to restart the movie
// by assigning the rewind function to the button's onRelease property
rewind_mc.onRelease = rewind;
// set up sound button to toggle sound on/off
// by assigning the soundOnOff function to the button's onRelease property
sound_mc.onRelease = soundOnOff;
// set up channel 1 button to load tv_movie1.swf into movie_mc
ch1_mc.onRelease = onChannel1Click;
}
Now everything is declared, defined and assigned. We've even added the code already in section 5 to start the movie going by calling the init function.
There are many embellishments that could be made to this movie to improve it, including:
last update: 21 Feb 2006
Discussed on this page:
on/off button, pause/play button, controls with two states, examples of using a variable to track state or using _currentframe in the toggle button itself to track state
Files:
beegame_start.fla
(free download)
tv_movie1.swf
tv_movieplayer_start.fla
tv_movieplayer.fla
In togglebutton.zip, password required
Subscription:
A password may be obtained by subscription ($20 for one month)
An access password will be emailed to the address you specify within 24 hours of receipt of payment, and will remain active for 30 days thereafter. A list of all files currently available at the site may be viewed here.