Using Masks






Using Masks

Up to this point, you have been working with assets in their entirety. However, it is often desirable to show only a portion of an asset. In some cases, you can simply edit the asset to show only a segment thereof. But if you need to reuse that asset (either in its entirety or a different part of it), you will need to create a copy, increasing file size. Masks provide the solution, allowing you to temporarily mask out parts of an asset and reveal only the desired area.

Flash masks simplify the masking process because they actually represent the hole through which you are looking. That is, if you wanted to see a small circular area of an image, you would only have to draw the circle; you wouldn't have to cover up all the unwanted areas of the image. For a more detailed explanation, see the "Masks" sidebar.

In this project, you'll learn how to use timeline mask layers and how to control dynamic masks with ActionScript.

Mask Layers

Your advertisement won't be very successful without a photo, so it's time to add one. Use a mask layer to show a portion of a photo in the area described by your shape-tweened outline:

  1. Create a new layer and drag it to the bottom of the timeline so it is beneath the first shape tween layer. Call this layer house.

  2. Import the house.jpg photo and place the photo in the house layer. Select the photo and convert it to a movie clip symbol named houseMC.

  3. Move the playhead to frame 30 so you can see the finished house outline. Position the photo movie clip so that most of the house and a bit of lawn are visible within the area described by the outline and the left and bottom edges of the Stage.

  4. The house is also visible outside the outline, so add a mask layer to fix that. With the house layer selected, add another layer immediately above it and name it house_mask.

  5. Double-click the house_mask layer icon to open the Layer Properties dialog, and select Mask from the available options.

  6. Repeat step 5 using the house layer, but in this case select Masked.

  7. You now need to fill in the outlined area with a solid shape to use as the mask for the house layer. To speed things along, you can use the mask already provided to you in the source files. As you read briefly in Chapter 5, a file can be opened as an external Library, making it easy to copy assets from that file into your current document. Use the File Import Open External Library menu command to open the animated_ad_library.fla file.

  8. Drag the maskGraphic symbol from the external Library to your main movie and place it in the house_mask layer, carefully positioned so the top and right edges butt the outline. It should be placed at approximately (0, 75).

  9. To see the effect during authoring, lock both the masking and masked layers. You should now only see the house photo inside the outlined area.

  10. Save your work and test your movie.

Your ad is taking shape, but the masked photo detracts somewhat from the impact of the shape tween. Add one final touch by fading in the photo after the shape tween has made its best impression:

  1. Click and drag the first keyframe, in both the house_mask and house layers, to frame 13. Moving the photo to this point lets your shape tweens animate all on their own for the first second.

    Masks

    You have seen that Flash files are typically created by compositing one or more layers in a file. You've also seen how both the main timeline and movie clip timelines organize the layers and display their contents over time. Masks are often used to create traditional visual effects in Flash, such as a spotlight effect in which one layer is viewed through the "hole" created by the masking layer. That is, as shown in Figure, the masking layer defines the area of the underlying masked layer that remains visible (the remainder is "masked off" and therefore invisible).

    Think of masks as "viewing windows." The graphical shape you place on a masking layer acts as a window, allowing a partial view of the layer beneath it. This is similar to how you can look through a window in your house to see the front yard, but you can't see through the walls, which mask the view of the neighbor's house.

    The masking layer masks only the content of a masked layer; it does not affect content on normal layers. If you wish to mask more than one adjacent layer with the same mask, double-click on each and change their layer types to Masked. You can also drag a layer beneath a masked layer (or anywhere in a group of masked layers) to convert it automatically.

    The mask area controls what portions of the masked asset are visible


  2. One second isn't enough, however, so let the image fade up slowly while the animation finishes. Select frame 48 in the house layer, and make it a keyframe.

  3. Move the playhead to the first keyframe (frame 13) in the same layer, select the houseMC movie clip, and give it an Alpha setting of 0 in the Properties panel.

  4. Finally, select the keyframe in the house layer in frame 13, and add a motion tween using the Properties panel.

  5. Lock the house layer again and test your work. Your timeline should now resemble the detail view shown in Figure. If you wish, compare your progress with animated_ad_06.fla in the 07 folder.

