Chapter 7. The Movie Clip Object

CONTENTS
  •  Properties of Clips
  •  Variables in Clips (or "Homemade Properties")
  •  Methods of Clips
  •  Referencing Clips and Addressing
  •  Summary

The Movie Clip object is the most prevalent and most understandable of all Flash objects. Even the most novice Flash user knows more about objects than he might realize. Although you might not use the words instance, class, and object, you've experienced the concepts. By dragging a Movie Clip onto the Stage, changing its alpha, and then dragging another one and scaling it, you experience the concept of multiple instances of the same master each with different properties. Each instance (Movie Clip on the Stage) of the class (the master symbol) is an object that has properties (such as _alpha and _scale).

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 generally. As you read this chapter, don't think that "now I'm learning the complicated concept of objects;" rather, think that "now I'll be able to modify every aspect of a movie clip using scripting!" Although you are indeed learning about objects, it's the application of making Movie Clips do cool things that's most interesting.

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.

Properties of Clips

graphics/icon02.gif

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 name instances of Graphic symbols only clips, buttons, or (non-static) text.

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).

Figure 7.1. Flash's built-in properties as listed in the Actions panel.

graphics/07fig01.gif

You'll notice that all the built-in properties start with an underscore (as in _alpha not alpha). So, an actual script that changes the alpha of a clip named "box" to 50 percent would look like this:

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.

You Can Get Them All, But You Can't Set Them All

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 frames to a clip while authoring not while watching a movie. Other non-settable properties, however, don't make sense. For example, I constantly find myself trying to set the _currentframe property of clips, as in box._currentframe=12. As much as I try, it doesn't work because _currentframe is just one of the properties you can only ascertain and cannot set. By the way, you achieve the same result by using the method box.gotoAndStop(12), which is covered later in this chapter.

Figure 7.2. The Debugger displays the non-settable properties in gray.

graphics/07fig02.gif

Anonymous Targeting

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 easiest way to understand this concept is to realize that, unless otherwise specified, Flash always assumes the address this precedes any reference to an instance. That is, saying clip._alpha=50 is the same as saying this.clip._alpha=50. The keyword this means "this timeline." Translated, clip._alpha is assumed to refer to the alpha of an instance named "clip" in the current timeline where this.clip._alpha is just more explicit. In either case, these are "relative" addresses; that is, "relative to the current timeline." If you don't specify "this" (or let it be assumed), you must target the clip instance by preceding its name with the full path to that clip. We'll discuss addressing clips in more detail later this chapter, but what about referring to a property without specifying a clip at all? That is, what will _alpha=10 (or this._alpha=10) do?

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 implied. If you're in the main timeline, you can actually set and get properties of the main timeline. Think of real life. You can say "the hair color of that kid" like this.kid.haircolor, if you will. (This assumes that there's a "kid" right in front of you otherwise, you'd have to precede your reference with an address other than this, such as "look across the street at the kid's hair color.") But if you just said "hair color" or "this hair color is brown" without specifying an object (or clip instance), you'd assume that it was the person speaking whose hair color was in question. The main point I'm making here is that if you don't use "object-dot-property" and just use "property," you'll be referring to the property of the timeline in which the script resides. Personally, I've only recently gotten into the habit of always including this instead of assuming Flash knows that's what I mean. Remember, too, from Chapter 1, "Flash Basics," that scripts in keyframes or buttons are "in" (that is, their this is) the timeline in which the button or keyframe resides, but scripts attached to clip instances are "in" the clip itself (not the timeline in which the instance resides).

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 implying that you want the current timeline to be used. Even though this isn't always necessary (and will often be assumed if you leave it off), I think it helps to understand when you include it and think "this timeline." Actually, you'll see in later chapters, as well as in the "Dynamic Referencing" section later in this chapter, that you often need this to identify the current clip and then refer to the object that you are currently "in." In the case of clip instances, each instance is an object. You'll see other kinds of objects in which you can similarly use this to point to the current object. I recommend including this when addressing clips anonymously, but just realize that you are implying it when you leave it out.

Variables in Clips (or "Homemade Properties")

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 slight differences with variables (oh, I mean "homemade properties") in that all can be both seen and changed (unlike properties, some of which can only be seen and not changed). In addition, you shouldn't name your variables with an underscore. Finally, another difference is that only built-in properties cause an immediate and obvious visual change. If your clip's "age" variable is higher or lower, you won't "see" anything unless you write a statement that affects a built-in property. Perhaps use clip._alpha=100-clip.age and then if the clip is older (its age is a higher number), it will be more transparent.

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 assigns brother's age to the result of the expression this.sister.age-2 (or two less than sister's age). These examples don't have an immediate and clear practical use, but they serve to show how you can treat custom variables just like properties.

