|
|
CONTENTS |
|
The Movie Clip object is the most
We'll cover all these details in this chapter. After you understand the Movie Clip object, you'll not only be able to change any property of a clip with scripting, but you'll understand objects
In this chapter, you will:
Access and modify built-in properties of clip instances.
Create custom variables that act like homemade properties.
Learn the concept of, and how to use, "methods" of Movie Clip objects.
Address clips dynamically in addition to absolute and relative addressing.
|
|
When you drag a Movie Clip from the Library onto the Stage, you have already set the
_x
and
_y
(position) properties of the instance created. Each instance on the Stage will have its own set of properties. The available built-in properties are the same for every instance, but the actual settings for each vary. Properties such as
_scale
,
_rotation
, and
_alpha
are examples of other built-in properties that you can modify. Although you can set properties of instances of Graphic symbols while authoring, you can only access properties of instances of objects (such as Movie Clip instances) with scripting. You can both ascertain the current values of a clip's properties and change them through scripting. Flash MX gives you access to instances of clips, buttons, and dynamic or input text. A simple way to understand this fact is that you can't
|
Here's the form that a script takes to access a clip's properties:
clipInstanceName.theProperty
Notice that this is only an expression that results in the value for whatever property you put in the position, "theProperty."
To set a clip's property, the form is:
clipInstanceName.theProperty=newValue;
The form is always "object-dot-property" (or, really, "address to object-dot-property"). Even though you can often refer to the object (that is, the clip instance) by its instance name (which is set through the Properties panel), you'll want to make sure that such a clip has been addressed correctly. It is often easier to understand when you precede "clipInstanceName" with a relative or absolute address reference. The section "Relative and Absolute Referencing" later in this chapter covers this in more detail, but realize that if you don't qualify the instance name with an address, Flash assumes the clip you're addressing resides in the same timeline in which you write this script.
The property (shown as theProperty earlier) is whatever property you want to reference. The list of built-in properties is available in the Actions panel (see Figure 7.1).
You'll notice that all the built-in properties start with an
box._alpha=50;
Pretty simple, eh? It really is. After you understand the concept of "object-dot-property," you'll understand a lot of other topics that come later in the book.
One issue that might be initially frustrating is that although you can
always
ascertain the value of any property of a particular clip, you can set the values of only certain properties. For example, you can set the
_alpha
property of a clip (as in
box._alpha=50
), but you can't set the
_currentframe
property of a clip. The best way to learn which properties are both "set-able" and "get-able" is to look at the Properties tab of the Debugger. As you can see in Figure 7.2, the properties in gray are only available to view (not to change). This makes sense when you look at a property such as
_totalframes
(which contains the total frames in a clip) because you can only add
I mentioned that you can refer to a clip's property (for example,
instanceName.property
) only when the instance (
instanceName
) is in the same timeline in which this script is written. I think the
It's actually quite simple. When you refer to a property with no clip name, Flash assumes that you are referring to the clip where you are currently; that is,
this
is
The idea of anonymous targeting is that you leave off the object part of the form object-dot-property and use just this-dot-property. By doing this, you're
If you understand how the built-in properties of clips can be ascertained and often changed through the dot syntax (object-dot-property), you'll have no problem understanding how to reference the variables you create in clips. Actually, you should think of homemade variables (in clips) as homemade properties of those clips. Not only is the syntax similar (object-dot-variable), but variables are conceptually the same as properties. Built-in properties include
_x
and
_alpha
. If you use a variable inside a clip, say
age
, you can think of the age property of that clip. Of course, you could say
this.box.age=21
in the same way that you could say
this.box._alpha=50
. There are
Variables exist inside clips as soon as you start using them. If you had the script
this.age=1
; on the first keyframe inside a clip, every instance of that clip would have its own "age." This is identical to how every clip has its own
_alpha
(and every other property). You have to create and maintain the custom variables, whereas properties are built-in, but the concept is the same. Suppose, for example, that you had two instances of this clip (with the
this.age=1
script in frame 1). From the main timeline, if you name one instance "brother" and the other "sister" and then select Debug Movie, you would be able to see each clip's variables (see Figure 7.3). Back on the main timeline, you can place a button that includes the script _
this.sister.age=12
(within a mouse event, of course)—and then perhaps another button with
this.brother.age=this.sister.age-2
. Notice that both are statements that assign a value to the age variable unique to one clip. The second example
To
onClipEvent (enterFrame) {
this._x+=this.speed;
}
Every time the screen refreshes (12 times a second if the frame rate is 12fps), this will assign the
_x
property to "speed" more than it is currently (that is,
_x+=speed
). First, whose
_x
property? When you don't specify a clip (that is, you use
this
), the script refers to the
_x
property of the timeline in which it resides— or, inside the clip itself. So,
this._x
is just the
_x
property of the clip itself. Because it's anonymous, the same script will work on as many instances that you can attach this script to. Second,
speed
is a custom variable. Because it's being used "inside" the clip (remember that scripts attached to clips act as though they are inside the clip), the variable
speed
is this clip's
speed
(like this clip's
_x
). If
speed
is not defined
this.thing1.speed=5; this.thing2.speed=10;
Now, the movie should move the two clips to the right. The one with a higher "speed" will appear to go faster (that is, in bigger steps). You can think of speed either as a variable or a property—I don't care. Because it behaves and
This is really starting to get fun! After you understand the concept of object-dot-property, you can use the same syntax on variables. Now you're going to learn how methods follow a similar syntax: object-dot-method. A method is easy to confuse with a property, but they are quite different. Think of real-life properties first: hair color, height, weight, tooth count… whatever. Although these properties can change, at any instant, they're basically static. As
As humans, we also have certain activities that we can perform—for example, combing our hair, brushing our teeth, running… whatever. The point is that these behaviors are analogous to the concept of methods. A method
In Flash, it's even easier to understand. The simplest method (of clips) is
gotoAndStop()
. By itself, a script that says
gotoAndStop(3)
will jump to frame 3 in the timeline where the script is written. However, that's just because there's no object specified and the code really says
this.gotoAndStop(3)
. If the script says
this.box.gotoAndStop(3);
, the clip with the instance name "box" in the current timeline
There are many built-in methods made for clip instances. Most are listed under Actions in the Actions panel—but remember that many "actions" are really statements. Most of the methods for clips are probably very familiar to you: stop() , play() , gotoAndPlay(num_or_label) , gotoAndStop(num_or_label) , nextFrame() , prevFrame() , for example. I'll bet you've used most—if not all— of these. But now you know that they're methods that can apply to unique clips, as in this.box.stop() or this.slideShow.nextFrame() .
One thing you should notice is that all methods have parentheses that follow the method name. This is required (and a good way to recognize methods). Some methods accept parameters between the parentheses—as in
gotoAndStop(12)
. You can't just say
gotoAndStop()
—you have to specify which frame number (or string label name) you want to go
to
. The concept of parentheses for parameters will come up again in Chapter 8, "Functions." The word
function
is probably better suited to thinking of human functions such as brushing teeth or combing hair. Think
method
or
function
—it doesn't matter. The difference is that methods are functions that apply to one object (or clip, in this case) at a time. (If you think the list of methods for clips is short, just wait until
Although you'll find only a few of the Movie Clip's methods listed under Actions, Movie Control (such as stop() , play() , and gotoAndPlay() ), you'll find them all under Objects, Movie, Movie Clip (see Figure 7.4). Keep in mind that when you understand the way to use methods, you can figure out all these. That is, you always use the form clipName.method(parameters) (or just this.method(parameters) when addressing the current clip). However, it makes sense to step through a few of the more interesting Movie Clip methods now.
|
getBounds()
will return any clip's dimensions, which effectively ascertains a clip's
getBytesLoaded() and getBytesTotal() are used to ascertain filesize information on .swf files being loaded dynamically through loadMovie() or the main movie itself when you use _root.getBytesTotal() . globalToLocal() and localToGlobal() are fancy ways to convert a point (x and y coordinates) in one clip instance to the equivalent point in another clip instance. As you recall from Chapter 1, different clips' coordinate systems vary. These methods perform a sort of "exchange rate" on coordinates. Just as you could ask, "How many dollars is 100 yen worth?," globalToLocal() answers the question, "If a point is 100x 100y in this clip, what coordinates is that same point in another clip?" The catch is that the parameter you supply must be in the form of a generic object because it contains two values (one for x and one for y). You can avoid globalToLocal() by making calculations manually—it's just harder that way. hitTest() is used to determine whether one point is within the shape or bounds of a particular clip. For example, you can determine whether the user has clicked on a graphic portion of a movie clip—effectively making a clip act like a button. Also, hitTest() can tell you whether one clip is currently intersecting another. (We'll use hitTest() in Workshop Chapter 2, "Creating Custom Cursors," and Workshop Chapter 6, "Working with Odd-Shaped Clickable Areas.")
loadMovie()
enables you to download and play separate .swf files inside your main (host) movie. That is, if you had a clip with the instance name "clip" in your main movie, you could load a file called "other.swf" in place of "clip" with this code:
clip.loadMovie("other.swf")
. One thing to realize is the top-left corner of the loaded movie will align with the center point of the clip it's replacing. When creating the original clip (that gets
Figure 7.5. Using the top-left default center option makes registration for loadMovie() easier.
System.security.allowDomain("phillipkerman.com");
Naturally, you need to replace phillipkerman.com with the domain where the movie executing the loadMovie() method resides.
|
That pretty much covers the more interesting Movie Clip methods. Obviously, learning which one is which is just a start. You'll get plenty of practice with practically all these methods in upcoming chapters and workshops.
Now that you know about accessing a clip's properties, variables, and methods, you need to make sure that you address (or "target") the correct clip. Although Chapter 1
The section on addressing in Chapter 1 was
Now that you know to be clear about your starting point (that is, where the script is written), you can explore the different types of relative and absolute references. The following list shows several ways to address the rotation property of a frontWheel clip instance that happens to be inside the "car" clip instance. Inside frontWheel are many instances of a Spoke symbol, named spoke1 , spoke2 , and so on (see Figure 7.8). Remember, it's the instance names—not the symbol names—that matter when you address clips.
|
From a button or keyframe script on the main timeline:
From a button or keyframe in the Car symbol or from a script that's attached to the car instance in the main timeline:
From a button or keyframe in the frontWheel symbol or from a script that's attached to the frontWheel instance inside the car instance:
From a button or keyframe in the Spoke symbol or from a script that's attached to one of the spoke instances in the frontWheel instance:
|
It might seem that I was redundant by including the way to express an absolute reference in each example, but this will drive home the point that absolute paths are identical no matter what your frame of reference. They're hard-wired in that they will break if the hierarchy changes. Most people pooh-pooh absolute references for this reason, but absolute paths have a very definite advantage when relative references would otherwise be quite complex. For example, if you wrote a script attached to a clip inside one Spoke symbol inside frontWheel that was supposed to address a spoke instance inside the backWheel instance, a relative reference would look like this:
_parent._parent._parent.backWheel.spoke1
That is, from the clip inside a spoke instance, go up once to the instance of the spoke , go up again to the wheel that contains the spoke instance, go up again to the car that contains the wheel that contains the spoke , go down into backWheel , and then down into spoke1 . This is arguably more complex than the following absolute reference:
_root.car.backWheel.spoke1
Relative references work great when the resulting path is short or direct. I could target a neighbor's house relatively as "down the block and across the street." But to use a relative reference to my friend across the country, it would become a nightmare—an absolute reference would probably be better.
Another attribute of relative references arises when you place a script inside a master symbol, because the same script will be present in every instance you create. Remember, you can only address instances of clips. If a script is addressing another clip relatively, each instance (of the master symbol) will do the same thing. If a script addresses one clip instance
Here are a few reminders. Any reference that begins with _root is absolute and cannot be preceded with this or _parent . Starting a reference with _root means that you're writing an absolute reference. Also, any reference that doesn't already begin this , _parent , or _root can have this added to the beginning. Actually, it's implied and, personally, I find it the best way to learn.
When you know a clip's instance name or relative location, absolute and relative addressing is suitable. However, you might not be able to or want to hard-wire every reference. For example, assume that you have seven box clips (one for each page of a slideshow) and that you want them moved to the right when the appropriate page of a slideshow is active. In other words, you have something like Figure 7.9 where invisible buttons are placed on top of the seven box clips. Users will be able to jump to any page (by clicking a box on the left) or they'll be able to advance to the "next" (or "previous") page by clicking the arrow buttons. The clip instances are named box_1 , box_2 , and so on. It's easy enough to address each box from the individual invisible buttons placed on top of each one. But the arrow buttons must be able to address clips dynamically. If you're on page 1 and you click the right arrow button, you want box_1 to move to the left and then box_2 to move to the right. But when you're currently on page 2, the same right arrow button should then move box_2 to the left and box_3 to the right. (All this in addition to telling the slideshow Movie Clip to go to the next frame.) The point is, the right arrow button will need to do the same basic operation (move boxes), but it should do so slightly differently depending on the current page. You need to refer to a "box_x" clip dynamically (where "x" depends on the current page).
In pseudo-code, the script on the right arrow button should be
Set box_currentFrame's _x to 0 //current Frame being the current frame in the slideShow Make the slideShow go to the next Frame Now, set box_currentFrame's _x to 50 //now that "currentFrame" has increased.
But you can't just say
this.box_currentFrame._x=0
because the clips are only named
box_1
,
box_2
, and so on. You can ascertain the
_currentframe
property of the slideshow clip (using
this.slideShow._currentframe
). The
(this.+"box_"+slideShow._currentframe)._x=0;.
The only problem is that although
"box_"+slideShow._currentframe
indeed
The solution is easier than the explanation of how it works. Here's how you do it:
this["box_"+slideShow._currentframe]._x=0;
If you said this["box_"+2] , notice the result of concatenating "box_" and 2 will be a string "box_2" , but when this string is placed in brackets that immediately follow a target path ( this , in this case), Flash will try to find the clip instance with that name in the path given. By the way, you can include any path ( _root , _parent …whatever); you just have to precede the brackets with a path because you can't assume this will be added for you if you leave it blank). In actuality, every timeline has a special kind of array (called an associative array ) that contains the name of each clip present. In Chapter 11, "Arrays," you'll learn more about arrays and associative arrays.
Naturally, you don't need to know that much about associative arrays to start referring to clips dynamically. Just specify the path (like
_root
) and follow that—not by a dot—but by a square
on (release) {
this["box_"+this.slideShow._currentframe]._x=0;
slideShow.nextFrame();
this["box_"+this.slideShow._currentframe]._x=50;
}
This code first figures out which box instance to target by combining
"box_"
with the value of
this.slideShow._currentframe
, and then it sets the
_x
of the correct box clip to
. Next, it makes
slideShow
advance to the next frame. Finally, it targets another
"box_x"
in
_root
to set its
_x
to
50
. But at this point (now that
slideShow
has advanced), the value for
this.slideShow._currentframe
has increased, so a different box is
The more streamlined version that follows is a lot less complex than the solution I originally developed. Just to see another way to solve this task (and to review other concepts, such as
on (release) {
this.slideShow.nextFrame();
for(i=1;i<8;i++){
this["box_"+i]._x=0;
}
this["box_"+this.slideShow._currentframe]._x=50;
}
In this solution, the first line sends slideShow to the next frame. Then, in the for-loop statement, I set all seven "box_" clips' _x back to zero. Finally, I set the correct box's _x to 50. I admit that this solution isn't eloquent, but it's still good for review.
As I said, you can start writing expressions that result in a dynamic clip name and, as long as you put it between brackets that immediately follow a path, it works great. You'll learn more about what's really happening when you study arrays. Just don't forget the syntax is:
path[string].property
not
path.[string].property
Notice that you don't use a dot after the path when the brackets are present.
It might look as though we're addressing clips by name, but notice that their names are never between quotes. This is because clips are a different data type. You can only address a clip with a string using the bracket reference technique described previously. Realize, too, that as a data type, clips can be stored in variables. For example, you could have one variable containing a string (
myName="
Although it might seem as though you learned several aspects of Movie Clips in this chapter, the truth is that you learned one basic concept: the syntax
targetPath.clipInstanceName.property
. The part "dot property" could change to "dot variable" or "dot method" for slightly different purposes. Actually, homemade variables are best
You also learned how each timeline (or target path) contains an array full of all the clips present. This enables you to dynamically refer to clips by building their names dynamically with an expression. The syntax is path[stringName].property .
The best part of this chapter was that every concept about Movie Clip instances is totally transferable to the concept of objects generally. When you learn more about objects in Chapter 12, "Objects," and Chapter 13, "Homemade Objects," you'll see the same concepts of instances, properties, and methods. From now on, each chapter will continue to expand on the same themes.
|
|
CONTENTS |
|