The masked layer appears indented beneath the masking layer in the timeline


Scriptable Masks

Mask layers add flexibility when it comes to working with portions of assets, but, as you will read repeatedly in this book, more creative options are possible with the aid of ActionScript. One simple ActionScript method allows you to assign one movie clip to mask another. This means that you can script interactive masks and turn masking on and off.

In this next segment of the project, you'll add representative homeowners to bring a human touch to your ad:

  1. Add a new layer named couple above the shape tween layers and below the headline layer.

  2. Import the couple.png file and position the couple on the lawn as if they are about to enter their new home.


    Note: Keeping layer names short and descriptive makes it much easier to work with the timeline.
  3. Convert the photo to a movie clip called coupleMC, and give it an instance name of couple_mc using the Properties panel.

  4. Add another layer directly above the couple layer and call it scr_mask, short for " scriptable mask."

  5. Switch to the Rectangle tool (R) and, in the scr_mask layer, draw a rectangle on the Stage with a solid fill and no stroke. Make it tall enough to cover the couple and wide enough to cover a bit of extra space on either side. Don't forget their shadow on the left. The rectangle should be approximately 250 x 115 pixels.

  6. Convert the rectangle to a movie clip symbol called scriptableMask and give it an instance name of scrMask_mc.


    Note: Symbol names should also be descriptive, but they can be a little bit longer without being cropped by the Library panel. Short and descriptive is also the rule of thumb for instance names, because you will be writing scripts that refer to them. You want to be sure the name is clear, but not hard to type.
  7. Position the scriptable mask symbol just to the right of the couple, at approximately (180, 285). When you're finished, the relative positioning should look something like Figure.

    The scriptable mask symbol appears just to the right of the couplethe item to be masked.

  8. In frame 1 of the actions layer, add this script:

    	couple_mc.setMask(scrMask_mc);
    

  9. This turns the rectangle into a mask for the couple. Test your movie to make sure that neither is visible. Remember that a mask is a hole through which you see. Since the rectangle is not on top of the couple, you can't see them.

  10. Next, make the mask follow your mouse. In frame 1 of the actions layer, add to your script by setting up an event handler for the scriptableMask movie clip. Within the event handler, use the self-referential keyword this to set the x-coordinate of the movie clip to the x-coordinate of the mouse. The code should look like this:

        scrMask_mc.onEnterFrame = function() {
           this._x = _xmouse;
        };
    

  11. Save your work and test your movie. Depending on where your mouse is, you still may not see the couple. Move your mouse over the lawn, however, and the couple should wipe in and out of view. If you like, compare your movie with animated_ad_07.fla.

Alpha Masks

The reveal is a nice surprise, but thanks to a new feature in Flash 8, you can make it look even nicer. At long last, Flash 8 can now use alpha data in a mask. This means that your mask can contain a gradient with a color that has, for example, 100% alpha fading to a color that has 0% alpha, giving it soft edges.

Unfortunately, you still can't do this quickly in a mask layer, but accomplishing it with ActionScript is very easy. First, change your scriptable mask by replacing its content with an alpha gradient:

  1. Double-click the mask symbol to edit it, and select the solid color you used.

  2. Open the Color Mixer. You will create a custom gradient, much the same way you did in Chapter 1.

  3. This time, instead of using a radial gradient, switch the gradient type to Linear.

  4. The color bar at the bottom of the panel should default to solid black fading to solid white. If it doesn't, don't worry. It doesn't matter what color is used in a mask. Click the lefthand gradient color chip and give that color an alpha value of 0. You should see the grid background in the gradient bar to indicate transparency.

  5. You don't have a lot of room to move your mouse and fade in the couple, so make the gradient narrower. Drag the right-hand color chip to the left until it is about a quarter of an inch from the left.

  6. Optional: If you want to fade out the couple if you move your mouse too far to the left, you can duplicate steps 3 and 4 with two new color chips in the right half of your gradient. Just like the prior steps, but mirrored horizontally, the extreme right should have an alpha of 0, and another alpha of 100 should be a quarter of an inch from the right edge of the gradient.

  7. Your finished gradient should look like Figure. (If you opted not to use step 6, your gradient will be solid on the right.)

    The alpha gradient for the scriptable maskthis figure includes the optional gradient on the right


    Note: If you want to store the gradient for later use, open the Color Swatches panel and click in an empty area to add a swatch. It will appear at the bottom, in the strip of gradient swatches.
  8. Because you started by selecting the mask shape before making your gradient, it should not have the gradient applied. If this is not the case, switch to the Paint Bucket tool and apply the gradient to the shape in the mask symbol, scriptableMask.

  9. Save your work.