Figure 7.3. Think of custom variables as homemade properties (despite the fact the Debugger lists them as variables).

graphics/07fig03.gif

To sneak in a quick example of how you might apply this, consider a script attached to a clip that reads

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 anywhere, it will be "undefined" and will evaluate as 0 when used in a mathematical expression; thus, it will have no visual effect (just as adding zero to the clip's _x property will have no effect). However, if you had two clips with this script (with instance names thing1 and thing2, respectively), you could place a script in the first frame of the main timeline that reads:

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 follows the same syntax of properties, maybe it's just easier to think of variables as properties unique to the clip where they're used.

Methods of Clips

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 humans, we are given these properties and they can change (sort of like the built-in properties or custom variables in Flash). There's not much more to say about properties.

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 performs an operation on an individual object. Even though "brushing teeth" is a method, it can be applied to you or me. The method does its "thing" on me or on you. I brush my teeth; you brush your teeth.

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 jumps to frame 3. Does it look familiar? Object-dot-method is the same as object-dot-property and object-dot-variable! You're pretty much done with the book now. Obviously, there's more, but after you get it, you really get it.

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 next chapter, when you write your own functions that can be used as methods of clips.)

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.

Figure 7.4. All of the Movie Clip's built-in methods (listed under Objects>Movie in the Actions panel).

graphics/07fig04.gif

graphics/icon02.gif

attachMovie(), createEmptyMovieClip(), createTextField(), duplicateMovieClip(), and removeMovieClip() enable you to create (and delete) clip instances at runtime. In the case of createTextField(), you can create new Text Field instances. You'll see how to use all these in Chapter 10, "Keyboard Access and Modifying Onscreen Text" and Chapter 12, "Objects," as well as in Workshop Chapter 15, "Creating a Dynamic Slide Presentation."

getBounds() will return any clip's dimensions, which effectively ascertains a clip's size. Because a clip's dimensions include four values (xMin, xMax, yMin, and yMax), getBounds() actually returns a value in the form of a generic object (which contains all four values in a single variable). You'll learn how a generic object maintains multiple values in later chapters (including Chapters 11, 12, and 13). In Workshop Chapter 5, "Mapping and Scripted Masks," you'll use getBounds() in a practical exercise.

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.")

graphics/icon02.gif

swapDepths() and getDepth() can control the visual stacking (or layering) of multiple clips. Once you place clips on the Stage (or create them using a loadMovie(), attachMovie(), or similar script), they'll remain in front of or behind other clips. You can swap the stacking depth on any two clips. (I used this feature extensively on my homepage at: www.phillipkerman.com.)

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 replaced), just use the top-left default center point in the Convert to Symbol dialog box (see Figure 7.5). Also, you need to wait until the movie is fully loaded before you start applying a method such as gotoAndStop(). You can't jump to frame 10 until the movie has loaded completely. You can, however, use the methods getBytesLoaded() and getBytesTotal(), which return information about the loaded movie (as in clip.getBytesLoaded()), and which enable you to determine how much has been downloaded. (We'll do this type of thing in several workshops.)

Figure 7.5. Using the top-left default center option makes registration for loadMovie() easier.

graphics/07fig05.gif

graphics/icon02.gif

The address of the .swf that you're loading can be relative or absolute. If an absolute address points to a .swf residing at a different domain (than the host movie), however, the .swf being loaded has to give permission to the host movie. The new Flash MX feature "allowDomain" lets a .swf say, "It's okay for another domain to load me into their movies." Luckily, the code is more concise. Place the following in a keyframe (of the move being loaded "other.swf" in the preceding example):

System.security.allowDomain("phillipkerman.com");

Naturally, you need to replace phillipkerman.com with the domain where the movie executing the loadMovie() method resides.

graphics/icon02.gif

setMask() enables you to specify dynamically that one clip masks another. For example, myPicture.setMask(shapeClip) causes the clip instance "shapeClip" to act as though it were in a mask layer above the "myPicture" instance (in a masked layer). Another advantage of this great addition to Flash MX is that you can now control objects acting as masks by using script just as you can control any clip. Workshop Chapter 13, "Drawing Graphs," discusses a few cool applications of these features.

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.

Referencing Clips and Addressing

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 offered a general discussion of addressing, it won't hurt to revisit the topic and apply it to what you've learned in this chapter. Basically, you can set/get properties and variables or assign methods to any clip you want you just need to be clear which clip (or which timeline) you are addressing.

Relative and Absolute Referencing

