When a movie clip instance with attached scripts enters a scene, that scene can take on a new look, feel, and function through the use of clip events. These events allow actions to be triggered when an instance enters or leaves a scene, when the user moves the mouse around in the scene, and in other ways.
This section describes the various clip events and provides real-world analogies for their uses. Note that you can use clip events only with scripts attached to movie clip instances.
When someone or something enters a room or an area, there can be all kinds of ripple effects: the demeanor of people already in the room changes; the environment can be affected in some way; even the person (or thing) entering the room can change as a result of what's going on inside. This event handler provokes a similar response by triggering a script when a movie clip instance enters a sceneuseful for initializing the movie clip, for having it be affected by the environment it's entering, or for having it affect the environment.
If a movie clip instance can affect a scene when it enters, it can also affect the scene when it leaves (sometimes in the opposite way). You can use this event handler to trigger a script when a movie clip instance exits a scene.
When an object is given energy or power, it usually signifies that it is taking action on a continuous basis. Consider a clock: without power it sits motionless and useless. If you provide power to it, it ticks, the hands on the face move, and you're able to use it to tell time. This event handler is used to trigger a script continuously, at the same rate as that of your movie as it plays. If your movie's frame rate is set to 20 frames per second, the scripts this event handler triggers are executed 20 times a second. This event handler has many powerful applications, as you'll learn from lessons throughout this book.
Think of this event as a motion detector within your movie. If a movie clip instance is present in the scene to which this clip event is attached, a set of actions can be executed each time the user moves the mouseeven if it's just a pixel. This event allows you to create motion-related interactivityfor example, the ability to detect movement direction (right, left, up, and down), current mouse position, and more.
Because the mouse and keyboard are designed to interact with computers, these clip events don't have real-world equivalents. However, they do provide a means of executing scripts when the user presses (or releases) the mouse button or specific keys. While these events may seem similar to the press, release, and keyPress events described earlier in this lesson, they're a bit more powerful. Using the keyUp and keyDown clip events, you can create key-combinations, or keyboard shortcuts, in your application so that action is taken when a sequence of keys is pressed. In contrast, the keyPress mouse event allows a single key to initiate action. The mouseUp and mouseDown clip events are different from the press and release mouse events because while the latter only trigger scripts when the user interacts directly with a button, the mouseDown and mouseUp events trigger scripts when the mouse is pressed or released anywhere on the stage.
In real life, incomplete instructions can lead to all sorts of problems. The same holds true in Flash. Because Flash lets you load various types of data (variables, external SWFs, JPGs) from external sources into movie clip instances, this event handler plays a vital role because it triggers a script, attached to an instance, only after this data has been completely loaded into it from the source. In doing so, it prevents you from receiving the types of errors that result from incomplete instructions. You can use this event to re-execute actions (refresh) if data is loaded into the clip more than once.
This is a visual representation of how clip events are triggered. The down arrow represents pressing the mouse button or a key. The up arrow represents releasing the button or key. The asterisk represents an occurrence of the event.
In the next exercise, we'll create a project that simulates a burglar's getting caught in the act. The burglar's presence (or absence) will determine how the scene plays, and the burglar himself will be programmed to respond to the environment in various ways using clip events.
Open ClipEvents1.fla in the Lesson02/Assets folder. Open the Property Inspector.
This project contains a single scene that includes seven layers named according to their content. Take special note of the two frames with labels. The one labeled Clear represents the scene without the burglar, and the one labeled Burglar introduces the burglar into the scene. (Move the playhead between these frames to get a handle on this concept because it will be critical to the success of our project.) The burglar graphic is actually a movie clip instance named burglar_mc, which will contain most of the scripts that control our movie's interactivity (more on that in a bit). The burglar_mc movie clip instance is the only movie element that appears and disappears when the user navigates between these two frame labels; all other elements are constantly present. Let's look at these constantly present elements.
At the top-right of the stage are four buttons. The one that depicts the burglar with the international sign for "No" (red circle with a line through it) on top will eventually be set up to move the scene to the Clear frame, thus "removing" the burglar from the scene. The other three buttonsTiny, Small, and Normalwill be used to dictate our burglar's size.
Below these buttons is a light-green circle graphic: a movie clip instance named timer_mc. We will program timer_mc to spin when the burglar is in the scene, giving the sense that it's tracking time.
Below the timer_mc movie clip instance is a text field named timeAmount_txt. Here, we will be incrementing a number as long as the burglar is presentonce again to give the sense that we're tracking time.
Below this text field are two more text fields, one with an X beside it, the other with a Y. We'll program our burglar to follow the mouse as it moves around. These text fieldsmouseXPosition_txt and mouseYPosition_txt, respectivelydisplay the current x and y coordinates of the burglar_mc movie clip instance as it moves.
Below these text fields is the last text field. Named message_txt, this text field will provide the current status of our environment ("All Clear," "ALERT!" and so on).
Our scene contains only two other elementsboth movie clip instances that need to be examined in depth to be understood.Double-click the small circle in the top-left of the work area, just above the stage, to edit this movie clip in place.
This movie clip has an instance name of siren_mc. With its timeline visible, you can see that it's made up of three layers and two frame labels. At the frame labeled On, there's a siren sound on the timeline. When this movie's timeline is sent to that frame label, the sound will play. This will be used to simulate an alarm being turned on. The other frame label on this timeline, Off, contains no sound; when the timeline is sent to that frame, the alarm will cease playing.Return to the main timeline. On the Lights layer, click the Show Layer button (red X) to reveal a big black box that covers the entire stage. Double-click it to edit this movie clip in place.
This movie clip has an instance name of lights_mc. With its timeline visible, you can see that it's made up of four layers and five frame labels. This movie clip is used to simulate various light angles in the movie. We'll be scripting our project so that when the burglar moves to a particular area of the screen, the appropriate light will come on.
For example, if he moves left, the left "light" will come on (frame labeled Left). On the Sound layer, we've placed a sound at each one of the frame labels that gives the audio effect of a big switch being toggled (the light is turning on).
Now that the introductions are complete, it's time to start scripting!Return to the main timeline. On the Lights layer, press the Hide Layer button to hide the big black area that is the lights_mc movie clip instance. With the Actions panel open, select Frame 1 on the Actions layer and attach this script:
message_txt.text = "All Clear"; var time:Number = 0; var size:Number; stop ();
The first line places the text "All Clear" in the message_txt text field as soon as the movie plays. Whenever the timeline is sent back to this frame label, this action will execute again. Knowing this, we can deduce that whenever "All Clear" appears in the message_txt text field, the main timeline is at Frame 1 and the burglar is not present. An understanding of this functionality will prove important in a moment.
The next two lines of script create the time and size variables, which both hold numeric values. We haven't assigned values to the size variable yet, but some of the scripts we add later will do so.
The last line stops the timeline from moving past this frame until we instruct it to do so.With the Actions panel open, select the Tiny button and attach this script:
on (release) { if (message_txt.text == "All Clear") { size = 50; gotoAndStop ("Burglar"); } else { burglar_mc._xscale = 50; burglar_mc._yscale = 50; } }
With the Actions panel open, select the Small button and attach this script:
on (release) { if (message_txt.text == "All Clear") { size = 75; gotoAndStop ("Burglar"); } else { burglar_mc._xscale = 75; burglar_mc._yscale = 75; } }
With the Actions panel open, select the Normal button and attach this script:
on (release) { if (message_txt.text == "All Clear") { size = 100; gotoAndStop ("Burglar"); } else { burglar_mc._xscale = 100; burglar_mc._yscale = 100; } }
With the Actions panel open, select the No Burglar button and attach this script:
on (release) { gotoAndStop ("Clear"); }
This button does one thing: it moves the main timeline to the frame labeled Clear, where the burglar_mc movie clip instance does not exist. When the timeline is moved back to Frame 1, the actions we set up in Step 4 execute again.
In summary, the Tiny, Small, and Normal buttons are used to make the burglar appear or to resize him. The button we just configured makes the burglar disappear.
The rest of the scripting for our project will be placed on the burglar_mc movie clip instance.With the Actions panel open and the main timeline at the frame labeled Burglar, select the burglar_mc movie clip instance and attach this script:
onClipEvent (load) { startDrag (this, true); this._xscale = _root.size; this._yscale = _root.size; _root.lights_mc.gotoAndStop("bottom"); _root.mouseXPosition_txt.text = _root._xmouse; _root.mouseYPosition_txt.text = _root._ymouse; _root.message_txt.text = "ALERT!"; }
This set of actions is triggered when this movie clip first appears (load), or when it reappears in the scene as a result of the timeline's being moved to this frame. The first action causes the burglar_mc movie clip (this) to become draggable. The next two actions scale the movie clip's horizontal and vertical size based on the current value of the size variable, which exists on the root (main) timeline. Remember that we set this variable with one of our three buttons (Tiny, Small, or Normal). When one of the buttons is pressed, the size variable is set to a value of 50, 75, or 100 (depending on which button was pressed); the main timeline is sent to the frame containing this movie clip instance; and, on loading, the value of the size variable is used to set the size of the burglar.
The next action tells the lights_mc movie clip instance to move to the frame labeled bottom. At this label it appears that light is shining from the bottom of the screen. This is just a default setting. We'll make the light_mc movie clip instance a bit more dynamic in a moment.
The next two actions display the mouse's current x and y positions in the text fields on the root timeline (mouseXPosition_txt and mouseYPosition_txt, respectively).
The last action displays the text "ALERT!" in the message_txt text field on the root timeline to indicate that the burglar is now present.Add this script just below the end of the current one:
onClipEvent (enterFrame) { _root.time++; _root.timeAmount_txt.text = _root.time; _root.timer_mc._rotation = _root.timer_mc._rotation + 1; }
Here, the enterFrame event controls three actions that are executed 24 times a second (because this type of event executes actions at the same rate at which the movie plays).
The first action uses the time variable on the main timeline (which we created in Step 4), to hold the value of an incrementing number. Using the ++ operator, each time the enterFrame event occurs (24 times a second), the value of this variable is incremented by 1. This syntax is the same as writing the following script:
_root.time = _root.time + 1;
The next action is used to display the incrementing value of the time variable in the timeAmount_txt text field.
The last action rotates the timer_mc movie clip instance by 1 degree, 24 times a second. This will produce the effect of the timer being turned on while the burglar is present.NOTE
Because this script exists on the burglar_mc movie clip instance, it will execute only while that instance is present in the scene.
Add this script just below the end of the current one:
onClipEvent (mouseMove) { if (_root._xmouse > Number(_root.mouseXPosition_txt.text) + 10) { _root.lights_mc.gotoAndStop("right"); _root.message_txt.text = "Intruder is moving East"; } else if (_root._xmouse < Number(_root.mouseXPosition_txt.text) - 10) { _root.lights_mc.gotoAndStop("left"); _root.message_txt.text = "Intruder is moving West"; } else if (_root._ymouse > Number(_root.mouseYPosition_txt.text) + 10) { _root.lights_mc.gotoAndStop("bottom"); _root.message_txt.text = "Intruder is moving South"; } else if (_root._ymouse < Number(_root.mouseYPosition_txt.text) - 10) { _root.lights_mc.gotoAndStop("top"); _root.message_txt.text = "Intruder is moving North"; } _root.mouseXPosition_txt.text = _root._xmouse; _root.mouseYPosition_txt.text = _root._ymouse; }
The actions in this script are triggered every time the mouse is moved. An if/else if statement compares the mouse's current position with its last known position, and then acts accordingly. We'll examine the first comparison in the statement; having done that, the rest should be self-explanatory.
Before we continue, it's important to note that the load event we set up in Step 9 contained two actions that set the text displayed in the mouseXPosition_txt and mouseYPosition_txt text fields based on the x and y positions of the mouse when the burglar_mc movie clip is loaded. We will now use those text values in the comparisons made in this script. Since the information displayed in the fields will be used in mathematical comparisons in our if/else if statement, their values have to be converted to numbers using the Number() function. Thus, the script sees them as numeric values rather than text values.
The first part of this script states that if the current horizontal position of the mouse (_root._xmouse) is greater than the value of mouseXPosition_txt plus 10, two actions will be executed. By checking the mouse's current position against its last recorded position, we can determine in which direction it's moving. For example, if the current horizontal position of the mouse (_root._xmouse) is 300 and the previously recorded position (as displayed in the _root.mouseXPosition_txt text field) was 200, we know the mouse has moved to the right. In this case, our script would trigger two actions: one to move the lights_mc movie clip instance to the frame labeled right (where the light appears to come from the right part of the stage) and one to display the message "The intruder is moving East" in the message_txt text field. The if statement uses four comparisons to determine whether the mouse has moved right, left, up, or down.
NOTE
Keep in mind that although the mouse can move in two directions simultaneously (for example, up and right in a diagonal direction), our script gives single-direction movement precedence. This means that right-left movements are of higher priority than up-down movements. If the mouse moves both left and down, the script will detect only the left movement. The reason is that the if statement first looks to see if the mouse has moved right. If it has, the two actions for dealing with this movement are executed, but no other part of the if statement is executed. If the mouse hasn't moved right, that part of the if statement is ignored, and our script checks whether the mouse has moved left. If it has, the two actions for dealing with this movement are executed, but no other part of the if statement is executed. This same process continues when checking for down and up movements. In essence, once a movement in any single direction has been detected, the rest of the script is ignored. Because the if statement looks for right, left, down, and up movement in that order, if it detects right and left movements first, down and up movements won't matter.
On a side note, you'll notice that in each comparison we add or subtract 10 from the value of mouseXPosition_txt or mouseYPosition_txt so that the mouse must move at least 10 pixels from its last recorded position before any action will occur. If we didn't do this, the mouse's movement on screen would look like firecrackers going offthat is, visually too intense.
The last two actions of this script (placed just before the last curly brace in the script) record the current x and y positions of the mouse so that the next time this script is executed (when the mouse is moved), these values can be used in the comparison process of the if statement again. Because these values are placed in the mouseXPosition_txt and mouseYPosition_txt text fields, each time the mouse is moved and these values are updated, the changes are displayed in those fields as well.
In essence, this script compares the current position of the mouse against its previously recorded position; takes appropriate action based on whether the mouse has moved left, right, up, or down; and records the mouse's current position for the next time the mouse is moved.Add this script after the current one:
onClipEvent (unload) { _root.time = 0; _root.timeAmount_txt.text = _root.time; _root.timer_mc._rotation = 0; _root.message_txt.text = "All Clear"; _root.mouseXPosition_txt.text = ""; _root.mouseYPosition_txt.text = "" ; _root.lights_mc.gotoAndStop ("Off"); }
This script dictates what happens when this movie clip instance (burglar_mc) is unloaded, or is no longer in the scene (as a result of the main timeline's moving to a frame where the burglar doesn't exist). This occurs when the No Burglar button is clicked and the main timeline is moved to the Clear frame (which is actually Frame 1).
The actions restore the elements to their original state (that is, before the burglar appeared in the scene). The first one resets the time variable to 0. The next action sets what is displayed in the timeAmount_txt text field to the value of time (making it 0 as well). The next action resets the rotation property of the timer_mc movie clip instance to 0; the action after that displays "All Clear" in the message_txt text field. The subsequent two actions clear the mouseXPosition_txt and mouseYPosition_txt text fields, and the last action moves the lights_mc movie clip instance to the frame labeled Off. This last action turns the scene black again.Add this script after the current one:
onClipEvent (mouseDown) { this.gotoAndStop("right"); _root.message_txt.text = "Intruder is confused"; }
Add this script after the current one:
onClipEvent (mouseUp) { this.gotoAndStop("left"); _root.message_txt.text = "Intruder is running"; }
Add this script after the current one:
onClipEvent (keyDown) { _root.siren_mc.gotoAndStop("on"); _root.message_txt.text = "Backup has been called"; }
Add this script after the current one:
onClipEvent (keyUp) { stopAllSounds(); _root.siren_mc.gotoAndStop("off"); _root.message_txt.text = "Silent alarm activated"; }
When any key is released, these three actions are executed. The first stops all sounds, including the currently playing siren. The second action sends the siren_mc movie clip instance to the frame labeled off (causing the siren to be turned off). The last action causes the message_txt text field to display "Silent alarm activated."
NOTE
Because the mouseDown/mouseUp and keyDown/keyUp clip events are attached to the burglar_mc movie clip instance, none has an effect until that instance appears in the scene.
Choose Control > Test Movie to test the functionality of our project.
Press one of the buttons on the top-right corner of the stage to make the burglar appear. When he appears, notice how the environment changes. Move him around to see what changes his movement provokes. Press the button to remove him and notice what happens. When the burglar is in the scene, click the mouse or press the Spacebar on the keyboard. Most of our movie's interactivity depends on the burglar_mc instance being present in the scene, showing how introducing a single instance into the scene can change its dynamics completely.Close the test movie and save your work as ClipEvents2.fla.
This completes the exercise.