Using what you've learned so far, you'll create a behavior that will allow you to fade sprites in or out over a given number of frames, without having to use keyframes in the Score. You'll do this in order to fade in the three pieces of art in the first section, in a more random fashion. You could manipulate the keyframes the sprites are now using to fade in, but that would be cheatingafter all, this is a lesson in Lingo. First, let's get rid of the keyframes currently used to fade the artwork in.
Open the portfolio project from your project_one folder and select the three artwork sprites in the first section: growth_01, growth_02, and growth_03. Right-click within the selected sprites and select Remove Keyframe.
When you select Remove Keyframe all three of the sprites will disappear from the Stage. This is because the very first frame within each span still has the blend value set to 0 percent.
Hold down Ctrl/Command and single-click the first frame of each sprite's span to select the frame as shown. Next, select the Sprite tab within the Property inspector and choose 100 percent for the blend.
With the keyframes removed, the artwork simply appears at the start of the first section, and no longer fades in. It's time to create the behavior to do just that. Before writing any code, however, you should think about what the behavior will need as far as handlers and properties.
Because you want to fade the sprite over a certain number of frames, you'll need a property to store the frame count in. And if you're counting frames you'll want to handle one of the frame events such as enterFrame or exitFrame that are sent on a per frame basis. You'll also need to figure out the blend step: how much do you blend per frame? For that you'll need to know the starting and ending blend values. Let's get started by defining the necessary properties, as well as creating a getPropertyDescriptionList() that will accept the initial values for the properties.
Select the first artwork sprite in channel 3. Next, create a new behavior for the sprite by either right-clicking the sprite and selecting Script from the context menu or selecting New Behavior from the Behaviors drop-down menu in the Score's Sprite toolbar. Enter the following Lingo:
Before entering the start of the fade behavior, delete the default mouseUp handler that Director automatically generates.
property framesToFade, perFrameBlend property startBlend, endBlend property finished, blendDirection on getPropertyDescriptionList pList = [:] addProp pList, #startBlend, [#comment:"Beginning Blend %:", ¬ #format:#integer, #default:0, #range:[#min:0, #max:100]] addProp pList, #endBlend, [#comment:"Ending Blend %:", #format:#integer, ¬ #default:100, #range:[#min:0, #max:100]] addProp pList, #framesToBlend, [#comment:"Blend for how many frames:", ¬ #format:#integer, #default:30] return pList end
First, six properties are defined, three of which are given initial values through the GPDL handler. The other three will be initialized within a beginSprite() handler. Note in the GPDL that the #range parameter is being used not only to provide a slider, but also to limit the input values to being between 0 and 100 only.
Next, you'll add the beginSprite() handler that will calculate the value for perFrameBlend as well as figure out the blendDirection. Knowing which way the blend is going is necessary in order to know if the sprite's current blend has reached the target endBlend value.
After the getPropertyDescriptionList() handler add the following beginSprite() handler. It will serve to initialize several properties that will be used by the exitFrame() handler:
on beginSprite me finished = false perFrameBlend = (endBlend startBlend) / framesToBlend if perFrameBlend > 0 then blendDirection = #fading_in else blendDirection = #fading_out end if sprite(me.spriteNum).blend = startBlend end
Remember that the beginSprite event is fired just one time, when the playhead encounters the span. For this reason a beginSprite() handler is a perfect spot to initialize variables. First, finished is set to false to tell the script that the fade has not yet finished. Next, the perFrameBlend value is calculated by dividing the total blend amount (endBlend startBlend) by the number of frames to blend over. Instead of using a simple counter you achieve the same result by calculating the blend on a per-frame basis. Because the perFrameBlend can be either positive or negative, depending on the startBlend and endBlend values, the direction of the blend is stored in the blendDirection property. Finally, the blend of the sprite that the behavior is attached to is set to the startBlend value.
Not only does beginSprite() run one time, it runs before the frame is drawn, making it also ideal for setting sprite properties such as blend and position through Lingo.
At this point, all that's left to add is the exitFrame() handler that will execute on every frame.
Add the following exitFrame() handler to the behavior.
on exitFrame me if not(finished) then startBlend = startBlend + perFrameBlend if blendDirection = #fading_in then if startBlend >= endBlend then startBlend = endBlend finished = true end if else if startBlend <= endBlend then startBlend = endBlend finished = true end if end if sprite(me.spriteNum).blend = startBlend end if end
This may look complicated, but it's really pretty simple. First, note the use of if and end if conditional statements, which constitute the bulk of the handler. An if statement goes like so: "if some condition is true thendo some stuffend if." Every if statement must have a matching end if, and you can use the keyword else to execute actions when the condition fails: "if some condition is true thendo some stuffelsedo some other stuffend if."
Let's examine the handler.
First we have a test to see if the blend has finished: if not(finished) then. The not() method negates somethingand because finished is initialized to be falsenegating it makes it true and satisfies the condition for entry. Note that you could have just as easily used if finished = false thenand it would have had the same effect. Using not() simply shows an alternate method.
Therefore, when finished is false the perFrameBlend value will be added to the current value of startBlend, and the rest of the handler will execute. Because perFrameBlend can be either positive or negative, startBlend will either increase or decrease accordingly. This is where the importance of needing to know which direction the blend is going comes into play. If startBlend is increasing, in the case of the sprite fading in, then you need to check to see if the value of startBlend has gotten to, or surpassed, the endBlend setting. On the other hand, if you are fading the sprite out, then perFrameBlend will be negative and startBlend will decrease each frame. In this case you need to check to see if its value is less than or equal to the endBlend value.
In either case, when startBlend reaches endBlend the finished property is set to true, and the endBlend value is placed into startBlend. This is done so that the final time this line executes: sprite(me.spriteNum).blend = startBlend the sprite's blend will be guaranteed to be set to the endBlend value. Once finished is set to true the initial test will fail (because negating true makes false) and the script will essentially stop executing.
Remember that you can create comments within your scripts as explanatory notes. This will make it easier to come back to, if you need to. To create a comment, begin a line with two minus signs: -comment text after the double dash. Comments are auto-colored red.
Name the script sprite_fade and close the script window. Choose Use Defaults in the alert that appears.
Using the defaults will cause the sprite to fade in from 0 percent to 100 percent over the course of 30 frames.
Locate the new behavior in the cast, then drag and drop it onto the second piece of artworkthe sprite in channel 4. Have it fade from 0 percent to 100 percent over 20 frames. Repeat with the last piece of art in channel 5, but have this sprite fade in over 50 frames.
At this point, if you were to play the movie you'd notice a problem: now that you have removed the keyframes from the sprite spans of the art, the sprites will fade in while the ball is animating and also before the curtains open. This is easily remedied by moving the initial frame of each artwork sprite to coincide with the start of the curtains opening.
Click and drag the first frame of each artwork sprite from frame 15 to frame 25, to coincide with the curtains opening.
Once you've got all three spans adjusted, you may realize another benefit of behaviors. The artwork now occupies frames 25 through 44a total of 19 framesbut the sprites fade in over 30, 20, and 50 frames, respectively. Using Lingo frees you from having to use the Score for animation. Another benefit is a significantly fewer number of frames used in the Score. In a large project, that can make a big difference in the length of the Score.
Although each of the three sprites is fading in from 0 percent blend, you can use the same behavior to fade sprites out by setting the starting blend to 100 percent and the ending blend to 0 percent.
That's about it for the Portfolio project before publishing it to a projector. You should save the movie before moving on. Before you finish completely, you may want to go back and add the sound for the second section, create an exit button, or create a button that returns to the intro section.