The section on addressing in Chapter 1 was extensive in covering the concept. Now we'll look at addressing (or referencing) clips very specifically. As anyone who's studied physics knows, "Everything is relative." When you're in a car driving beside a train, it can seem as though the train is barely moving or even moving backward. The train could be going backward relative to your perspective, when in fact relative to the Earth, the train is moving forward quite fast just not as fast as your car. The concept is called frame of reference, or starting point. "Frame of reference" applies to Flash when you think about a script's starting point. If you put a script in a keyframe, your starting point (the "this," if you will) is the timeline in which the keyframe resides. If that's inside a clip, your starting point is the timeline inside that clip. Placing a script on a button is similar to keyframes because your starting point is the timeline where the button is placed. It gets a little weird when you place a script on a clip instance. A scripts on a clip instance behaves the same as though it were in the clip (like a keyframe or button in that clip). It makes sense when you think about it, but it's also easy to incorrectly assume that you're starting at the timeline in which the clip is sitting. Figures 7.6 and 7.7 show how frames of reference work.

Figure 7.6. Because your frame of reference is from outside the bowl, the fish appears to be "in water, in the bowl."

graphics/07fig06.gif

Figure 7.7. Scripts attached to clip instances (or to keyframes in the clip) act as though they are "in" that timeline.

graphics/07fig07.gif

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.

Figure 7.8. Regardless of how many times the Spoke symbol is used, you can target an individual instance by its instance name.

graphics/07fig08.gif

From a button or keyframe script on the main timeline:

  • Relative: this.car.frontWheel._rotation

  • Absolute: _root.car.frontWheel._rotation

From a button or keyframe in the Car symbol or from a script that's attached to the car instance in the main timeline:

  • Relative: this.frontWheel._rotation

  • Absolute: _root.car.frontWheel._rotation

From a button or keyframe in the frontWheel symbol or from a script that's attached to the frontWheel instance inside the car instance:

  • Relative: this._rotation

  • Absolute: _root.car.frontWheel._rotation

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:

  • Relative: _parent._rotation

  • Absolute: _root.car.frontWheel._rotation

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 absolutely, multiple copies of the script (caused from multiple instances of that symbol on the Stage) might be redundant, but it won't address more than one clip. Let's say you put a script in the first frame of the master Wheel symbol. Consider a relative script: this.spoke1._xscale=200. This will cause the "spoke1" in both the frontWheel and backWheel instances to get wider. Actually, if you use the wheel symbol anywhere else in the entire movie, its "spoke1" will grow too. Compare this to using the absolute reference _root.car.frontWheel.spoke1._xscale=200. Naturally, this script will execute once for every instance of the master Wheel symbol used, but the result is that it will affect only one thing: the spoke1 that's inside the frontWheel that's inside the car that's placed in the main timeline. It's not that one method is better than the other; it's just that they have different results. As much as this might sound like a defense of absolute references, that's not the case. There's a need for both absolute and relative references. That being said, I definitely try to use relative references as much as possible. They tend to enable you to make drastic changes to your movie at the last minute without extensive script rewrites.

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.

Dynamic Referencing

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).

Figure 7.9. In this example, the arrow button will dynamically target an individual box clip in the left column.

graphics/07fig09.gif

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 closest guess that makes sense (but won't actually work) is

(this.+"box_"+slideShow._currentframe)._x=0;.

The only problem is that although "box_"+slideShow._currentframe indeed evaluates to "box_1" (if the current frame of slideShow is 1), this result is a string (not a reference to a clip instance). That is, we don't say "box_1"._x=0,we say box_1._x=0. Sorry to show all these ways that don't work, but it helps to see the issue at hand.

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 bracket that contains an expression that results in a string matching the name of the clip you want to address (_root["box_"+2]). Notice that addressing the _root timeline is an explicit target. If the clip whose name you were building dynamically existed in a nested clip, you could use _root.subClip[stringExpression] (where "stringExpression" resulted in a string that matched a clip name in the subClip's timeline. After you have addressed your target clip, you can continue with the " dot-property,"" dot-variable," or " dot-method." The finished script (shown earlier in pseudo-code) looks like this:

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 0. 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 targeted (and moved to an x position of 50).

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 loops), check out this other solution:

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="phillip"), another containing a number (myAge=36), and still another containing a Movie Clip reference (myClip=_root.someClip). I say "reference" to a clip because, like other reference data types discussed in Chapter 4, "Basic Programming in Flash," (compared to "value" or "primitive" data types), Movie Clips are objects. After you assign myClip to reference the someClip instance, you could say myClip._alpha=50 and the original would change. I mention this because you'll quite often want to store references to clips in variables, but you need to remember those variables contain only "pointers" to the original. We'll store clip references in variables in Workshop Chapter 6 (as well as other times throughout the book).

Summary

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 understood as homemade properties. And methods are just functions that are assigned to individual clips. (Properties just are; methods do something.)

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


ActionScripting in MacromediaR FlashT MX
ActionScripting in MacromediaR FlashT MX
ISBN: N/A
EAN: N/A
Year: 2001
Pages: 41

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net