If you test your movie now, you may be surprised to see that the mask wipe still uses a hard edge. This is because one final step is required. For the alpha gradient to have an effect, Flash must composite the mask clip and masked movie clip together. For increased efficiency, Flash 8 makes this possible by treating them both as bitmaps.

So, you must select each movie clip and enable runtime bitmap caching. You'll learn more about that in Chapter 10, but for now you should know that, when caching is enabled, Flash caches a bitmap version of a movie clip whenever any major changes are made to it. This allows bitmap transformations, which are often more efficient than vector transformations, to be applied to the clips.

You can enable this property by selecting each bitmap and clicking "Use runtime bitmap caching" in the Properties panel. Or, in your goal to use more and more ActionScript as your comfort level increases, add this to your frame 1 script:

	couple_mc.cacheAsBitmap = true;
	scrMask_mc.cacheAsBitmap = true;

Now when you test your movie, you should see the couple fade in with a soft wipe. Your file should now resemble animated_ad_08.fla.

Variables and Scope

If you need Flash to remember something for later reuse, you often need to define a variable and populate it with a value. This is similar to how you use the equivalent of variables in your day-to-day life. Every time you make an effort to remember something, you are, metaphorically speaking, using variables. When you commit a phone number to memory, you store that information in a way that allows you to recall it as a phone number, not as something else. For example, you don't try to recall that information by searching your memory for an address.

Storing data in a variable can be as simple as writing:

	myNumber = 1;

Recalling that information only requires that you refer to the variable by name to retrieve its data. For example, the following line will display the value of the variable in the Output panel:

	trace(myNumber);

The Output panel is a text-only window that allows you to display information during authoring as a debugging technique. (It's not available when you view your files in a browser.) It is also used to show you any errors that you may have in your scripts. The trace() command simply tells Flash to display something in the Output panel. In this case, testing your movie would display the number 1

While putting information into and getting information out of variables is straightforward, being sure to work with the variable you want is important. In most cases, the scope of a variable is limited to the timeline in which it is defined.

Consider a file that has a movie clip called myMovieClip in the main timeline. A variable defined in the main timeline has a value only in that timeline, and a variable defined in the movie clip will be valid only in the context of that movie clip

For example, if you wrote the following in frame 1 of the main timeline:

	myNumber = 1;
	myNumber = 2;
	trace(myNumber);

you would see 2 in the Output panel. The myNumber variable is defined in the main timeline, and its value is changed with the second line of the script. However, if you wrote the following:

	myNumber = 1;
	myMovieClip.myNumber = 2;
	trace(myNumber);

you would see 1 in the Output panel. This is because, although the second line gives myNumber a value of 2, it is a different myNumberthis variable is a new myNumber stored in the movie clip, not the same myNumber used in the main timeline. The example above uses the familiar dot syntax you've been using for a few chapters, but in this case you are working with a variable, rather than a method or a property. Just as when you started writing event handlers this way, this prevents the need to apply the script directly to the movie clip, so your code is more centralized.

You are not likely to arbitrarily use the same variable name in multiple locations, so that will not often cause confusion. However, sometimes this is good practice, as in the case of multiple movie clips that all share similar functionality but retain some unique variable values that set them apart. For this reason, whether you use the same variable names or not, it helps to understand that even though the same variable name may be used in more than one timeline, scope will affect the population and retrieval of any variable.

Over the next several chapters, you will use variables for a variety of purposes, so you'll have plenty of chances to work with them and understand scope in practice. In the next chapter, you'll also learn about static data typing, which allows you to tell Flash what types of data you will be storing in a variable. This helps Flash warn you when you try to do something unexpected with the data of a specific variable.

For now, however, it's just important that you understand what variables are, and that they are necessary when you need to remember something from one situation to another. You will practice with this concept in the "A Conditional Surprise" section of this chapter.


A Conditional Surprise

You've taken the time to add a sneaky reveal to your ad, to make it more interesting. However, there's still a chance that the surprise can be ruined. If your mouse happens to be near the couple during the opening tweens, the couple may even appear before the house does! To prevent this from happening, you'll need to use a conditional statement and a variable.

You'll use conditional statements throughout the remainder of this book, and in much of your own scripting. A more in-depth look at these logical structures can be found in the sidebar "Conditional Statements," but, briefly, they are designed to execute instructions only if something else is true. For this reason, they are often referred to as if statements. A simple example is: if the light is green, you may drive through the intersection. This type of logical thinking prevents accidents from happening, because the relevant instructions (driving, or showing the homeowners in your file) are executed only when the required conditions are met.

To make a conditional statement work, you need a condition to satisfy. Here, you'll use a variable to store an on/off state for the conditional to check ( variables are discussed in greater depth in the sidebar "Variables and Scope"). Much like a light switch, when you set the variable to "on," or "true" in the Flash vernacular, the conditional will work; in this case, your scriptable mask will move with the mouse. When the variable is "off," or "false," the mask will not move and your homeowners will not be visible prematurely.

In the context of your file, if the variable showCouple is true, the scriptable mask will follow the mouse. If not, the mask will not be able to move. Here's how to set it up:

  1. If you haven't already done so, get out of your scriptable mask and back to the main timeline.

  2. In frame 1, change your script a little by using the following if statement to surround the line about moving your scriptable mask. The edited section of the script follows, with changes in bold:

    	scrMask_mc.onEnterFrame = function() {
    	   if (showCouple == true) {
    		   this._x = _xmouse;
    	   }
    	}
    

You will learn about the syntax in an upcoming section of this chapter, so don't worry. The odd repetition of equals signs will be explained!

Adding this code ensures that the mask won't move unless the showCouple variable is true. If you test your movie, you will see that the couple never appears. But how can you set the variable to true? One way to accomplish that is to add a button to your ad:

  1. Add a new layer above your shape tweens and below the couple, and call it buy_button.

  2. You don't want the couple to be visible until after your animation is over, so add a keyframe to the last frame, frame 85.

  3. In that keyframe, in the buy_button layer, create a button in the lower-right corner of the main timeline. The sample file uses a "For Sale" sign, so if you want to use that, take it from the external Library you used when working on your mask layer. See "Mask Layers" for review, if needed.

  4. Give your button an instance name of buy_btn.

  5. In the actions layer, in frame 85, add the following button event handler to the existing script:

    	buy_btn.onRelease = function() {
    		showCouple = true;
    	};
    

This script sets the variable showCouple to true, and the file now works the way you want it to. However, by using a nice scriptable mask reveal, you've taken the chance that your users may not ever know the couple is there. As an additional measure, add some instructions to encourage them to explore.

Placing the instructions in a keyframe in frame 85 would be adequate, since they won't appear until you are ready for them. However, that doesn't teach you anything new, so you'll put the instructions there but also use another movie clip property to make them invisible until the button you made is clicked:

  1. Create a layer called instructions above the buy_button layer and put a keyframe in frame 85.

  2. Select the Text tool and, to the right of the house, add the following text:

    	YOU could own this home. (Explore the photo with your mouse.)
    

    Feel free to be less explicit if you want to leave more to the imagination of the user.

  3. Convert the text to a movie clip, call it instructions, and give the clip an instance name of instructions_mc.

  4. Finally, in frame 85, change your frame script to control the visibility of the instructions_mc movie clip. When the playhead first enters the frame, the _visible property will be set to false. Only when the buy_btn is used is the property set to true. The final frame script looks like this:

    	stop();
    	instructions_mc._visible = false;
    	buy_btn.onRelease = function() {
    	    instructions_mc._visible = true;
            showCouple = true; 
        };
    

  5. Save your work and test your movie. If desired, compare your file with animated_ad_09.fla.

Your file should now outline the house that starts to fade in during the outline animation, cascade the headline character by character, and then display a For Sale sign. When you click on the sign the instruction should pop in, and you will be able to see your virtual homeowners when you move your mouse left over the lawn.


Note: Adding a new layer for each discrete element is not always necessary. In many cases, it makes your file easier to work with, but adding too many layers can require unwanted scrolling in your timeline. Feel free to combine more than one element in one layer, as long at that layer isn't being used for a tween. Also, don't forget what you learned in Chapter 3: you can group layers into folders in the timeline. The final source file in this project has been reduced to fewer layers using both of these measures, so you can compare timelines and see which approach works better for you.

Conditional Statements

It is not always preferable for all ActionScript instructions to execute right away. You already have experience with triggering scripts only when a user event occurs, such as the press of a button. It's also sometimes desirable to execute portions of code only when certain circumstances are true. This is possible with the use of conditional statements.

A conditional, or if, statement always tests for truth. You can use a special symbol to test if something is false, but even in that case, you are effectively asking, "Is it true that this is false?" Remembering that you are always testing for truth will get you fewer unexpected results from your code.

Conditional statements can be written with varying degrees of complexity. You can start with a simple test, add alternative actions in case of failure, and even combine more than one evaluation in a single test. You will see examples of all of these scenarios in this sidebar, making the concepts clearer. If any of the symbols used here are unclear, see the "Operators" sidebar.

For all of the examples herein, the following given truths will be used when evaluating each conditional:

	//givens
	x = 2;
	y = 3;
	myVar = true;

The most basic structure of a conditional is a single if statement:

	if (x > 1) {
	stop();
	}

In this example, the timeline in which this code appeared would be stopped because x, with a value of 2, is indeed greater than 1. In addition to a single test, you can also provide an alternative course of action. Consider the following example:

	if (x > 20) {
		myClip.gotoAndPlay(1);
	} else {
		myClip.gotoAndPlay(10);
	}

Here, because x is not greater than 20, the evaluation fails and the second instruction is executed, sending the movie clip myClip to play from frame 10. More than one evaluation can be used, too. You must have only one if and only one optional else, but you can have any number of optional else if structures. Here is an example:

	if (x < 0) {
		trace("x is negative");
	} else if (x == 0) {
		trace("x is zero");
	} else {
		trace("x is positive");
	}

In this situation, since x is 2, the first two tests will fail and the alternative will execute, placing "x is positive" in the Output panel.

Note the double equals sign in the second (else if) test. This is a required comparison operator. The single equals sign you are used to seeing is an assignment operator. If the else if statement had accidentally been written with a single equals sign, the value of zero would have been assigned to x. This event would, of course, always make that test true, since you just made the assignment. Therefore, the result would incorrectly trace "x is zero" in the Output panel, even though x is really 2.

In a single if structure, however, only one evaluation can be true. If more than one test can evaluate to true, only the first will be executed, and the script will then continue on with any code that follows the conditional. Here's an example:

	if (x > 0) {
		trace("x is positive");
	} else if (y > 0) {
		trace("y is positive");
	} else if (myVar == true) {
		trace("myVar is true");
	}

In this case, all three evaluations are true, but only "x is positive" will appear in the Output panel. All other tests will be skipped, since the first test evaluated successfully.

Note that in the case of variables that have a value of true or false (called Booleans), it is possible to condense the test statement by dropping the operator. Remember that an if statement tests for truth. Therefore, it is possible to say:

	if (myVar) {
		trace("myVar is true");
	}

When greater complexity is required, it is sometimes convenient to use more than one test in an if structure. This is possible if you use the and logical operator, represented by a double ampersand (&&), or the or logical operator, represented by a double pipe (||). They require that all or any of the tests be true, respectively. For example:

	if (x > 0 && x < 5) {
		trace("success");
	}

Since x is both greater than zero and less than five, this statement would evaluate successfully. Now consider this:

	if (x == 2 || y == 10) {
		trace("success");
	}

Although y is not 10, x is 2. Using the or operator means that one successful evaluation is a successful test, so "success" will still appear in the Output panel.

Finally, if you want to test if something is not true, you can use the not logical operator. The exclamation point (!) is used to test if something is false. Therefore, looking back on your Boolean test, consider the following change:

	if (!myVar) {
		trace("myVar is true");
	}

Using the not operator means this would fail, because myVar is true.

You've just been exposed to the majority of the possible conditional statement scenarios in one relatively brief assault, so don't feel bad if it takes a while to sink in. This book is designed to revisit these topics in multiple projects, so you'll use conditionals a few more times throughout the book. If any such example remains unclear, refer back to this passage for help.


Operators

An essential element of virtually all ActionScript is the operator. A generic description of an operator is a symbol that represents a function already built into the language that acts on an object. In more basic terms, operators typically calculate a new value from one or more existing values. The equals sign (=) is an example of an operator, and it is used to assign a new value to a variable.

For space reasons, this cannot be an exhaustive look at operators of all kinds. Basic operators, such as the arithmetic operators used for addition (+), subtraction (-), multiplication (*), and division (/), will be omitted. Similarly, not every operator in every category will be discussed here, and operators used for more advanced purposes are outside the scope of this text. However, all operators are clearly explained in the help system built right into Flash, as well as numerous online resources. So, if you are ever uncertain about a specific use of an operator, you are never far from a more detailed explanation.

In this sidebar, you will learn about some of the less obvious operators that are used frequently in basic contexts and that may appear in this book. The lines starting with // are comments to help you understand the code, as described in the "Comments" sidebar in Chapter 4.

The most common operator is the aforementioned assignment operator, which you have used many times. It is only mentioned in this list to allow you to contrast its look and functionality with the comparison equals operator (==) that you will see in just a moment.

	// assignment operator, single equals sign:
	x = 1;

The next most common group of operators is the arithmetic operators. You no doubt have experience adding two numbers using the plus sign (+). However, you may not have seen the following shortcut operators before. These are just pairs of symbols that represent a longer structure used when changing a value by a specific factor. Examples include adding 1 to something, multiplying something by 2, and so on. You will frequently see the first and second examples in loops, as a variable is incremented (or decremented) as the loop progresses.

	// add one, as in:
	// x = x + 1
	x++;
	
	// subract one, as in:
	// x = x - 1
	x--;
	
	// add, subtract, multiply, divide by any number n,
	as in:
	// x = x + n
	
	x += n;
	x -= n;
	x *= n;
	x /= n;
	
	// example:
	// x = x + 10
	x += 10; 

Comparison operators are used in conditional statements. (For more information, see the "Conditional Statements" sidebar.) These operators are used to compare two values. Take special note that when comparing a variable to a value to test if they are equal, two equals signs are required. Also, the exclamation point (!), when combined with the equals sign, means not equal to.

	// less than (or greater than), as in:
	if (x > 1) {
	}

	// less than (or greater than) or equal to, as in:
	if (x <= 1) {
	}
	
	// is equal to?, as in (note DOUBLE equals sign):
	if (x == 1) {
	}

	// is not equal to?, as in (note DOUBLE equals sign):
	if (x != 1) {
	}

If the double equals sign is not used when required, the familiar functionality of the single equals sign will apply. This is an assignment operator, which is not what you would want to use in this context. See the "Conditional Statements" sidebar for a demonstration of this situation.

The final group of operators discussed here is logical operators, which are also used in conditional statements. The first is the not operator, which is used to test if something is false. The second two are the and and or operators, which are used when testing multiple conditions in a single statement.

	// NOT (!, is movie clip not visible?), as in:
	if (! myClip._visible) {
	}

	// AND (&&, where BOTH must be true), as in:
	if (x == 1 && y == 2) {
	}
		
	// AND (||, where EITHER can be true), as in:
	if (x == 1 || y == 2) {
	}

If these samples don't all make sense immediately, don't worry. You will use operators in most scripts that you write, and using them will rapidly become second nature. In the upcoming section on ActionScript animation, for example, you will practice with a variety of shortcut operators, and in upcoming chapters you will also use comparison and logical operators. For now, as long as you understand what operators are, you can always look them up to confirm the purpose or syntax of any one.




 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows