This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
(paragraph), (bold), and (italic), which are used to lay out the document. Director does not recognize embedded objects other than tables. Director ignores the following features found in HTML documents: images, frames, input fields, and embedded applets. HTML documents can be imported locally or from the Web. Caution
Make sure you are using HTML text from a Web server that you know will always be online. Otherwise, the text in the linked cast member may not appear in your movie.
3486-6 ch04.f.qc
7/24/00
5:40 PM
Page 161
Chapter 4 ✦ Using Text in Director
If you select the Link to File option when importing an HTML document that is located on a Web server, the linked cast member in Director will automatically update when the source page on the Web server is updated, provided that the user has a working Internet connection when they play the movie. The user does not have go to the actual Web page for this to occur.
Note
Authors can now use external linked scripts that can be updated separately by another author. This is a very useful feature when working on large-scale Director projects that involve multiple programmers and authors. The supported file extensions for scripts are .txt or .ls, Director’s internal file extension for linked scripts. A linked script is updated only during the authoring stage of the movie’s development. A copy of the script is stored in the movie when it is output as a Projector or Shockwave file, thus avoiding the need to distribute the scripts with your movies. Director 8 now has the capability to import and link to external Lingo scripts.
New Feature
You import text files just as you do any other type of element, by choosing File ➪ Import, selecting the files that you want to import, and setting the options, such as linking. CrossReference
Director’s Import operations are discussed in detail in Chapter 2.
Embedding Fonts in Your Movie The best way to deal with the cross-platform font problems is to embed the desired fonts directly in your movie. When you embed a font in your movie, Director stores all of the font information so that the font can be displayed even if it is not installed on the user’s system. Embedded fonts appear in the Cast window, just like any other cast member, and are accessible from all of Director’s font menus. All of the text members you used in this chapter have had embedded fonts applied to them; the fonts appear on the Windows operating system the same way they appear on the Macintosh operating system that was used to create the movies for this book. Director compresses the fonts, which means that they will increase the size of your movie by an average of 15K to 25K. If file size is a concern, you can include just the characters used for the text. This option is useful if you are developing movies that will be played back over the Web. You can also include bitmap versions of the font for displaying text at sizes smaller than 12 points, where antialiasing can have a negative effect on the text. Note
There are no legal issues involved with distributing fonts that you embed in your movie, because they are available only to the movie itself and cannot be used in any other application.
161
3486-6 ch04.f.qc
162
7/24/00
5:40 PM
Page 162
Part I ✦ Working with Director
Embedding a font It’s a good idea to embed the fonts that you want to use in your movie before creating Text cast members that use them: 1. Choose Insert ➪ Media Element ➪ Font. In the Font Cast Member Properties dialog box that appears (see Figure 4-18), you can choose a font, select bold and italic versions of the font, and include specific bitmap sizes and characters.
Figure 4-18: In the Font Cast Member Properties dialog box, select the attributes of the font that you are embedding in your Director movie.
2. Select the font by clicking the arrow button next to the Original Font list box. A list appears, showing all the fonts installed on your system. Choose the font that you want to use from this list. 3. In the New Font Name box, the name of the new font appears followed by an asterisk. Director uses this new name in all of its font menus. It’s better to use the default name for the font, because it is more obvious than its embedded version. Here are some things that you should consider before selecting the other options: ✦ If you want to have bold or italic versions of the font (which are more attractive), click the check boxes to turn these options on. Selecting these options includes a bitmap version of the bold and italic characters of the font, which increases the size of the Font cast member.
3486-6 ch04.f.qc
7/24/00
5:40 PM
Page 163
Chapter 4 ✦ Using Text in Director
✦ To include bitmap versions of the font at specific sizes, click the Sizes radio button below the Bitmaps options and type in the sizes that you want to use, separated by either spaces or commas. Select this option if you will be displaying small text sizes that won’t look good if they are antialiased. ✦ If file size is a concern, add only the characters that you are using for the text. Click the Partial Set radio button below the Characters option. Choose to include Punctuation, Numbers, and Roman Characters, and type in any individual characters that you want to include. Tip
If you are developing Director projects simultaneously on both the Windows and Macintosh platforms, using embedded fonts enables you to open and edit Text and Text Field cast members without losing their font attributes, even if the font is not installed on the user’s system.
Summary This chapter explained some of Director’s powerful text-handling capabilities. Among the topics discussed were these: ✦ Director supports three types of text: bitmapped text, RTF (Rich Text Format), and text fields. ✦ You can embed fonts in a movie, and you can apply embedded fonts to Text and Text Field cast members. Using embedded fonts ensures that the text will be displayed and edited correctly on any platform, even if the font is not installed on the user’s system. ✦ Rich Text can be antialiased, enabling you to remove or reduce the “jaggies” effect that often occurs with bitmapped text. ✦ You can flip, rotate, skew, and animate Text cast members in the same way that you perform those operations on a bitmapped cast member. ✦ HTML documents can be imported into Director and when imported, they retain their original formatting and hypertext links. ✦ Lingo scripts can be linked as external files that are automatically updated when the script is revised. ✦ You can edit the properties that determine the way text is displayed (if the text is editable), and you can change how the Tab key affects the Text cast member. The next chapter describes how to use sound in your Director movies.
✦
✦
✦
163
3486-6 ch04.f.qc
7/24/00
5:40 PM
Page 164
3486-6 ch05.f.qc
7/24/00
5:41 PM
Page 165
5
C H A P T E R
Using Sound
S
ounds add another dimension — an important one — to Director movies. Aside from putting dazzle into your movie, sounds fulfill a key concept of multimedia: to provide information in a format that maximizes the impact of the presentation. Multimedia is a multisensual method of relaying information to an audience. Whether you are creating a simple animated cartoon sequence or an elaborate interactive application, you essentially are teaching your audience about the topic of your movie. The mechanisms of learning are complex, but one simple axiom is always true: The more ways you present information, the better your chance of reaching your audience with positive results. Director supports a variety of digitized sound file formats that you can use to enhance your movies. In this chapter, you learn how to choose a sound format. You also learn the basics of importing and editing sounds for Director movies. When you understand sound theory and how Director deals with sound files, you have taken an important step toward using sound effectively with your audience in mind.
Sound Basics Sounds can take a movie from the mundane to the spectacular. They can inform, guide, and stimulate the interest of the user. Understanding Director sound basics provides the foundation you need for using sounds creatively and efficiently in your movies: Two key concepts should be behind every audio decision you make when working with Director and sounds: ✦ The first concept is to remember your audience. A sound should enhance the movie while balancing the needs and resources of the user.
✦
✦
✦
✦
In This Chapter Importing sounds into movies Digitized sound formats Adding sounds to your movies Editing sounds outside of Director File sizes and sampling considerations Using and editing sounds efficiently Working with sound Xtras
✦
✦
✦
✦
3486-6 ch05.f.qc
166
7/24/00
5:41 PM
Page 166
Part I ✦ Working with Director
✦ The second concept is actually more than that; it’s a law. Two types of files can bring a computer to its knees in nearly the blink of an eye: complex graphics files and sound files. Sound files can be huge, requiring significant resources to store and play them. Therefore, the law is to choose and edit sounds carefully, to balance creativity and file size. This section discusses importing sounds. It also discusses the difference between internal and external sounds, helps you choose among sound formats, and explains how you can edit sounds externally.
Importing sounds As the author of a Director movie, you need to make a number of decisions regarding a series of issues that affect the final movie. One issue, as already mentioned, is your audience. The audience is especially critical if your movie will contain sounds. Your audience may not have the system resources that you have, and thus balancing file size and quality factors with the goals of your movie becomes essential to the movie’s success. In selecting sounds for your project, you need to consider three factors: file format, sampling rate, and file compression. If you are developing a movie designed for both PC and Macintosh platforms, you can save a significant amount of time if you consider file format before creating the movie. Choosing a sound format supported by both platforms is one way of ensuring that you don’t need to create the movie twice. As your movies grow in size, finding individual sprites and cast members when you want them can become a tedious task. It’s easy to miss a single cast member and cause your movie to fail, especially if you must swap a number of cast members to conform to a specific platform. When you choose a sound for use in a Director movie, you should also be aware of the sampling rate and file compression. The basics of importing a sound file into Director are the same regardless of the sound format you choose. When you import a sound file into Director, it becomes a cast member that you can place in the Effects section of the Score. Unlike other types of cast members, sound cast members aren’t placed on the Stage.
Importing a Sound File into Director On the CD-ROM
The companion CD-ROM has several sound files that you can import into your movie and that you can use for the exercises in this chapter. They are found in the EXERCISE:CH05:AUDIO (EXERCISE\CH05\AUDIO) folder. This collection of sounds, generously provided by Jay Shaffer (copyright 2000 Zenapse), was downloaded from the Zenapse Web site at http://www.zenten.com/zenten.
1. Choose File ➪ Import or press Command+R (Ctrl+R) to display the Import Files dialog box (see Figure 5-1).
3486-6 ch05.f.qc
7/24/00
5:41 PM
Page 167
Chapter 5 ✦ Using Sound
Figure 5-1: Use the Import Files dialog box to select sound files and add them as cast members.
2. Choose the folder that contains the sound file that you want to import into Director, and then select the file. You can select multiple files by pressing the Shift key while clicking the files. Click Add to move the selected filenames into the File List. 3. Click the Media Option menu at the bottom of the window. From the pop-up list, choose Include Original Data for Editing if you want to use an external sound editor. This option enables you to quickly edit and update the sound in your movie, by launching the external editor when you double-click the cast member. 4. When you have selected all the files you want to import and added them to the File List, click the Import button to complete the operation and return to the Director window. The sound files you selected appear in the Cast window.
Using internal versus external sounds Internal and external sounds are stored differently, and managed differently by Director as well. When you import a sound into Director, it’s placed in the cast and considered an internal sound. (The cast member can be either an internal or external cast.) The sound information is saved with the cast or movie, which also increases the file size of the movie. External sounds, on the other hand, are linked by Director, which enables you to store the sound file separately from the movie, thereby reducing the movie’s file size.
167
3486-6 ch05.f.qc
168
7/24/00
5:41 PM
Page 168
Part I ✦ Working with Director
OLE and sound files: A bad match Director supports OLE functions. OLE (Object Linking and Embedding) is a difficult concept for many people, but it’s not as complicated as it seems. OLE enables you to easily share and edit elements between two OLE-compliant applications, without having to worry about import and export filters. The shared objects are transferred via the Windows Clipboard, from one application (known as the server application) to another application (the client application). OLE is primarily a Windows function, although a Mac OLE SDK (Software Developers Kit) exists and can be used to add OLE functions to Macintosh applications. When you use OLE, you can choose to either link or embed the object in the client application. Linking the element means that the element is stored separately from its associated document. Every time you open the associated document, the application searches for the object and moves it into the document. So, if you change the object, it will be updated when it appears in the client application. Embedding an object means it’s stored with the receiving document and isn’t updated each time you open that document. Both linking and embedding enable you to quickly edit the object and return to your document. It’s important to understand that OLE is designed to transfer text and graphics — not sounds — between applications. Director sees every OLE object, text and graphics both, in terms of a bitmap. OLE is not intended for the transfer of sound files, and sounds may become corrupted if this method is used to place them in documents. Some OLEcompliant graphics applications include sound editors, but you should never use OLE to place these files.
Tip
Consider storing large sound files in linked external casts. Doing so enables the sound to stream and reduces the file size of your movie.
Director preloads internal sounds into RAM before playing them. Although this works well for small sound files such as beeps, storing larger music sound files internally can cause a lag in the movie. External sound files are streamed, which means that they start playing while the rest of the file is loading. The drawback to external sound files is that if you move the sound file to another location, the link is broken and must be reestablished before the sound will play in your movie. Tip
Creating a folder to contain all the elements of your movie can save you a lot of grief when it’s time to output the movie. When files are stored using this method, all the files required for the movie are in the same location, which reduces the risk of losing a critical file. This storage method also reduces the amount of time it takes for Director to search for a specific file.
3486-6 ch05.f.qc
7/24/00
5:41 PM
Page 169
Chapter 5 ✦ Using Sound
Choosing a sound format Another audience issue when you’re working with sound files concerns resources. Sound file sizes typically range from large to humongous. These large files can bloat your movie, causing longer load times. And if the end-user has a system with limited resources, these files can cause the movie to crash. The choice of file format is, therefore, an important one. Director supports AIFF (Audio Interchange File Format) and WAV (Waveform Audio File) sounds, AU (Sun Audio), MP3 (MPEG 1 layer 3), SWA (Shockwave Audio), QuickTime Audio for Windows and the Macintosh, as well as Macintosh System 7 sounds. Director also supports RMF (Rich Music Format) files using the Beatnik Xtra by Headspace, although the files cannot be imported into the Cast window and must be controlled with Lingo. Use the following information to choose a sound format: ✦ WAV Files: WAV sound files are primarily Windows files, although they can be imported on the Macintosh platform also. Director supports WAV files compressed with IMA-ADPCM compression (Interactive Multimedia Association — Adaptive Differential Pulse Code Modulation). Be aware, however, that any compressed file must be decompressed (expanded) before it can be used. Compressed files are good for storage purposes, but they can take longer to load. ✦ AIFF Files: Although they don’t support compression, AIFF files have the advantage of being multiplatform. Both PCs and Macintosh machines can play AIFF sound files. This format is not a native format for the PC, but Director and a variety of other programs support AIFF on the PC without the use of external software. ✦ AU Files: This is a common sound format that is used on Unix workstations. Unless you are building scientific applications, you probably will not encounter this format. ✦ MP3 Files: Director supports files that are compressed using the MPEG 1 layer 3 compression. MP3 compression requires a lot of processor time to decompress. The MP3 format has exploded onto the scene within the last year, and there are now many sources for MP3 audio on the Internet. Caution
Just because an MP3 file is available for listening, does not mean that you have the right to use it in your multimedia application. Make sure that you have the author’s permission before using any MP3 audio files.
✦ QuickTime Audio: Digital QuickTime movies that contain only audio can be used in Director. They are imported and treated as any other QuickTime digital video cast member. To use QuickTime audio in your movies, QuickTime extensions must be present on the computer playing the audio file. Chapter 6 covers QuickTime digital video in detail.
169
3486-6 ch05.f.qc
170
7/24/00
5:41 PM
Page 170
Part I ✦ Working with Director
✦ Macintosh System 7 Files: If you are creating your movie on a Macintosh, you can record sounds from within Director by choosing Insert ➪ Media Element ➪ Sound. You need to have an audio input or microphone connected to your Macintosh. This feature is for Macintosh only, and it is not supported in the Windows version of Director. ✦ Shockwave Audio (SWA): Shockwave Audio files can be compressed up to a ratio of 176:1, and they can be streamed as well. You first need to use Director to create Shockwave Audio files from another type of audio file. You then can import or link the Shockwave Audio files to your movies. Creating Shockwave Audio files is covered in the “Working with Sound Xtras” section of this chapter. ✦ Rich Music Format (RMF): Using the Beatnik Xtra and Lingo, you can incorporate RMF files into your movie. RMF files take up very little disk space, yet they deliver outstanding audio quality. Rich Music Format files play back on both the Windows and Macintosh platforms as long as the Beatnik Xtra is installed on the user’s system or delivered with the movie. The drawback to using RMF files is that they can’t be imported into the Cast window and used in the sound channel like other audio files. Considering the small file size and amazing sound quality that this format provides, it’s worth taking the time to learn how to use RMF files. Chapter 18 explores Beatnik Xtra in more detail. Regardless of the chosen format, you need the assistance of a good sound editor to adjust the length and effects within your sound file. Optimizing sounds within your sound editor can help keep the file size small without compromising the quality of your movie.
Editing sounds externally Director doesn’t provide the capability to edit sounds within the program. Director does enable you to specify an audio-editing application in the program’s preferences, however. After you’ve specified an application, you can edit a selected sound cast member by choosing Edit ➪ Launch External Editor or by doubleclicking the cast member in the Cast window.
Specifying an External Sound Editor 1. Choose File ➪ Preferences ➪ Editors to display the Editors Preferences dialog box (see Figure 5-2). 2. Scroll through the list to choose the type of sound file for which you want to select an editor. In this example, the WAVE file type is selected.
3486-6 ch05.f.qc
7/24/00
5:41 PM
Page 171
Chapter 5 ✦ Using Sound
Figure 5-2: The Editors Preferences dialog box enables you to select an external editor for your sound files.
3. Click the Edit button. The next dialog box displayed reflects your choice of file type in the title bar; in this example, you see the Selected Editor for WAVE Sound dialog box (see Figure 5-3).
Figure 5-3: The Select Editor for WAVE Sound dialog box enables you to specify the application to use for editing your sound files.
4. Click the Browse button and then locate the audio-editing application on your hard drive. Select it, and it appears in the list window. Click Open to accept this choice. Click OK to close the Select Editor dialog box and return to the Editors Preferences dialog box. 5. If you want to select more than one sound-editing application, repeat Steps 2 through 4. If you select more than one application at this time, you will have to specify which one you want to be the active editor for your movie by highlighting the name. When you are satisfied with the settings, click OK to return to Director’s main window.
171
3486-6 ch05.f.qc
172
7/24/00
5:41 PM
Page 172
Part I ✦ Working with Director
Choosing a sound-editing application provides you with a quick bridge for editing your sound files. Instead of exiting Director and opening another program, you can simply launch the external editor from within Director. In addition, the changes you make are automatically incorporated into your movie, which reduces the need to delete and reimport cast members. Note
The Director 8 Studio includes a sound-editing program. If you are using the Windows version, the sound-editing program is Sonic Foundry’s Sound Forge XP4. The Macintosh version uses BIAS Peak LE as its sound editor.
Sampling rates, recording modes, and other issues Understanding a bit about a sound’s file size and quality will help you when you’re using an audio-editing application to process audio files for your movies. Factors that affect the size of a sound file are the sampling rate, recording mode (stereo or mono), bit depth, and compression method. It’s a good idea to choose the highest sampling rate possible when recording the original audio, and then sample it down later on in the editing process. The sampling rate is the frequency at which a sound is converted to digital format. A sampling rate of 44.1kHz, for example, means that the sound is sampled 44,100 times each second the sound lasts. In most cases, a sampling rate of 11.025kHz is good for voice recording, and 22.05kHz is fine for music-quality recording. Higher sampling rates result in a better recording. If you want to have a CD-quality recording, use a 44.1kHz sampling rate. Tip
Not all of the audio used in your movies needs to use the same settings. Rarely does a voiceover segment need to have CD audio quality. On the other hand, you might want a music soundtrack to be full stereo and sampled at CD quality. Carefully determining the needs for each segment of audio will help your movies sound more professional and yet stay within a reasonable file size.
Choosing mono recording mode rather than stereo is another way to yield a smaller file. Mono recording mode uses a single channel for the sampling, whereas stereo mode uses two channels to improve the quality of the sound. Figure 5-4 shows the same WAV file in both a stereo and a mono format, as represented in an audio editor. Note
A mono audio file is half the size of a stereo file at the same sampling rate.
Sounds are frequently resampled from 16-bit to 8-bit to save storage space. Typically, 8-bit sounds are lossy, which means information is lost in the translation from a higher bit depth, resulting in a poorer sound quality. If your sound editor supports the removal of silent bits of information and dynamic compression, you can edit a
3486-6 ch05.f.qc
7/24/00
5:41 PM
Page 173
Chapter 5 ✦ Using Sound
16-bit file prior to converting it to 8-bit. This editing improves the quality of the sound when it’s resampled to 8-bit. (For more information, see the documentation for your sound editor.)
Mono (one channel)
Stereo (two channels) Figure 5-4: Stereo and mono sounds represented in an audio editor Tip
You might find that 8-bit samples are noisier than 16-bit samples. You can get better quality if you lower the sampling rate from 22.5 kHz to 11.25 kHz and use a 16-bit sample, than if you use an 8-bit sound sampled at 22.5 kHz — even though the file size is approximately the same.
Table 5-1 compares the file sizes that result when applying various sampling rates and recording modes to a sound file in the humongous range. I chose a 74-second file for comparison because the differences between the file sizes were so dramatic; most sound files aren’t this long. Looping sound enables you to give the illusion of a longer sound file without straining the resources of a computer (see “Looping Sounds,” later in this chapter).
173
3486-6 ch05.f.qc
174
7/24/00
5:41 PM
Page 174
Part I ✦ Working with Director
Table 5-1 File Size Comparison for Different Sampling Rates/Recording Modes Sampling Rate
16-Bit Stereo
16-Bit Mono
8-Bit Stereo
8-Bit Mono
44.1 kHz with compression; WAV file format
3.15MB
1.57MB
1.57MB
812K
22.5 kHz with compression; WAV file format
1.58MB
812K
812K
412K
11.25 kHz with compression; WAV file format
818K
412K
412K
376K
44.1 kHz WAV file format
12.5MB
6.29MB
6.29MB
3.14MB
22.5 kHz WAV file format
6.29MB
3.14MB
3.14MB
1.57MB
11.25 kHz WAV file format
3.14MB
1.57MB
1.57MB
805K
44.1 kHz AIFF file format (AIFF does not support compression)
17.9MB
8.95MB
8.95MB
4.47MB
Obtaining sounds for your movies The first step in obtaining sounds for your movies is to determine the type of sound files you need. Some multimedia projects require voiceovers; others require specialeffects sounds (SFX), such as a bell or thunder. On the CD-ROM
Several demos from audio providers are on the CD-ROM. One of our favorites is a demo from Rarefaction, which makes a series of music and effects CD-ROMs called A Poke in the Ear.
If your sound card supports audio input, you can record your own sounds, either by using a microphone directly connected to your sound card or by transferring sounds from tape to your computer. You can find a variety of sound sources on the World Wide Web and through companies that market sound clips. Some of these sound files are considered public domain, which means that you can use them freely. Others are protected by copyright laws and licensing agreements. If you have questions regarding these laws, the licensing information for a particular sound file, or both, contact the source before including the sound file in any project. Tip
If you are creating movies on the Macintosh, you can record sounds directly into Director by choosing Insert ➪ Media Element ➪ Sound. In the Macintosh Sound Recording dialog box that opens, record the sound by using the built-in microphone. Unfortunately, this feature is not available to Windows users.
3486-6 ch05.f.qc
7/24/00
5:41 PM
Page 175
Chapter 5 ✦ Using Sound
With a clear idea of what you need and a little research into the available sources, you can incorporate any sound you can imagine into your project. Audio files can quickly consume gigabytes of hard drive disk space. If you’re using large amounts of audio for your movie, we suggest that you avoid recording directly to your computer. It’s far better to record to high-quality tape and then transfer the sounds to your computer as you need them.
Tip
Adding and Editing Sounds One of this book’s authors was in a situation in which he had less than two days to create an animation sequence of an alien being interviewed by a reporter. Given the tight deadline, he had to create the animation of the alien talking before the voiceover was recorded. Because he couldn’t add the audio track until the very last minute, having the alien’s mouth move in sync with the audio would have been almost impossible to pull off successfully. To solve the problem, he had the alien talk telepathically, indicated by a forehead wrinkle that moved when the alien spoke. This technique enabled him to rough-in the animation before the voice-over track was recorded and digitized, and then make minor adjustments to the movie after the audio files were imported into Director. This trick saved a lot of time and turned out to be a very comical effect. Sure, none of this was terribly complicated, but it required time and a little creative ingenuity. It also required knowing how to manage a sound and use sound channels after the sound was imported into the movie.
Placing sounds in the Score After your sounds have been imported as cast members, you are ready to place them in your movie. On the CD-ROM
The companion CD-ROM has several sound files that you can import into your movie for this exercise. You can find them in the EXERCISE:CH05:AUDIO (EXERCISE\CH05\AUDIO) folder.
Placing a Sound Cast Member in the Score 1. Start by opening the movie into which you want to place a sound. 2. Director enables you to hide or show the Effects channels in the Score (by default, they’re hidden). To turn the Effects channels off and on, click the Hide/ Show Effects Channels button in the Score window, as shown in Figure 5-5.
175
3486-6 ch05.f.qc
176
7/24/00
5:41 PM
Page 176
Part I ✦ Working with Director
Figure 5-5: Click the Hide/Show Effects Channels button to display or hide the effects channels.
3. In one of the sound channels, click the location where you want the sound to start. Note
The Score displays two channels for sound. Although Windows technically supports only one, Director supports multiple sound channels and enables you to place sounds in both of the visible sound channels in the Score, which is accomplished by mixing the two sound channels together to produce a single channel on Windows-based machines. Additional channels beyond the visible two are accessible only through Lingo or via digital video.
4. Drag the sound cast member from the Cast window to the location you selected in the Score (see Figure 5-6). When you release the mouse button, the sound cast member appears in the Score in the location you selected. Alternatively, you can drag the sound cast member to the Stage. Although Director cannot place sound members on the Stage, it automatically places the sound in the first available sound channel of the Score for the current frame, and it becomes a sound sprite.
Figure 5-6: The sound cast member appears in the sound channel at the location you specified in the Score.
3486-6 ch05.f.qc
7/24/00
5:41 PM
Page 177
Chapter 5 ✦ Using Sound
When you create a new sound sprite, Director assigns it a default length (28 frames). You may need to adjust the length of an individual sprite (by extending it in the Score) to ensure that the sound plays completely. If you find that this situation occurs frequently, you may want to adjust the Span Duration amount in the Sprite Preferences dialog box (choose File ➪ Preferences ➪ Sprite), so that you aren’t constantly having to change the length of sprites.
Changing the Default Length for Sprites 1. Choose File ➪ Preferences ➪ Sprite to display the Sprite Preferences dialog box (see Figure 5-7). 2. In the Span Duration section of the dialog box, enter a new value in the Frames field. 3. Click OK to return to Director’s main window.
Figure 5-7: Adjusting the default sprite length
Setting a default length for sprites is a good policy, but any given cast member may require more or fewer frames.
Adjusting the Length of Individual Sound Sprites 1. In the Score window, drag the last frame of the sound sprite you want to adjust. To make the sound sprite longer, drag to the right, as shown in Figure 5-8; to make the sprite shorter, drag to the left. As you drag, you can see the sound sprite extending or contracting in length. 2. Rewind the movie and play it. Continue adjusting in the same way until you are satisfied with the length of the sound. Tip
To keep your movie compact, adjust the frame length of sprites to a sufficient length, but no more than what is required to achieve the desired effect.
177
3486-6 ch05.f.qc
178
7/24/00
5:41 PM
Page 178
Part I ✦ Working with Director
Figure 5-8: Adjust the length of a sprite by dragging the end of the sprite. Note
You can also set a tempo statement to force the movie to wait until a sound finishes playing (see “Using Cue Points in a Movie” later in this chapter).
Using channels effectively Director doesn’t limit you to playing a single sound at a time. Director displays two sound channels for your use. You can play two sounds at the same time; in addition, you can add more sound channels by using Lingo commands (see Chapter 18). Playing multiple sounds is useful if you are creating a complex multimedia project and need to gather a variety of sounds. For example, in a movie about a jungle expedition, you might want sounds of birds, animals, people talking, and native drums. It would be difficult to pull all those sounds together into a single audio file. You can have all those sounds by alternating sounds in Director’s two sound channels. Look at the two sound channels in Figure 5-9. The sound sprite in channel 1 is ambient background noise (an alien spacecraft in this instance). The sound sprites in channel 2 are voice-overs that provide information about the current activity in the movie. What you can’t see is the editing that coordinates the sounds in both channels. The background noise becomes softer when the sprite in channel 1 is playing; it becomes louder when channel 1 is silent. Director doesn’t have an independent capability to alter the volume of a single channel without using Lingo. The volume editing for this example was done in an external sound editor. In addition to volume changes, you can add other mixing effects, such as echoes and fades. By carefully editing your sound files, you can customize the sounds to fit the mood or theme of your movie.
3486-6 ch05.f.qc
7/24/00
5:41 PM
Page 179
Chapter 5 ✦ Using Sound
Figure 5-9: Using both sound channels, you can simultaneously play two sounds in your movie.
Managing Sounds Adding sound to a short and simple movie is a process of simply dragging the sound cast member to the Score. The sound starts to play when the playhead reaches the beginning frame of the sound, and the sound plays to the end of its allotted number of frames. But what happens when your movies become more complex and lengthy, containing several sounds and not just one or two? Managing these sounds involves several tasks: You control when a sound plays, whether it repeats, and whether the movie pauses for the sound. Good sound management not only enhances your movie, but it also can be critical to the success of your multimedia applications. New Feature
Director 8 introduces several new Lingo commands that expand Director’s audio playback capabilities. These commands give greater control over various aspects of creating a movie, such as looping, transport, cue points, panning, and crossfading. Chapter 18 discusses these new commands.
179
3486-6 ch05.f.qc
180
7/24/00
5:41 PM
Page 180
Part I ✦ Working with Director
Using cue points in a movie Director makes it easy to control the pace of your movie by using cue points in audio files. You use cue points to mark a position at which you want an event to occur in a digital audio or digital video file. In Windows, you can use either SoundForge XP4 or CoolEdit; on the Macintosh, you can use either BIAS Peak LE or SoundEdit 16 to place cue points in audio and digital video files. Suppose that you want to create an animated tour of an art museum. Adding narration at each stop on the tour would enhance the movie enormously. By placing cue points in the voice-over, you can pause the playback head at a specified frame that displays an exhibit in the museum, until the voice-over has finished giving the information about that exhibit. When the cue point is reached, the movie continues to the next frame or exhibit. The cue points ensure that the timing for each scene in the movie matches the voice-over.
Incorporating Cue Points On the CD-ROM
In this exercise, you can use the cuepoint.dir file found on the companion CD-ROM in the EXERCISE:CH05 (EXERCISE\CH05) folder.
1. Open the cuepoint.dir movie in Director. The sound file called idunno has already been imported and placed into the movie. This audio file contains four cue points that were added before importing it into the movie. 2. There are four markers in the movie. Although it’s not necessary to use them, markers make it easier to determine the exact spot in the movie where you want to add the cue point (see Figure 5-10).
Figure 5-10: Adding markers to indicate where to add cue points makes it easier to organize your animation.
3486-6 ch05.f.qc
7/24/00
5:41 PM
Page 181
Chapter 5 ✦ Using Sound
3. Double-click frame 10 — identified by a marker labeled add percussion — in the tempo channel. The Frame Properties: Tempo dialog box appears, as shown in Figure 5-11.
Figure 5-11: Specifying the pause to wait for a cue point
4. Click the Wait for Cue Point option. 5. Open the Channel list and select the sound file. 6. In the Cue Point list, select the cue point named Add percussion. 7. Repeat Steps 3 through 6 for the Add synth and Begin fade markers. The cue points in the audio file have the same name as the markers. 8. Rewind the movie and play it back with the Score window open. The playback head advances until it hits a cue point; it then waits until the audio file reaches that cue point, and then it continues to advance until it reaches another wait for cue point command. Note
If the frame does not include a sound file with cue points, the only option on the Cue Point pop-up list is {No Cue Points}.
Tempo, sounds, and interactivity Director enables you to place interactive elements, such as forms, buttons, and other effects, in your movies. It’s important to remember that once a sound begins to play, it plays to the end of its allotted frames. This can cause a conflict with interactive elements, such as a sound attached to a button. Although you can’t stop the sound (except through the use of Lingo), you can control the other sprites and elements of your movie. You can avoid conflicts between sound, tempo, and interactivity by using Lingo commands to play the sounds. (Methods for using Lingo to control interactivity, sound, and animation are discussed in the Lingo portion of this book.)
181
3486-6 ch05.f.qc
182
7/24/00
5:41 PM
Page 182
Part I ✦ Working with Director
Caution
It’s a good idea to avoid using the same frame for a sound or digital video cast member and several other effects sprites. The sound or digital video can take control of the movie, and it’s difficult to predict the order in which the other effects will play. In addition to the problem of playing order, this arrangement can cause a brief but critical hit on the resources of low-end computers. To alleviate this conflict, duplicate the frame and specify a different effect for each frame; this helps you control the playing order and manage resources — without memory or effects conflicts.
Looping sounds You can get a lot of mileage out of very small and brief sound files. Many of the sounds around us are repetitive: the roar of thunder, the pounding of surf, footsteps, a ringing bell, the din of city traffic, a murmuring crowd. With some careful editing, together with Director’s capability to loop sound, you can add sounds without significantly increasing the file size of your movie. Director offers you two non-Lingo methods of repeating a sound. You can specify that you want just the sound to loop, or you can include the sound in a film loop. On the CD-ROM
For the next exercise, you can import any of the audio files that begin with the word loop that are located on the CD-ROM in the EXERCISE:CH05:AUDIO (EXERCISE\CH05\AUDIO) folder.
Setting a Sound to Loop 1. In the Cast window, select the sound that you want to loop. 2. Click the Properties button in the Cast window to activate the Property Inspector. You may need to click on the Sound tab to activate the Sound Properties window (see Figure 5-12).
List view toggle button
Play/Stop buttons
Figure 5-12: Setting a sound to loop
3486-6 ch05.f.qc
7/24/00
5:41 PM
Page 183
Chapter 5 ✦ Using Sound
3. Mark the Loop check box, and click the Play button to hear the sound loop. Whenever you use this cast member in a movie, it will loop. Note
The sound playback function is available only in the Normal View mode of the Property Inspector. If you are in List View mode, click the View Mode toggle button to switch to the Normal View mode.
Caution
If you are placing the member into a sound channel, you need to make sure that it spans enough frames to play the entire sound. Otherwise, it will sound clipped (cut off).
Looping sound is an effective means of getting the most from small sound files. If your sound is coordinated with a specific animation sequence, consider including the sound in a film loop with the animation. In the next exercise, you add a sound file to a graphic animation sequence created by using the Cast to Time command to create a film loop that contains both graphics and audio. CrossReference
Chapter 3 discusses using the Cast to Time command for animating and creating film loops.
Including a Sound in a Film Loop On the CD-ROM
Use the movie called orb.dir on the CD-ROM for the following EXERCISE:CH05 (EXERCISE\CH05).
1. Open the orb.dir movie in Director, and then open the Cast window by choosing Window ➪ Cast or by pressing Command+3 (Ctrl+3). 2. Select the cast member named Drone sound and drag it into sound channel 1 of the Score window so that it begins in frame 1. Then click the tail of the sprite and drag it to frame 10 (see Figure 5-13).
Figure 5-13: Drag the tail of the Drone sound sprite to frame 10.
183
3486-6 ch05.f.qc
184
7/24/00
5:41 PM
Page 184
Part I ✦ Working with Director
3. In the Cast window, click the cast member named orb01, and then hold down the Shift key and click the cast member named orb10. Choose Modify ➪ Cast to Time to insert the cast members into the movie as a single sprite. 4. In the Score window, make sure the orb01 sprite starts in frame 1. If it does not start in frame 1, drag the sprite so that it begins in frame 1, click the drone sound sprite in sound channel 1, and then press the Shift key and select the orb sprite in sprite channel, 1 as shown in Figure 5-14.
Figure 5-14: Select the sound and sprites that you want to use for the film loop.
5. Choose Insert ➪ Film Loop to create the film loop. Give the film loop a meaningful name, and then click OK; the loop appears in the Cast window. After you’ve created the film loop, you can delete the selected sprites from the Score (but not from the cast). 6. Drag the film loop from the Cast window to the Score and place it in a sprite channel. 7. Open the Control Panel by choosing Window ➪ Control Panel or by pressing Command+2 (Ctrl+2). Set the playback to loop. Rewind your movie and play it. 8. You can add keyframes and tween the film loop to have the sprite move around the Stage. (If you are unfamiliar with these techniques, refer to Chapter 3 for detailed instructions.) Tip
You can’t create a film loop with only sounds. You must include other sprites or the Loop option will be unavailable. However, you can create a shape with the Floating Tool Palette that has no fill or outline and use it as the sprite.
3486-6 ch05.f.qc
7/24/00
5:41 PM
Page 185
Chapter 5 ✦ Using Sound
Back doors to sounds Earlier in this chapter, we stated that without Lingo you are restricted to using the two visible sound channels to play one sound each. That’s not exactly true. You can trick Director into playing more sounds — by using film loops that contain a different sound in each loop. This technique enables you to have a unique sound in each film loop, and one in each of the sound channels. The only limitation to this trick is the availability of resources. In fact, this “back door” technique is problematic for systems with limited resources. If you include a digital video in a film loop, the sound attached to the video is disabled. The animation, however, isn’t disabled.
Setting the volume for a movie Director enables you to set the volume for your movie and save the volume settings both with the file and when the movie goes to distribution. As mentioned earlier in this chapter, you can’t control the volume of individual elements such as sounds or digital videos within your movie without using Lingo or a behavior. CrossReference
Chapter 18 discusses controlling sound with Lingo.
When you set the volume of a movie, it’s important to remember that computers respond differently to volume settings. You cannot determine the volume levels that are set for a user’s computer. It’s a good idea to set the volume settings in the medium range, and to assume that users will adjust the volume to suit their computers and their individual tastes. You can set the volume of your movie by using the Control Panel or the Volume command: ✦ If you choose Control ➪ Volume, select a volume level from the pop-up menu. ✦ If you use the Control Panel, click the Volume button and choose a volume level from the pop-up menu (see Figure 5-15). Tip
When choosing a volume level, it’s a good idea to take into account any sound editing that you’ve done. The idea is to keep the median sound level consistent (with the exception of fades and effects). Your movie will have less impact if the volume is constantly changing.
185
3486-6 ch05.f.qc
186
7/24/00
5:41 PM
Page 186
Part I ✦ Working with Director
Figure 5-15: Click the Control Panel’s Volume button to select a volume for your movie.
Working with Sound Xtras If you read Chapter 1, you already know a little about Xtras — small plug-in applications or scripts that enhance movies and expedite production by performing a series of tasks related to the selected sprite, frame, cast member, or movie. Xtras may come from a third-party developer or from Macromedia. Director includes a variety of Xtras for your use, such as Behaviors, Shockwave Audio (SWA), and Beatnik Lite. If you are a programmer, you can also develop your own Xtras for use with your movies. CrossReference
For more coverage of Xtras, see Chapter 26.
Using Shockwave Audio (SWA) Director’s built-in compression method for audio is called Shockwave Audio (SWA). The SWA Xtra compresses both internal and external sound files, yielding much smaller file sizes than other compression routines. Caution
Shockwave Audio will not compress MP3 or SWA files.
You can use Shockwave Audio to compress sound files to be used for the Internet and on disk: ✦ External sound files can be streamed. Streaming means that the sound file begins to play as it is downloading. Users don’t have to wait for the entire file to load before hearing sound. Streaming can be critical to the success of a Director project on the Internet, where you need to be conscious of file sizes and download times. Shockwave Audio will not stream sounds compressed at values lower than 16Kbps (kilobits per second). ✦ Although internal sounds can’t be streamed, you can still enjoy a good rate of compression without degradation of quality. When you specify Shockwave Audio settings for internal sounds, all of the sounds are compressed. You can’t compress some sound files and not others.
3486-6 ch05.f.qc
7/24/00
5:41 PM
Page 187
Chapter 5 ✦ Using Sound
Shockwave Audio works only with compressed Director movies. Although you can specify compression settings at any time during the creation process, they actually don’t take effect until you compress the movie by creating a projector or a Shockwave movie, or by using the Update Movies command. When you distribute a movie compressed using Shockwave Audio, you must include the Xtras to decompress and play the sound. Generally, this is automatic, but it’s a good idea to make sure that you distribute all the associated files with your movie.
Note
Understanding Shockwave compression Shockwave Audio enables you to compress sound files up to a 176:1 ratio, which creates a much smaller file than other sound formats. The bit-rate scheme used by SWA is not related to the bit rate used to sample sound files; instead, it is related to the speed of transmission. Therefore, the higher the compression rate, the faster the download, the decompression, and the playing of the sound. Remember that some degradation of the sound quality occurs, as it does with most compression. SWA technology, however, changes the file as little as possible to achieve the desired compression. It’s a good idea to try a variety of compression values and check the quality of the sound. Then choose the best quality that balances the type of sound, movie, and distribution you intend to use. For example, a voice-over doesn’t require the same quality needed for music, and it can be compressed safely at a lower rate, between 8Kbps and 16Kbps transfer rate. Table 5-2 shows the optimum compression ranges for Internet use. These rates are not for the user, but rather on the server end, for delivery.
Table 5-2 Optimum Shockwave Audio Compression Ranges
Note
Delivery System
Compression Bit Rate
Quality Capability
T1
64 Kbps to 128 Kbps
Extremely high quality
ISDN or CD-ROM
32 Kbps to 56 Kbps
FM stereo to CD quality
28.8 modem
16 Kbps
FM mono or AM quality
14.4 modem
8 Kbps
Telephone quality
Director automatically converts any file with a compression rate below 48Kbps to monaural.
187
3486-6 ch05.f.qc
188
7/24/00
5:41 PM
Page 188
Part I ✦ Working with Director
In the next exercise, you learn to compress the audio files in your movies, using Shockwave Audio. In previous versions of the program, this operation was located under the Xtra’s menu. In Director 8, you choose File ➪ Publish Settings to find this operation.
New Feature
Compressing Internal Shockwave Sound Cast Members 1. Choose File ➪ Publish Settings, and then click the Compression tab to display the Shockwave Audio settings section (see Figure 5-16). Figure 5-16: Specifying compression settings for internal sound cast members.
2. Click the Compression Enabled check box to enable compression. 3. Click the kBits/second list box and choose the bit rate that you want to use for compression. See Table 5-2 to help determine the best bit rate for your application. 4. If you a want to convert the sound to mono from stereo, click the Convert Stereo to Mono check box to enable this conversion. 5. Click OK to complete the operation and return to Director’s main window. CrossReference
Other settings in the Compression tab deal with compressing the images in your movie. Chapter 8 discusses these options.
When you distribute a movie that uses Shockwave Audio Compression, you need to include the SWA Xtra with the file. You can choose to have it downloaded to the user’s computer via Shockwave’s automatic download capability, but it will need to be present for the compression to work. Note
If your movie uses MP3 or SWA audio, the compression setting will not affect the audio.
3486-6 ch05.f.qc
7/24/00
5:41 PM
Page 189
Chapter 5 ✦ Using Sound
Compression schemes are a bit like snowflakes in a blizzard. No two of them are identical, and there are many from which to choose. The sound industry is struggling to establish standards to provide commonality across platforms. Director supports a variety of compression types, either directly or though the use of Xtras. The best idea is to choose the type that meets your platform needs, while providing the best quality for your movie.
Compressing and Streaming External Sound Cast Members On the CD-ROM
To practice converting WAV files to SWA and linking them as external sound files, use any of the WAV files on the companion CD-ROM in the EXERCISE:CH05:AUDIO (EXERCISE\CH05\AUDIO) folder. There is also a ready-made SWA file in the same folder, called idunno.swa.
1. Create an external Shockwave Audio file (SWA). Macintosh users can create this file using Bias Peaks LE. Windows users can use Director’s conversion command by choosing Xtras ➪ Convert WAV to SWA. The dialog box that appears enables you to specify the external sound files you want to convert (see Figure 5-17). Note
Macintosh users can skip Steps 2 through 7. Figure 5-17: Windows users can convert WAV files to SWA files.
2. Check the bottom of the dialog box. If the Folder for Converted Files indicated is not the folder in which you want to store your files, click Select New Folder. Navigate to a folder where you want to store your files, and then click Select Folder to return to the Convert WAV Files to SWA Files dialog box. (It’s a good idea to keep all associated Director files in the same directory, especially if you intend to distribute your movies on the Internet.)
189
3486-6 ch05.f.qc
190
7/24/00
5:41 PM
Page 190
Part I ✦ Working with Director
3. Click the Add Files button, and then navigate to and select the files that you want to convert. To select multiple files, press the Command (Ctrl) key and click each filename to highlight it. When all desired files are selected, click the Open button. If the files you need to convert are not in the same folder, you might have to repeat this step more than once. Selected files are displayed in the Files To Convert list. To delete a file from the list, select it and then click the Remove button. 4. Choose the Compression Settings you want to use. (For guidance, refer to the earlier instructions for compressing internal files.) 5. When you have added all the files to be converted and you have specified the compression settings, click the Convert button to begin the conversion. A progress bar appears, and you can watch as the compression occurs. 6. When the compression is complete, click the Close button to return to Director’s main window. 7. The compressed files are still external to your movie, so now you must add the sounds to your internal cast. Choose Insert ➪ Media Element ➪ Shockwave Audio. 8. When the SWA Cast Member Properties dialog box shown in Figure 5-18 appears, click the Browse button, navigate to the location where you saved the converted Shockwave Audio files, and double-click the one (or ones) you want to import. The conversion process automatically compresses the movie and changes its extension to .SWA, so look for files ending with this extension. You can use a URL (an Internet address) as the Link Address for the SWA file. Note
For this step, you can also use the idunno.swa file that’s on the CD-ROM in the EXERCISE:CH05:AUDIO (EXERCISE\CH05\AUDIO) folder.
Caution
The location or link you specify for the SWA cast member must remain the same or else a broken link occurs and the movie will fail. To reduce the possibility of broken links, store all linked files in the same folder.
Figure 5-18: The SWA Cast Member Properties dialog box enables you to specify the options for SWA cast member Xtras.
3486-6 ch05.f.qc
7/24/00
5:41 PM
Page 191
Chapter 5 ✦ Using Sound
9. Specify a sound channel. The default is Any, which enables Director to assign a sound channel based upon availability. 10. Choose a Preload Time from the list box. This figure represents the maximum number of seconds that can lapse prior to streaming your sound. Because slow Internet connections can affect the transfer times, it’s a good idea to choose a higher value than the 5 seconds Director uses as a default. 11. Specify the volume you want to use for your sound file. It’s best to choose a medium volume as a compromise for all platforms. 12. Click the Play button to preview the sound. Click OK to return to Director’s main window. 13. Repeat Steps 8 through 12 for each SWA file that you want to use. 14. Place each of the SWA cast members in a sprite channel (not a sound channel), and extend the sprite to ensure that the sound plays completely. Using linked Shockwave Audio cast members for Web-based Director movies is a way to reduce the download time. Because the audio is actually a separate file located on a server, it doesn’t need to be downloaded with the movie. This feature also makes it possible to update the file independently of the rest of the movie.
The Beatnik Xtra Lite The Beatnik Xtra — built by a company called Headspace Incorporated — is similar to their Beatnik player for Web browsers, and enables you to use RMF (Rich Music Format) audio files in your movie. The RMF file format was developed to take full advantage of the Headspace Audio Engine, a multiplatform, General MIDI-compatible, 64-voice synthesizer that features custom downloadable sample files and enables you to create very sophisticated digital audio processing effects. The Beatnik Xtra also supports most other standard audio formats, such as WAV, AIFF, and MIDI. Rich Music Format audio files take up very little disk space, yet they provide an outstanding level of audio quality and are an ideal sound format to use for Shockwave applications. Unfortunately, RMF files cannot be imported into Director and placed in the score as a music sprite. You must use the new Lingo commands provided with Beatnik Xtra to incorporate RMF files into your movie. The up side to this is that you have a wide range of control over the sounds, and you can create very complex audio effects. Figure 5-19 illustrates an application of the Beatnik Xtra. CrossReference
Chapter 18 teaches you to use the Lingo commands and behaviors for the Beatnik Xtra.
191
3486-6 ch05.f.qc
192
7/24/00
5:41 PM
Page 192
Part I ✦ Working with Director
Figure 5-19: Using the Beatnik Xtra, you can create very complex audio effects.
Using Sound Behaviors Director enables you to alter the behavior of your movies by using Lingo scripting. The trade-off is that Lingo is a complex scripting language. If you aren’t familiar with programming or scripting languages, adding Lingo scripts to your movies can be daunting. In response to this challenge, Director uses behaviors. Behaviors are cast members added to sprites and frames of your movie to easily provide interactive functionality without complex scripting. You can find the built-in behaviors that come with Director in the Library Palette. New Feature
Director 8 includes four new sound behaviors — Pause Sound, Stop Sound, Channel Volume Slider, and Channel Pan Slider — that take advantage of the new sound capabilities added in this version of the program.
Director includes six built-in behaviors in the sound category. Each requires that you provide parameters, such as the name of a sound, the channel assignment, and the event that you want to use to start the behavior. Table 5-3 lists the behaviors and describes the usage and parameters that you can apply.
3486-6 ch05.f.qc
7/24/00
5:41 PM
Page 193
Chapter 5 ✦ Using Sound
Table 5-3 Director’s Built-in Sound Behaviors Behavior
Description
Parameters
Play Sound
Used on the Stage, Score, or a sprite to play an assigned audio file.
Sound to play Defines the cast member used by the behavior Sound channel Choose which channel to use for playback When to play sound The event that triggers the sound Preload sound When to load the sound into memory before playing Seconds to preload Determines how many seconds of the sound are preloaded Number of loops Sets how many times the sound plays (0 = forever)
Pause Sound
Used on the Stage, Score, or a sprite to pause the sound in a defined channel.
Sound channel Assign which sound channel to pause When to pause sound Set the event that triggers the pause
Stop Sound
Used on the Stage, Score, or a sprite to stop the sound in a defined channel.
Sound channel Assign which sound channel to pause When to stop sound Set the event that triggers the pause
Sound Beep
Causes the system beep to play when a sprite that has the behavior applied to it is clicked.
None
Channel Volume Slider
Apply this behavior to a graphic sprite to turn it into a slider that controls the volume of the sound being played.
Sound channel Define which sound channel this slider controls Constraining sprite Assigns a sprite that determines direction and distance of slider movement (a setting of 0 uses the Stage for the constraint) Initial sound volume Sets the volume level for the chosen sound channel when the slider first appears Continued
193
3486-6 ch05.f.qc
194
7/24/00
5:41 PM
Page 194
Part I ✦ Working with Director
Table 5-3 (continued) Behavior
Description
Parameters
Channel Pan Slider
Apply this behavior to a graphic sprite to turn it into a slider that controls the pan from left to right of the sound being played.
Sound channel Define which sound channel this slider controls Constraining sprite Assigns a sprite that determines direction and distance of slider movement (a setting of 0 uses the Stage for the constraint) Initial sound pan Sets the initial pan setting for the chosen sound channel when the slider first appears
When you add a behavior from the Library Palette to a sprite or frame, the behavior is copied to the internal cast, to prevent the master behavior from being accidentally overwritten. Included in the Library Palette are a series of behaviors related to sound. For example, consider a movie that displays a series of musical instruments. By adding a behavior to each of the instrument sprites, you can play a sound file that makes the sound of that instrument when an event occurs. In the case of the instruments, you might want the sound to play when the user clicks the instrument. To display the Library Palette, choose Window ➪ Library Palette, and then display the sound behaviors (shown in Figure 5-20) by clicking the Library List button in the upper-left corner of the palette. Then choose Media ➪ Sound. CrossReference
Director’s behaviors and how to work with them are discussed in detail in Chapter 7.
Figure 5-20: Director’s built-in sound behaviors are located in the Library Palette.
3486-6 ch05.f.qc
7/24/00
5:41 PM
Page 195
Chapter 5 ✦ Using Sound
Summary Sound enhances your movies, and it adds the professional finishing touch to make your movie a success. By understanding sound basics, you can easily add sounds to your movies. In this chapter, you learned how to: ✦ Choose sound file formats that meet your platform’s authoring needs. ✦ Add sound to your movie and control it with tempo settings. ✦ Link larger sound files as external files. Place smaller sound files in the internal cast. ✦ Get the most out of sounds through repetition by using looping and by duplicating small sound files. ✦ Store Director files and linked files in the same location to prevent broken links and to improve loading time. ✦ Use behaviors to give sounds interactive functionality. ✦ Employ the Shockwave Audio Xtra to get the maximum compression for your sound files, and to use streaming audio. ✦ Use sound cue points to control the pace of your movie. Chapter 6 teaches you to incorporate digital video into your movies.
✦
✦
✦
195
3486-6 ch05.f.qc
7/24/00
5:41 PM
Page 196
3486-6 ch06.f.qc
7/24/00
5:41 PM
Page 197
6
C H A P T E R
Using Digital Video
✦
✦
✦
✦
In This Chapter
D
igital video is simply the result of capturing, storing, transmitting, and displaying a rapid succession of digitized images on a computer. The why of digital video is perhaps as important as the what. As mentioned earlier in this book, it is by appealing to multiple senses that multimedia enhances communications and increases the effective retention rate of the user. Digital video provides a superior means of transmitting images and sounds of real-world events and animations in your Director movies. The result, of course, is that the impact of your movies on your audience increases. Director movies containing digital video are appearing with increasing regularity in our world. Using digital video enables you to create: ✦ Interactive kiosks ✦ Training CD-ROMs that display complex procedures ✦ High-impact sales presentations ✦ Edutainment titles (movies that entertain as well as educate) ✦ Virtual 3D worlds, using Apple’s QuickTime VR technology. The variety of movies that you can create with Director is limited only by your imagination. Whether your movie will grace a boardroom or a home computer, that movie can be enhanced with digital video. Director uses two video formats, AVI (Video for Windows) and QuickTime. AVI movies can be imported into Director only from the Windows platform — they will play back on both platforms, though. An AVI movie is converted to a QuickTime movie when it’s played on the Macintosh platform. The AVI
Understanding digital video Adding digital videos to your movie Managing video cast members Exporting as digital video Using QuickTime VR
✦
✦
✦
✦
3486-6 ch06.f.qc
198
7/24/00
5:42 PM
Page 198
Part I ✦ Working with Director
format has other severe limitations as well. AVI digital video movies, for example, can be played only in Direct to Stage mode (discussed later in this chapter). There are also very few Lingo commands that you can use to control AVI videos. Director offers much more support for the QuickTime video format on both the Windows and Macintosh platforms. Using the QuickTime video format enables you to take advantage of the wide range of QuickTime movies that you can create, including audio-only movies and 360-degree QuickTime VR panoramas. Director also gives you much more Lingo control over digital videos that use the QuickTime format. QuickTime is the industry standard for digital video, and it is very prevalent on the Web. If possible, you should use QuickTime digital videos for your movies to take full advantage of all the features that Director provides for incorporating digital movies into your multimedia applications. On the CD-ROM
CrossReference
To get the most out of the exercises in this chapter, you should have QuickTime 3.0 or 4.0 installed on your computer. If you need QuickTime 4.0, you can find the installer for both Windows and the Macintosh on the companion CD-ROM in the UTILITIES&SHAREWARE:APPLE:QUICKTIME (UTILITIES&SHAREWARE\APPLE\ QUICKTIME) folder. There are also several QuickTime movies that you can use for the exercises in this chapter. They are in the EXERCISE:CH06:VIDEO (EXERCISE\ CH06\VIDEO) folder. The topics in this chapter introduce working with digital video. Director is a robust program that offers features for all levels of users, and in Chapter 19 you work with digital video at a more advanced level by learning to manage this medium with Lingo.
Working with Digital Video A series of factors is involved in the creation of any digital video. In terms of Director movies, the most important of these factors are frame rate, image dimensions, color depth, file size and compression, and image quality.
Determining an effective frame rate Frame rate is the number of frames per second (fps) that are displayed on a screen. A rate of 30 fps represents high quality, but it’s unrealistic. Most computers don’t have the resources to display video at that rate, and the amount of hard disk space required to store such data is prohibitive. For any system to display digital video without disruption to quality, it must be capable of transferring data at a consistent rate of 150,000 bits (150K) per second. The amount of data contained in a digital video with a frame rate of 30 fps is enormous. Consequently, lower-end computer systems are incapable of transferring and rendering this amount of data at the required rate to maintain quality.
3486-6 ch06.f.qc
7/24/00
5:42 PM
Page 199
Chapter 6 ✦ Using Digital Video
A frame rate of 15 fps is much more realistic. Most computers can display this information without too much difficulty, enabling you to widen the range of your potential audience by choosing this lower rate.
Working with image dimensions When you are planning a Director movie, a key consideration is the final resolution at which the movie will be displayed. Director offers a variety of preset stage sizes, or you can specify a custom size that meets your needs. Before choosing a screen size, you should consider the typical computer configuration of your audience. For example, if you are developing a multimedia application that will be used in a corporate environment, you can safely assume that users will have 17-inch monitors set at 800 × 600 resolution. If you are developing for schools, which tend to have older computers, you may want to use a resolution of 640 × 480 to match the resolution of older 15-inch monitors. Director displays digital video in a window placed on the Stage. The default size of the window is equal to the exterior dimensions of the digital video frame. Although you can display a digital video at 640 × 480 pixels or larger, the file size would be prohibitive and might cause resource problems on low-end computers. Most computers are capable of playing back digital video at a resolution of 320 × 240 (the default size for a QuickTime movie) without any difficulty. You can also create your digital video at a smaller or custom frame size. Note
Director enables you to crop digital videos. For more information on cropping, see the later section “Scaling and Cropping a Digital Video.”
Considering color depth By default, Director for Windows plays all video in Direct to Stage mode (discussed later in this chapter) at a 24-bit color depth. On a Macintosh, the video is displayed at either 8-bit or 24-bit color depth. If your video hardware on a computer running the Windows operating system is set for 8-bit or 16-bit color depth, Director has to recomposite the image display to 24-bit. The result is a performance reduction in your movies. The digital video may appear jerky or slow. For best results in Windows, then, use digital videos that are set at 24-bit. If you get jerkiness or slowness in your 8- or 16-bit digital video, you can improve performance by sequencing images by using image and movie editors, or by respecifying cast member settings. The next exercise explains how to resequence images to improve performance. The section “Adding Digital Videos to Your Movies” later in this chapter discusses setting member properties.
Sequencing images to improve video performance Editing 8-bit and 16-bit images to improve video performance in Director is a somewhat tedious task, but if performance is a critical issue, it’s worth the effort. If the frames of the video are already stored as individual images, you are one step into the process. If they are not, you need to break your video into individual frames.
199
3486-6 ch06.f.qc
200
7/24/00
5:42 PM
Page 200
Part I ✦ Working with Director
Note
The following instructions for sequencing are very general. For more targeted instructions, consult the user manuals for your video and image editors.
Sequencing Images for Your Video 1. Import your video into a video editor, such as Adobe Premier (see Figure 6-1). If you already have the images set up as individual frames, skip to Step 5.
Figure 6-1: You can use a video editor such as Adobe Premier to convert an image into a sequence.
2. Export the video as a sequence of individual bitmap images or frames. Windows users will find it easier to save the images as BMP files, and Macintosh users should save the images as PICT files. 3. Open the sequence of images in a bitmap image editor or image converter, such as Equilibrium’s Debabelizer or Adobe Photoshop version 5.0 or later. (If your bitmap image editor or image converter allows for batch functions, this process will go more rapidly.) 4. Convert the images to RGB 24-bit images and save them. 5. Reimport the sequential images into your video editor. 6. Create a video file from the images. The video file is ready to import into Director.
3486-6 ch06.f.qc
7/24/00
5:42 PM
Page 201
Chapter 6 ✦ Using Digital Video
Getting the best performance from animated sprites We all like to see the exotic. Sometimes, however, exotic animated sprites cause a movie to slow too much and to play at less than the desired frame rate. Suppose that your movie has a 24-bit sprite of a colorful parrot wildly flapping its wings. The bit depth of the color and the animation might reduce the performance of your movie, especially if other sprites are active at the same time. To adjust for this problem, you could reduce the color depth of the parrot or create a film loop. Neither of those options, however, is as effective as exporting the animation sequence as a digital video. After the digital video is created, you can import it and place it in your movie. The parrot maintains its color, the animation is smoother, and the performance of your movie improves.
Be aware that this method can be a formidable task if your image editor or converter doesn’t support batch functions. For instance, sequencing 20 seconds of digital video that has a frame rate of 15 fps requires converting 300 frames! CrossReference
For more information on exporting frames as digital videos, see the section “Exporting Digital Video,” near the end of this chapter.
Controlling file size and choosing compression Like other graphics and sound files, digital video files tend to be on the large side. The average video that plays in your VCR requires 10 inches of videotape for each minute of play at 30 fps. An equivalent digital video file could take as much as 1.6GB of hard disk space. The amount of space required varies, depending on other factors in the creation of computer imagery, such as color depth and resolution. Even with the frame rate reduced to 15 fps, an uncompressed digital video file can consume several hundred megabytes of disk space. The issue of file size has prompted substantial research to find a standardized means of compressing the data to an acceptable size. A variety of codec (compression/decompression) methods are available. At the time of this writing, however, there is no standardized file compression method that works with all platforms. Director does support some file-compression techniques employed in conjunction with Apple’s QuickTime and Microsoft’s Video for Windows AVI (Audio Video Interleave) format. It’s important, nevertheless, that you design your movie carefully to use a codec that is cross-platform if you intend to incorporate digital video files. To achieve compression, most codecs reduce the amount of information stored with the file. Like the proverbial cutting room floor, bits and pieces of the original data are cut out to create a smaller file. A hierarchy determines which data is cut. The human eye is extremely discerning of color but doesn’t as readily perceive
201
3486-6 ch06.f.qc
202
7/24/00
5:42 PM
Page 202
Part I ✦ Working with Director
slight differences in brightness or motion. Compression schemes, therefore, typically cut information that refers to minor changes in both brightness and motion. Many digital video files contain sound, and — again, because people tend to notice a disruption in sound before they notice a disruption in image quality — frames of the video may be sacrificed in order to maintain the sound quality. Note
QuickTime is designed to give audio priority, whereas AVI is not. If the audio quality is important, you might want to use the QuickTime Video format for your digital video.
MPEG format Director doesn’t directly support the MPEG (Motion Picture Experts Group) format for digital video files. Xtras are available, however, that enable MPEG video to be imported into Director. MPEG uses interframe compression to achieve compression rates of up to 200:1. Interframe compression analyzes each frame of a video for redundancy, to create what are called reference frames. By comparing previous and subsequent frames in a video, only the difference between the frames is stored. Redundant information is removed, and the result is a smaller file. Like most compression schemes, files compressed using MPEG can be lossy (as the compression ratio goes up, the quality of the video is reduced). MPEG is less lossy, however, than compression schemes employed by the QuickTime or AVI formats. You can play MPEG in your Director movies with the assistance of any of the following: an Xtra, Lingo MCI messages, a Windows driver, or a Macintosh system extension designed for this purpose. The drawback with MPEG is that each type of software implements the compression differently, and this can make it difficult to control the quality of playback on all types and platforms of computers.
Selecting an image quality Probably the most important factor in making decisions regarding digital video in Director is image quality. We’ve saved discussion of this final factor for the last because it determines your final decision. You must decide what look is acceptable for your movie, given the constraints of file size and performance. The decision on how you use digital video is subjective, but should be influenced by your client’s needs, the characteristics of the target audience, and the content of your end product. Ask yourself these questions: ✦ Is there a truly valid need for the digital video to be full-screen and, if so, will the end-user’s computer system support the required data transfer rates without choking? ✦ Using a smaller digital video window would lose what content? Would there be a significant loss of clarity, or detail, or both?
3486-6 ch06.f.qc
7/24/00
5:42 PM
Page 203
Chapter 6 ✦ Using Digital Video
✦ Is there supplemental content that should be concurrently displayed on screen with the digital video — which might necessitate less than a full-screen digital video window? ✦ How will the end product be delivered (over the Internet, on CD-ROM, in a stand-alone kiosk format, and so on)? Will that medium handle the quantity of digital video? With the range of possibilities available (various codecs, frame rates, image size, and so on), only you can determine how much of your movie’s resources should be dedicated to the delivery of digital video. Be sure to consider what’s happening in the rest of the screen(s) across which the digital video plays. In most cases, your Director movie and the video in it will have more consistent performance and greater impact if you design the layout for the video to play in a smaller window.
Note
Adding Digital Videos to Your Movies Digital video files are imported and placed in the Cast window in the same manner as other files, but Director manages digital videos differently. By default, all digital videos are imported in Direct to Stage mode as linked files rather than contained in the movie. When Director links a file to your movie, it places a thumbnail of the cast member into the internal cast, as it would for any other cast member. In reality, the thumbnail doesn’t represent the actual file, however. It is a pointer to the location where the file is stored. When you save the movie, the location is stored with the movie. If you move the file to another location, Director won’t be able to find the file, and your movie won’t run correctly. To avoid this problem, store linked files, such as digital videos, in the same folder as your movie. Alternately, for better organization, you can store all the video files in a folder that is “down directory” from the movie. In other words, they will be in the same folder, just one layer deeper. Caution
Unlike sound files, you cannot include digital video sprites in a film loop. Although the video will appear at the appointed time in the film loop, it won’t play.
On the CD-ROM
There are two QuickTime digital video movies on the accompanying CD-ROM, landing.mov and radar.mov, that you can use for this exercise. They are in the EXERCISE:CH06:VIDEO (EXERCISE\CH06\VIDEO) folder. For better performance, you may want to copy the files to your hard drive.
Importing a Digital Video Cast Member 1. Open a new movie in Director and choose File ➪ Import to display the Import Files dialog box (see Figure 6-2).
203
3486-6 ch06.f.qc
204
7/24/00
5:42 PM
Page 204
Part I ✦ Working with Director
Figure 6-2: You select the digital video files that you want to place in your movie in the Import Files dialog box.
2. In the Show: File Type menu, choose QuickTime (Mac) or Video Clip (Windows). This restricts the file list to only those digital video files that are supported by Director. 3. In the Media list menu at the bottom of the window, choose Include Original Data for Editing if you want Director to include a pointer back to the video editor you specified in the Editor Preferences dialog box. This enables you to quickly access your video editor by double-clicking the associated cast member in the Cast window. 4. To import a single file, select it in the file list and then click the Import button. Or, if you want to choose more than one file or choose files from several folders, click the Add button instead, and the files will be listed in the file list window. When you’ve finished selecting your files, click Import to complete the operation and return to Director’s main window. The digital video cast members appear in the active cast. Note
You can also insert QuickTime movies by choosing Insert ➪ Media Element ➪ QuickTime. When you choose this operation, an empty cast member appears. Click on the Properties button to display the Cast Member Properties dialog box, and then click on the Options button. When the QuickTime Xtra Properties dialog box appears, click on the Browse button, and locate the movie that you want to import into Director.
After your files are placed in the cast, you can put the videos on the Stage and test their performance. Similar to other sprites, Director extends the video sprite across the number of frames you specified in the Sprite Preferences dialog box (displayed by choose File ➪ Preferences ➪ Sprite).
3486-6 ch06.f.qc
7/24/00
5:42 PM
Page 205
Chapter 6 ✦ Using Digital Video
Placing a Digital Video on Stage 1. Import a video file into your movie, and then click the frame in the Score where you want the digital video to start. 2. Drag the digital video from the Cast window to the location you selected in the Score. Alternatively, you can drag the digital video cast member to the Stage. Director places the video sprite in the first open channel of the active frame (see Figure 6-3). When you place the video into the Score and play the movie, the cast member appears on top of any other elements on Stage, regardless of its channel position. This is because Director, by default, imports digital videos with the Direct to Stage property set to TRUE. The Macintosh version of Director enables you to turn off the Direct to Stage option, but Director for Windows does not.
Figure 6-3: Place your digital video cast member in the Score, and extend the sprite to make sure that the video plays completely.
3. Rewind your movie and play it. If the video doesn’t play completely, click the end frame of the video sprite and drag it to the right to extend it. The sprite must extend through sufficient frames for it to play completely. Note
You can also set the Tempo to a slower frame rate by double-clicking a frame in the Tempo channel in the Score window and selecting a slower frame rate. A slower tempo setting does not affect the playback speed on the video, only the speed of the playback head as it moves across the frames in the Director movie.
4. Rewind and play your movie again. Repeat Step 3 as needed to ensure that the video plays completely. Tip
If you’d like to preview your video, you can choose Window ➪ Video, or press Command+9 (Ctrl+9). Your video appears in the Video window. If the video is a QuickTime (.mov) file, a control bar appears at the bottom of the window, enabling you to play, stop, advance, or rewind the movie. When the movie is stopped, you can cut, copy, and paste frames from one video to another.
205
3486-6 ch06.f.qc
206
7/24/00
5:42 PM
Page 206
Part I ✦ Working with Director
Understanding Direct to Stage mode Director supports QuickTime movies for both Macintosh and Windows. You can also import Video for Windows (AVI) files for use in the Windows version of Director. Both QuickTime and AVI formats enable you to incorporate audio effects in the file. When you place videos on the Stage, Director displays them using the default Direct to Stage option. This option allows for the best speed and smoothest display of digital video in a Director movie. Because this is the recommended way to use video in a Director movie, it is important to design the layout of your presentation so that the space required to play the video doesn’t interfere with other elements on the Stage. Direct to Stage has both advantages and drawbacks, however. When this option is enabled, you can sync your video to the soundtrack, effectively modifying the speed with which frames are displayed. You can also specify that Director play every frame, and set the maximum speed for the playback of your video. As noted earlier in this chapter, if you specify a frame rate, the video will play at the fastest speed possible, given resources and the frame rate of the video. It won’t play faster than the embedded frame rate, however. One drawback to the Direct to Stage option is that it places the digital video in front of every sprite on the Stage, regardless of the channel in which the video sprite is placed in the Score. Another limitation is that ink effects and transitions don’t work. Without the use of ink effects, it’s nearly impossible to conceal the perimeter rectangle that surrounds the movie window. Tip
It’s possible to have a QuickTime movie play in Direct to Stage mode, and yet still have it display in a nonrectangular format, by assigning a 1-bit cast member to act as a mask for the video. The default setting enables the video to show through the black pixels of the image. This advanced technique can only be accomplished using Lingo.
You can enable or disable the Direct to Stage option in the Digital Video Cast Member Properties dialog box.
Enabling or Disabling Direct to Stage 1. With the video cast member selected, choose Modify ➪ Cast Member ➪ Properties or click the Cast Member Properties button in the Cast window to display the Digital Video Cast Member Properties tab in the Property Inspector (see Figure 6-4). 2. Click on the Direct to Stage check box to enable or disable the option. If a check mark appears in the box, the option is enabled.
3486-6 ch06.f.qc
7/24/00
5:42 PM
Page 207
Chapter 6 ✦ Using Digital Video
Figure 6-4: The Direct to Stage check box is located in the QuickTime Tab of the Property Inspector.
Direct to Stage
Note
The name of this dialog box reflects the format in which the video was created. A QuickTime movie was used when creating Figure 6-4, so the tab box is called QuickTime.
Choosing whether to use Direct to Stage is a matter of assessing the needs of your movie. If the video has audio properties and you need to sync the video to the sound, leave Direct to Stage enabled. If it’s more important that your video blend in with the background, or if you have sprites that need to animate above the video, you’ll want to disable Direct to Stage. Remember that when this feature is disabled, you’ll be able to apply ink effects to your video and transitions to the frame.
Syncing video to sound If you are creating a video with sound for use in a Director movie, it’s a good idea to map or sync the audio file to the video before importing it into Director. Adobe Premiere and other video editors provide the tools to ensure that the sound plays at the same frame rate as the associated video portion of the file. Taking the time to sync your video and sound beforehand helps you manage the way Director processes such files. By default, Director syncs the frame rate of your video to match the embedded audio track. This syncing makes your movie appear more polished, but Director will skip playing frames in your video, if necessary, to achieve syncing; and skipping frames can produce undesirable results. You can avoid this by telling Director not to skip frames (if the video has no sound or you don’t need the sound to play). Do this by choosing Play Every Frame for the Video selection in the cast member’s Properties dialog box. Be aware, however, that choosing Play Every Frame disables sound.
207
3486-6 ch06.f.qc
208
7/24/00
5:42 PM
Page 208
Part I ✦ Working with Director
Digital video properties As you saw in the preceding exercise, you can set several other properties for your QuickTime digital videos. As with most other cast member properties, the List View mode of the Property Inspector, shown in Figure 6-5, labels the properties as they are referred to in Lingo scripts. It’s important to understand how each of these properties affects the way that digital video files will play back in your movies. Table 6-1 describes all of the properties you can set for QuickTime digital video. Figure 6-5: The List View mode of the digital video member properties labels them as they are referred to in Lingo scripts.
Note
The properties in Table 6-1 are listed as they appear in the List View mode of the Property Inspector.
Table 6-1 QuickTime Digital Video Properties Property
Description
sound
Plays the embedded sound in a video if enabled.
pausedAtStart
When enabled, causes the video to remain on its first frame when it appears on the Stage. You need to use Lingo to set some kind of event to trigger it.
3486-6 ch06.f.qc
7/24/00
5:42 PM
Page 209
Chapter 6 ✦ Using Digital Video
Property
Description
loop
When checked, the video loops back to the first frame and plays again continuously.
preload
Enables a video to preload into system memory before it’s played. This allows for better playback performance but increases the memory demands of your movie. Use with the Lingo command preloadRam to control how much of the video file is loaded into memory.
frameRate
Determines the frame rate at which the movie will attempt to play back. The user’s system resources will have as much, if not more, effect on the frame rate. Set this property by clicking on the arrow and adjusting the slider to the desired frame rate. To have the video synchronize to an embedded soundtrack, set the value to 0. To set the frame rate to the Normal setting, type –1 into the value; for the Maximum playback setting, type –2 into the field.
streaming
Determines whether a video will stream when played back over the Web. This feature is only supported on systems that have QuickTime 4 installed. It will have no effect on systems that have older versions of QuickTime. Can be set in both the Playback Properties and the Display Properties sections.
percentStreamed
Available only in List View. If streaming is enabled, it returns the percentage of the file that has been downloaded to the user’s computer. This property cannot be set. It only returns a value.
directToStage
Renders the video directly to the user’s screen. Plays the video at optimum performance but cannot be used if other sprites need to appear on top of the video or if ink effects need to be applied
crop
Enables the video to be cropped on the Stage. Set it to false if you want to scale a digital video.
center
When set to true, the video appears in the center of the rectangle created when cropped. Has no effect unless crop is enabled.
video
Enables the video of a digital video member to play. Set to false if you only want the audio to play.
controller
Enables the standard QuickTime controller to be displayed. Defaults the pausedAtStart property to true when enabled.
Mask
Available only in List View. Assigns a 1-bit cast member — used as a mask — in which the video will appear. The default setting is for the video to appear in the black pixels of the member.
invertMask
When a 1-bit cast member is assigned as a mask for a video, the video appears in the white pixels of the cast member instead of in the black pixels of the member.
209
3486-6 ch06.f.qc
210
7/24/00
5:42 PM
Page 210
Part I ✦ Working with Director
New Feature
Director now supports QuickTime 4.0’s streaming capabilities.
CrossReference
Other options for controlling digital video in your Director movies are available through Lingo commands. See Chapter 19 for further details.
Scaling and cropping a digital video Director enables you to scale and crop digital video cast members. Because the scale and crop options are cast member options, they affect the entire sprite rather than a single frame. Normally it’s not a good idea to scale any type of bitmap image, even a digital video, by a large amount. Scaling degrades the quality of the image, especially if you increase the size. Video editors don’t always enable users to create custom frame sizes, though, and your movie might call for a size that fits a specific area of your movie’s layout. If you can live with some degradation of quality to get a custom fit, then try scaling and see what you get. First, use your video editor to create the closest size for your needs. Then you can scale the video in small amounts to create the custom size, while minimizing the loss of quality. On the CD-ROM
For the next three exercises, start with the sim.dir movie located on the CD-ROM in the EXERCISE:CH06 (EXERCISE\CH06) folder. This Director movie contains two QuickTime digital movies. If you move the movies to your hard drive, make sure that you include the folder called video at the same level as the sim.dir Director movie.
Scaling a Digital Video 1. In the Cast window, select the video cast member called landing and drag it onto the Stage so that the video sprite is positioned as shown in Figure 6-6. 2. Choose Modify ➪ Cast Member ➪ Properties (or press Command+I or Ctrl+I) to display the Property Inspector. You may have to click on the QuickTime member tab to make it the active window. 3. In the Framing section, click the Scale radio button to enable the option. Click OK to return to Director’s main window. 4. On the Stage, drag the handle in the lower right corner to resize the video sprite so that it fits inside the black box. The video appears scaled on the Stage (see Figure 6-7). 5. Save the movie as sim1.dir. You can also crop a video. This capability is useful if you want to display a portion of the video within its bounding box. Although cropping has a similar appearance to scaling, it doesn’t actually resize the image. It merely hides a portion of the image. If you stretch the bounding box of the video later, it will reveal portions of the image that were previously hidden.
3486-6 ch06.f.qc
7/24/00
5:42 PM
Page 211
Chapter 6 ✦ Using Digital Video
Before scaling
Figure 6-6: Position the video sprite on the Stage.
After scaling
Figure 6-7: Scale the video sprite so that it fits in the window. Tip
By cropping your videos, you can reduce a distracting background. Cropping is also useful for creating special effects within your movies by enabling you to focus on a particular section of an image.
Cropping a Video 1. Open the sim1.dir movie from the last exercise, if it’s not already open. Select the video cast member named radar in the Cast window.
211
3486-6 ch06.f.qc
212
7/24/00
5:42 PM
Page 212
Part I ✦ Working with Director
2. Click the Properties button in the Cast window to display the Digital Video Cast Member Properties tab in the Property Inspector. 3. Under Framing, click the Crop radio button to enable the option, and then click the Center check box so that the video remains centered inside the bounding box after it is cropped. Then click OK to return to Director’s main window. 4. Drag the radar video cast member onto the stage. Note that there is a distracting yellow background surrounding the video (see Figure 6-8).
Before cropping
Figure 6-8: Remove the yellow background by cropping the video sprite.
5. On the Stage, drag the handles of the video sprite’s bounding box so that the yellow background is eliminated. Position the sprite in the window on the right, as shown in Figure 6-9. 6. Save the movie as sim2.dir. Rewind the movie and play it back. Caution
When you scale the Stage, the video sprite appears at its original size. If you try to crop a video with the Stage set at a zoom level other than 100%, you will get unexpected results.
Setting looping and controller preferences When you played back the movie in the preceding exercise, you were probably thinking that it would be nice to have the radar video constantly looping to create a more realistic effect. The Digital Video Cast Member Properties dialog box also enables you to specify looping and whether you want a visible controller for the video. Both of these settings affect the behavior of your movie.
3486-6 ch06.f.qc
7/24/00
5:42 PM
Page 213
Chapter 6 ✦ Using Digital Video
After cropping
Figure 6-9: The video sprite is cropped and moved into position.
If you set a video to loop, the action repeats until the playback head goes beyond the number of frames you’ve allotted for your video. If looping is not enabled, the video plays to the end and then displays the last frame of the video until the playback head moves beyond the last frame you allotted for your video. To enable/disable looping, check the Loop check box in the Playback options. If you enable Show Controller, a control bar appears below your movie that enables the user to start, stop, and step through the movie. The Show Controller check box option is available only if Direct to Stage is enabled. Caution
It’s not a good idea to enable the controller for a video cast member if it will be scaled, cropped, or used while another video is playing. This puts a huge demand on the system resources and can cause all kinds of strange things to happen.
Looping a Digital Video 1. Open the sim2.dir movie in Director if it’s not already open, and then select the radar video cast member. 2. Click the Properties button in the Sprite Overlay to display the Digital Video Cast Member tab in the Property Inspector. 3. Click the Loop check box to enable the option. Then click OK to return to Director’s main window. 4. Rewind the movie and play it. The radar screen now continuously rotates while the other video is playing. 5. Save the movie as sim3.dir.
213
3486-6 ch06.f.qc
214
7/24/00
5:42 PM
Page 214
Part I ✦ Working with Director
Specifying an external editor for Video cast members You can specify an external editor for a video cast member, so that you can quickly jump to an editing application outside of Director to modify your digital video. Double-click a cast member for which you’ve specified an external editor, and Director starts the editor and opens the video in it. After you’ve modified your video, save the changes and click Exit; the video cast member is updated automatically with the modifications that you made in the editor. Tip
You can edit a QuickTime movie in Director. This technique is discussed later in this section.
Specifying an External Video Editor for Video Files 1. Choose File ➪ Preferences ➪ Editors to display the Editors Preferences dialog box. 2. Scroll through the file type list, and select Video Clip (see Figure 6-10). Figure 6-10: Choose the file type for which you want to use an external video editor.
3. Click the Edit button to display the Select Editor for Video Clip dialog box. 4. Select the Use External Editor option, and then click either the Browse button or the Scan button (shown in Figure 6-11). If you click Browse, the Open dialog box appears; this is where you can navigate to the executable file that starts your video editor. If you click Scan, Director scans your computer for possible editors by searching for program files, and presents you with a list from which to choose. 5. Select the editor that you want to use, and click Open to return to the Editors Preferences dialog box. Click OK again to complete the operation and return to Director’s main window.
3486-6 ch06.f.qc
7/24/00
5:42 PM
Page 215
Chapter 6 ✦ Using Digital Video
Figure 6-11: Choosing an external video editor
Normally, double-clicking opens a QuickTime digital video in Director’s Video window. If you assign an editor, however, this action opens your video in the external editor you specified.
Note
Editing a digital video within Director There are times when you need to resequence images, or use only a portion of a digital video that you have imported into your movie. You can use an application that is capable of editing the video file, or you can perform some editing operations within Director itself. Although the process is a bit cumbersome — and you don’t have the accuracy and special effects capability that video-editing programs such as Adobe Premiere have — it’s very useful to be able to perform these operations in Director, especially if you don’t have a video-editing application on your computer. When you double-click on a QuickTime video cast member — provided you have not assigned an external editor for QuickTime — the QuickTime window opens up, as shown in Figure 6-12. The video appears in the window, along with a controller that enables you to play the entire movie, step through the movie one frame at a time, or jump to a particular section of the movie. You can also use the controller to select a specific range of frames and then copy the frames into a new video cast member. Caution
When you modify a video cast member, you are actually changing the original file to which the cast member is linked. It’s a good idea to make a copy of the movie that you are about to modify so that you have the original version of the movie in case you need to use it again.
On the CD-ROM
For this exercise, you can import the QuickTime movie called landing.mov, located on the CD-ROM in the EXERCISE:CH06:VIDEO (EXERCISE\CH06\VIDEO) folder.
215
3486-6 ch06.f.qc
216
7/24/00
5:42 PM
Page 216
Part I ✦ Working with Director
Play button
Video controller
Playback head
Single frame advance button Single frame reverse button
Figure 6-12: Double-clicking on a video cast member opens the QuickTime window.
Resequencing a QuickTime Movie 1. Double-click on a QuickTime video cast member to open it in the Video Cast Member window. 2. Select the beginning section of the video by moving the playback slider in the controller to the point where you want the selection to begin. 3. Hold the Shift key down and move the playback slider to the point in the movie where you want the selection to end. The section of the video that is selected shows up as a black area in the controller bar (see Figure 6-13). Figure 6-13: You can select a section of the video.
Selected section of video
3486-6 ch06.f.qc
7/24/00
5:42 PM
Page 217
Chapter 6 ✦ Using Digital Video
Tip
Use the single-frame buttons or the arrow keys on the keyboard to fine-tune the selection.
4. Copy the selection to the Clipboard, and then click on the New Cast Member (+) button to create a new video cast member. 5. Paste the selection in the new window, and a dialog box appears, prompting you to create a new QuickTime movie file (see Figure 6-14). Select the location where you want to store the movie, and then type in a name for the file. Figure 6-14: Select a location to store the new movie and type in a name for the file.
Note
Even though the movie was created in Director, it is still stored as an external file that is linked to the Director movie. Make sure that you don’t move the file to a new location after it is created or it will not play in the Director movie.
6. Back up to the previous video cast member by clicking the Previous Cast Member (left arrow) button at the top of the window, and repeat Step 3 to select another section of the video. 7. Copy the section, and then advance to the new video cast member by pressing the Next Cast member (right arrow) button. 8. Move the playback head to the position in the movie that you want to be the endpoint of the selection that you are pasting in. An alert message appears, warning you that you are about to change a linked file (see Figure 6-15). Click OK. The selection is then inserted into the movie. Figure 6-15: This alert message warns you that you are about to modify a linked cast member.
217
3486-6 ch06.f.qc
218
7/24/00
5:42 PM
Page 218
Part I ✦ Working with Director
Caution
You cannot undo this operation because it is being performed on an external file. It’s a good idea to create a copy of the cast member so that you don’t accidentally ruin the original one.
9. Press the Play button in the controller to view the changes that you have made to the video cast member.
Controlling Video Cast Members Often you need to have the movie wait on a particular frame until a video has reached a specific point or has finished playing. Suppose that you have several sprites that represent status lights on the Stage that need to change color as the video progresses. It would be almost impossible to accurately synchronize the lights changing with the video, due to the variety of computer systems your Director movie might be played on. As you already know, digital video can be quite the resource hog and it’s difficult to accurately predict how it will play on any given system. The most straightforward way to accomplish this without using Lingo is by setting tempo settings that tell Director to wait on a frame until a specified point in the video has played.
Specifying tempo settings Director enables you to specify tempo settings to control the way your movie interacts with video cast members. This is useful for pausing the movie while waiting for a video to finish playing. You can also use tempo settings to control the video and interactive portions of the movie. By setting cue points in the digital video, you can have the Director movie pause until the video has reached the predetermined cue point. After the digital video has reached the cue point, the Director movie continues. Before Director can recognize a cue point set within a video, however, you must first define the cue point, using an application that is capable of inserting cue point into a digital video. Both BIAS Peak LE 2 on the Macintosh and SoundForge XP4 on Windows — the default soundediting applications supplied with the Director Studio — are capable of performing this operation. The QuickTime movie landing.mov that you have used in previous exercises has several cue points added to it. You use the landing.mov file in the next two exercises to insert tempo settings that control the playback of the Director movie On the CD-ROM
You can use the vidcue1.dir and vidcue2.dir movies on the CD-ROM located in the EXERCISE:CH06:VIDEO (EXERCISE\CH06\VIDEO) folder for these exercises. If you copy the movies from the CD-ROM to your hard disk, make sure that you also put a copy of the folder called video, which contains the imported landing.mov QuickTime movie, into the same folder on your hard disk into which you copied the Director movies.
3486-6 ch06.f.qc
7/24/00
5:42 PM
Page 219
Chapter 6 ✦ Using Digital Video
Pausing a Movie to Wait for a Video to Finish Playing 1. Open the vidcue1.dir movie in Director, and display the Score window. If the effects channels are not visible, click on the Hide/Show Effects channel button to display the effects channels. 2. Double-click the Tempo channel in frame 60, located directly below the marker named “end” (shown in Figure 6-16) to display the Frame Properties: Tempo dialog box.
Tempo channel
Figure 6-16: Double-clicking in the Tempo channel of a frame that contains a video sprite causes the Frame Properties: Tempo dialog box to appear.
3. Click the Wait for Cue Point radio button to enable that option, and select the video from the Channel list. 4. In the Cue Point list, choose {End}, as shown in Figure 6-17. Click OK to return to Director’s main window.
Figure 6-17: Choosing {End} as the Cue Point forces Director to wait for your video to finish before continuing to the next frame of your movie.
219
3486-6 ch06.f.qc
220
7/24/00
5:42 PM
Page 220
Part I ✦ Working with Director
5. Drag the Score toward the bottom of the screen so that both the video sprite and the Score window are visible on the Stage; then rewind the movie and play it. In the Score window, the play head pauses at the {End} cue point you inserted in the Tempo channel until the QuickTime movie finishes playing, and then advances to the next frame. Even if you don’t have any cue points in your video, choosing {End} for the cue point setting causes Director to wait for the video to finish playing before continuing to the next frame of your movie. Tip
It’s not necessary to add markers to your movie in order to insert a cue point. Putting markers in your movie at the frames where you will insert cue points, however, makes it much easier to organize the movie if you’re adding more events that need to occur when the movie reaches a cue point.
Pausing a Movie to Wait for a Specific Cue Point in the Video 1. Open the vidcue2.dir movie in Director, and then make the Score window active. If the effects channels are not visible, click on the Hide/Show Effects channel button to display the effects channels. 2. Note the markers that have been placed in the Marker channel of the Score (see Figure 6-18). These markers are labeled with the same name as the actual cue points that you will insert into the Tempo channel.
Cue point markers Figure 6-18: Adding markers to the frames where you want to add cue points makes it easy to identify the frames where the cue points will be inserted.
3. Double-click the Tempo channel in frame 9, directly below the marker called Side view. The Frame Properties: Tempo dialog box appears. 4. Click the Wait for Cue Point radio button to enable the option, and then select the Side View cue from the Cue Point pop-up menu (see Figure 6-19).
3486-6 ch06.f.qc
7/24/00
5:42 PM
Page 221
Chapter 6 ✦ Using Digital Video
Figure 6-19: Select a cue point from the Cue Point pop-up menu.
5. Repeat Steps 3 and 4 to insert cue points underneath the Ortho view, Top view, Interior view, and Touch down markers. The markers are labeled with the same names as the cue points that you’re going to insert.
Note
6. Double-click on the Tempo channel in frame 60 (directly below the marker named end) and insert an {End} cue point. 7. Drag the Score window toward the bottom of the frame so that the video and text sprites are visible on the Stage. Rewind the movie and play it. Note that the text sprite is changing along with the scene changes in the QuickTime movie. Using cue points enables you to pace your movie and coordinate video events. To stop or pause a video, however, you need to add video controls by using Lingo or the Video Behaviors located in the Library Palette. CrossReference
More sophisticated integration of video, sound, and interactivity is accomplished by using Lingo statements within your movie. Chapter 19 discusses using Lingo to control digital video.
Working with video behaviors Behaviors are small Lingo scripts that control interactivity and the behavior of sprites. The video behaviors are located on the Library Palette. Open the Library Palette by choosing Window ➪ Library Palette. To access the video behaviors, click the Library List button in the upper-right corner of the palette and then choose Media ➪ QuickTime. When you apply a video behavior, a dialog box prompts you to enter parameters that control the behavior. Examples of parameters are the channel number of the video sprite or the number of frames the video occupies. Chapter 5 introduced you to behaviors for sound. Behaviors are prepackaged Lingo scripts with which you can quickly and easily control cast members. You just select
221
3486-6 ch06.f.qc
222
7/24/00
5:42 PM
Page 222
Part I ✦ Working with Director
the behavior that you want to use and drop it onto the sprite in the Score window or on the Stage. Director then prompts you for the parameters that define the action you want to apply. The advantage of using these two new features is the ease with which you can quickly create scripts. For example, you can create a custom control bar for your QuickTime cast member that enables the user to play, stop, or pause the video. The Library Palette contains two built-in Behaviors that you can use to control several different properties of QuickTime movies: ✦ The QuickTime Control Button behavior can be applied to a sprite that will act as a button to control the QuickTime video sprite. The parameters that you can set with this behavior are: Play, Rewind to the beginning of the video, Jump to the end of the video, Fast Forward at 2X the speed, or Fast Rewind at 2X the speed. You could easily make a VCR-like control panel to control QuickTime movies with this behavior. ✦ The QuickTime Control Slider behavior is used to create a custom slider that functions much the same way as the standard controller that can be displayed with QuickTime movies. Behaviors are a quick way to add simple Lingo scripts to your sprites and cast members. They guide you through the process of applying a script by requesting the information required. Attach as many behaviors to a sprite as you want to get the effect you want. CrossReference
Learn more about Director’s built-in behaviors in Chapter 7.
Exporting Digital Video Director enables you to export any range of frames as a digital video. After you’ve exported the frames as a digital video, you can import that video back into Director as a single cast member. The Radar QuickTime movie that you used earlier in this chapter was created using this technique. It started its life a series of sprites that were animated in Director and then exported as a QuickTime video. When you export a Director movie, it retains tempo settings, palette effects, and transitions; however, any interactivity that is in the selected range of frames is lost. In addition, if you choose to export the frames as a Video for Windows (AVI) file, Director doesn’t save any sounds with your video. Director only exports sounds using the QuickTime file format. Caution
Executing Director transitions in a QuickTime or AVI movie can bring a computer’s system resources to its knees. It’s much safer to remove the Director transitions when you export the Director movie as a video file, and then add transitions to the exported file with a video-editing program such as Adobe Premiere.
3486-6 ch06.f.qc
7/24/00
5:42 PM
Page 223
Chapter 6 ✦ Using Digital Video
When you export a range of frames as a digital video, Director internally plays that portion of your movie, capturing the action as it would appear on Stage. Any scripts or other elements that have a visible effect during that playback time are captured, as well. It’s important to remember that Director captures the entire Stage at its current size. If the action you want to save as a video is smaller than the current Stage size, you need to resize the Stage accordingly. Any elements that are off the Stage but still visible in the Stage window will not be visible in the exported video. Before resizing the Stage, be sure to use the Save As command to save your movie using a new name. This way, you can avoid resizing the Stage back to its original settings before importing your digital video back into your movie. It also provides you with a backup file of the original movie if the results of your export are unsatisfactory. If the Stage is zoomed, it will have no effect on the final size of the video file.
Note
If you are exporting your Director movie as a QuickTime digital video, you need to consider the compression format that you are planning to use. The compression setting that you choose can greatly affect the way the digital video will play back. Table 6-2 lists the compression settings that are available with QuickTime and describes the best use for each one.
Table 6-2 QuickTime Compression Settings Compressor
Description
Animation
This compression scheme works best for computer-generated animations that contain flat colors. It doesn’t work well for a scene that has gradient colors or photographic-type scenes in it.
BMP
Used for exporting a sequence of BMP images. This scheme does very little compression and shouldn’t be used for video output.
Cinepak
This compression method is ideal for videos that will be played back from CD-ROM.
Component Video
This compression scheme should be used if the movie you are exporting will be incorporated in a video presentation using a highend video-editing system, such as an AVID.
DV - NTSC DV - PAL
Formats used for digital video cameras. They are not recommended for exporting video from Director.
Graphics
This scheme is good for exporting 8-bit graphics, although the decompression time is very slow. Continued
223
3486-6 ch06.f.qc
224
7/24/00
5:42 PM
Page 224
Part I ✦ Working with Director
Table 6-2 (continued)
On the CD-ROM
Compressor
Description
H.263
This scheme was designed for video conferencing. It uses very high compression ratios. Movies compressed with this method lose quite a bit of quality.
Intel Indeo Video Interactive
Although a very high quality compressor, this scheme requires a Pentium processor for compression and decompression and is available only on the Windows platform.
Motion JPEG A Motion JPEG B
These compression schemes require a special motion-JPEG card to be installed in order to play back videos that use these compression formats.
None
Good for capturing video or exporting movies that will be captured by a high-end video-editing system, such as the AVID.
Photo JPEG
This scheme is good for exporting still images and QuickTime VR files. The decompression is very slow, so it’s not good for motion video.
Planar RGB
This scheme supports graphics with alpha channels. It’s good to use if you are exporting a series of images that will be composited (combined) with other video segments.
Sorenson Video
This scheme offers very high compression ratios with good image quality. It’s ideal for digital video that will be played back over the Web.
Video
This is a very fast compression/decompression scheme that is good for video that will be played back from a hard disk.
You can use the radar.dir movie on the companion CD-ROM for this exercise. The radar.dir movie is in the EXERCISE:CH06 (EXERCISE\CH06) folder.
Exporting a Range of Frames as a Digital Video 1. Open the radar.dir movie in Director. 2. Choose the File ➪ Export or press Command+Shift+R (Ctrl+Shift+R). The Export dialog box appears (see Figure 6-20). Tip
Prepare your movie for export by checking and testing all media. Don’t waste time by allowing a spelling error or a misplaced sprite to be discovered on the Stage after you’ve already exported to video!
3486-6 ch06.f.qc
7/24/00
5:42 PM
Page 225
Chapter 6 ✦ Using Digital Video
Figure 6-20: The Export dialog box
3. Set the Format field at the bottom of the dialog box to the desired export format (Video for Windows, DIB File Sequence, PICT, Scrapbook, PICS, or QuickTime Movie). Different options are available, depending on the platform with which you are using Director. 4. Using the radio buttons at the top of the dialog box, indicate whether you want to export the Current Frame, Selected Frames (which you must have selected before you open the Export dialog box), All Frames, or a Frame Range. If you choose the Frame Range option, enter the starting and ending frame numbers in the Begin and End fields next to the Frame Range radio button. 5. Click the Options button. a. If you are using Director for Windows and exporting to Video for Windows, the Video for Windows Export Options dialog appears, prompting you to enter the frame rate for the video. b. If you are exporting a QuickTime 4 movie, the QuickTime Options dialog box appears, as shown in Figure 6-21. Figure 6-21: The QuickTime Options dialog box appears for exporting to QuickTime.
225
3486-6 ch06.f.qc
226
7/24/00
5:42 PM
Page 226
Part I ✦ Working with Director
Note
Before exporting frames as digital video, disable any screensavers that might be active. Exporting to digital video can take time, and if your screensaver comes on during the process, it will be included in your video.
6. If you are exporting as a Video for Windows movie: a. Enter the fps (frames per second) in the Frame Rate field and click OK to close the dialog box and return to the Export dialog box. b. Click the Export button, and enter a filename for your video. c. A Video Compression dialog box appears in which you choose the codec to use, the compression quality, and the placement of keyframes. d. Click OK, and the movie is exported to video. Be prepared for a wait; video compression takes time. If you are exporting as a QuickTime 4.0 movie: a. Choose the compressor or codec type in the QuickTime Options dialog box. See Table 6-2 for more details on each of these settings. In addition, choose the Quality, Color Depth, Scale (such as 25%, 50%, 75%, or 100% of the movie’s Stage size), and whether sound channels are to be exported. When you have finished setting options, click OK. b. In the Export dialog box, click the Export button. Enter a filename for the digital video file and click the Save button. c. An Alert box reminds you that screensavers should be turned off during the file export. Click OK to dismiss the alert and the export process begins. Tip
To stop an export that is in progress, press Command+. (period) (Ctrl+.).
Exporting frames as a video is one way of keeping your movie compact, by replacing several sprites with a single sprite. Exporting frames of your Director movie as a digital video offers all the advantages — and the disadvantages — associated with including digital video in your movies. It can increase the file size of your movie, but it can also reduce the file size if the video is replacing several large cast members with a single, more compact cast member. You should consider the file sizes of the original cast members versus a digital video before deciding to export frames as a video.
QuickTime VR One of the more exciting video technologies supported by Director is Apple’s QuickTime VR (QTVR) format. QTVRs come in three flavors: panoramas, objects, and scenes. Panoramas are 360-degree images that can be viewed from any point in the 360-degree field of view. QTVR objects are three-dimensional objects that can
3486-6 ch06.f.qc
7/24/00
5:42 PM
Page 227
Chapter 6 ✦ Using Digital Video
be rotated and viewed from any angle. Scenes can contain a series of panoramas and objects that are linked together in what are referred to as nodes. All three formats give the user control, enabling them to adjust the view at any time. You can also control the view with Lingo. QTVRs can add a level of realism to your movies that’s not possible with other virtual reality technologies. Technologies such as Virtual Reality Markup Language (VRML) render the three-dimensional images in real time, thereby limiting the amount of information those images can display, such as textures and lighting, due to system resources. Thus, VRML objects tend to contain far less detail and appear crude. QTVRs are created from actual photographs or high-end 3D authoring programs capable of creating very detailed photorealistic images. It’s also possible to combine several QTVRs — called a nodal movie — into a single movie and create hotspots that enable a viewer to jump from one scene to another. On the CD-ROM
A wonderful example of QuickTime VR used in Director comes on the CD-ROM. Check out the Riddle of the Sphinx game preview. Riddle of the Sphinx is a five CD-ROM game, created in Director, that has taken the folks at Omni International more than five years to create.
Director treats QTVR movies just as it would any other QuickTime digital video. You can set the same properties for a QTVR file as you would for a QuickTime video. QTVR movies have the same limitations as QuickTime video in that you need to take into consideration file size and the resources needed to play them back. In the following exercise, you import a multinode QTVR movie into Director, place it on the Stage, and set properties that enable the user to navigate from one node to another. Multinode QuickTime VRs are composed of several independent QTVR scenes that are linked together, enabling a user to navigate from one node (QTVR movie) to another. On the CD-ROM
In this exercise, you import the nodal.mov QTVR file into the nodal.dir movie, which is in the EXERCISE:CH06 (EXERCISE\CH06) folder. The QTVR file is located in the video folder, located in the same folder as the Director movie.
Building a Virtual Tour 1. Open the nodal.dir movie in Director and import the nodal.mov file that is in the video folder. Use the same process you would use when importing a QuickTime video. 2. Click on the Properties button in the Cast window to activate the Property Inspector, shown in Figure 6-22. The video cast properties window should be active; if not, click on the QuickTime tab. 3. In Normal view, set the Playback setting to Play Every Frame (No Sound). Set the Frame rate to Maximum (–2 in the List view). Disable Play Sound (because there is no audio), and check Show Controller to display the controller.
227
3486-6 ch06.f.qc
228
7/24/00
5:42 PM
Page 228
Part I ✦ Working with Director
Figure 6-22: The Property Inspector set to the QuickTime tab
4. Make the Cast Window active and choose the nodal.mov cast member. Drag the member onto the Stage and position it inside the opening provided for the movie. The Stage should look like the one shown in Figure 6-23. Figure 6-23: Drag the mouse in the VR window to view the scene.
5. Rewind the movie and play it. Drag inside the QTVR window to change the view. The scene will rotate in the direction that you are dragging the mouse. The cursor changes to an arrow when it encounters a hotspot. 6. Click when the cursor changes to an arrow, and the QTVR switches to another node. To get back to main node, click on the small screen that appears in each second-level node.
3486-6 ch06.f.qc
7/24/00
5:42 PM
Page 229
Chapter 6 ✦ Using Digital Video
Using the controller buttons (shown in Figure 6-24) you can also view hotspots, zoom in and out, and navigate back to the previous node. You can control all of these actions through Lingo, so that they occur without the user having to interact with the scene. CrossReference
You learn to use Lingo to control this same scene in Chapter 19.
Figure 6-24: Click the Show Hotspots button to display the active areas in the QTVR.
Director does not have any capability to edit or create QTVR files. You need to create them with an application such as Apple’s QTVR Authoring Studio, and then bring them into Director. You can assign an external editor that opens the file if it is double-clicked; however, the same editor will be opened for all other QuickTime videos in your movie. This could present a problem, because QTVR editors do not generally offer the same kind of functionality as a digital video editor.
Summary Using digital video in your Director movies can greatly enhance the quality of your multimedia applications. Carefully implementing digital video into your multimedia applications enables you to accomplish effects that would be very difficult, if not impossible, to achieve using another graphics medium. Before moving on to the next chapter, review the aspects of digital video that were covered in this chapter: ✦ Director supports the QuickTime 3 format on both the Macintosh and Windows platforms. ✦ Digital video cast members are always linked. Take care when moving the files and when distributing your movies; be sure to include the linked files. ✦ You can crop and scale a video cast member.
229
3486-6 ch06.f.qc
230
7/24/00
5:42 PM
Page 230
Part I ✦ Working with Director
✦ You can insert cue points into a digital video, which enable you to control the tempo of the movie. ✦ Director has several built-in behaviors that you can use to control a digital video. ✦ You can export selected frames in your Director movies as digital video files. ✦ Director supports Apple’s QuickTime VR technology. In the next chapter, you learn to add interactivity to your movies by using Director’s built-in behavior libraries.
✦
✦
✦
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 233
7
C H A P T E R
The Power of Behaviors
✦
✦
✦
✦
In This Chapter
I
nteractivity is critical to multimedia — without it, a multimedia application is little more than a self-running slideshow. Director 6.0 introduced a powerful new tool for adding interactivity to your movies: the behavior. Whether encapsulated in the Library Palette, or implemented via Lingo using the Behavior Inspector, behaviors make your buttons click crisply, control media within your movie, and even keep time for you.
What Are Behaviors? With behaviors, you can add interactivity to a movie without Lingo scripting. Later, in Chapter 11, you learn to create a few simple scripts in Lingo to: ✦ Jump to a target frame ✦ Loop on the current frame
Introducing Director’s Library Palette window Accessing prepackaged behaviors Creating interactive Director movies without scripting Using the Behavior Inspector to attach, create, and edit behaviors Attaching external casts to use thirdparty behaviors
✦ Move the playback head forward one frame ✦ Move the playback head back one frame ✦ Jump to a target marker (creating a marker is covered later in this chapter)
Sending messages from one behavior to another
✦ When you create these scripts in Chapter 11, you actually create behaviors — because a behavior is nothing more than a script or a page of code that includes event handlers (or subroutines) for events that occur in your movie. Director’s standard events are listed later in this chapter and are discussed in detail in Chapter 11.
✦
✦
✦
3486-6 ch07.f.qc
234
7/24/00
5:44 PM
Page 234
Part II ✦ Bringing It All Together
The scripted actions in the bulleted list that opens this chapter are simple examples of what you can accomplish with behaviors. Fortunately, you can add powerful scripts to your movies without programming in Lingo, using the dozens of prescripted behaviors that are shipped with Director. Director’s built-in behaviors are contained as a series of external cast libraries (such as interactive.cst, navigation.cst, QuickTime.cst, text.cst, and so on) that are stored in the Libs folder within the Director 8 folder on your hard drive. These prepackaged behaviors enable you to add interactivity to objects in your movie, just by clicking, dragging, and responding to a few simple prompts. Note
A well-written behavior doesn’t require modifications to its code in order to work in your program. That means you can attach behaviors to objects without writing a single line of code.
Accessing Director’s predefined behaviors All the predefined behaviors included with Director appear in the Library Palette window. You can display the Library Palette by choosing Window ➪ Library Palette. The purpose of this palette is to enable you to view and attach predefined behaviors to sprites in your movies. Using the Library Palette window, you can click, drag, and attach behaviors to objects in your movies, but you cannot edit or delete the original behaviors. When you drop a behavior from the Library Palette window onto an object, Director copies the behavior to the movie’s Cast window. That’s where you can view and edit the behavior, as you learn to do later in this chapter and throughout the Lingo sections of the book. Behaviors are grouped into several categories (Animation, Controls, Internet, Java Behaviors, Media, Navigation, and Text). Each category contains behaviors that are related to the action that the behavior was built to perform. Several categories — media, for example — are divided into subcategories that group the behaviors according to the aspects of the main category with which the behaviors were designed to work. The categories found on the Library Palette and the types of behaviors that are contained in them are: ✦ Animation. These behaviors are applied to sprites to perform numerous animation effects and can enable the user to manipulate sprites while the movie is playing. There are three types of animation behaviors: automatic, interactive, and transitions. • You use automatic animation behaviors to animate sprites automatically; although they can be triggered by another event, they don’t require any user interaction. Some of these behaviors are frame-based — the action happens over a series of frames in the Score. Others are time-based — the action happens over a specified period, regardless of the number of frames the sprite occupies in the Score.
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 235
Chapter 7 ✦ The Power of Behaviors
• Interactive animation behaviors require some type of user interaction to trigger them. You use most of the behaviors in this section to manipulate sprites on the Stage while the movie is playing. For example, you can make a sprite “draggable,” enabling a user to drag the sprite to another location on the Stage. There are also several behaviors that detect the location of a sprite while it is being moved on the Stage and then determine whether it’s within the bounding box (referred to as the rect) of another sprite. • Sprite transition behaviors create transitions from one screen to another, using the new imaging Lingo feature introduced in Director 8. Many of these effects mimic ones found in programs such as Adobe Premiere, such as barn doors and soft-edge wipes. CrossReference
Chapter 26 goes into great detail about the new imaging Lingo commands introduced in Director 8.
✦ Controls. Controls contain a series of behaviors designed to add interactivity and user feedback to your movies. Most of the basic behaviors that are applied to buttons are found in this category. Also, several behaviors enable you to create a status bar and ToolTips to display custom messages. Last, but not least, one behavior is for building an analog clock that uses the internal clock on the user’s computer to correctly display the time. ✦ Internet. The Internet category (you guessed it) contains behaviors designed for building movies that primarily will be played over the Web. Three subcategories of behaviors are located here: Forms, Multi-user, and Streaming. The first two subcategories contain behaviors that are designed to enable your movie to interact with a Web server. The Streaming category contains behaviors that enable you to control the way Shockwave movies will download and play back over the Web. • The Forms subcategory contains behaviors for creating forms in your movies that the user can fill out. The data can then be sent to a Web server and used by other applications, such as a database. These behaviors are for advanced users and require a working knowledge of Web server applications. • The Multi-user subcategory contains behaviors for connecting to and disconnecting from a server. Also, several behaviors in the subcategory are for creating Shockwave “chat rooms,” which enable multiple users to communicate with each other over the Web. • The Streaming subcategory contains behaviors that control the way the media elements in a Shockwave movie download from the Web. You can use behaviors to display a progress bar showing the status of the movie as it is being downloaded. In addition, several behaviors enable you to loop a movie until the media elements that you defined have been downloaded.
235
3486-6 ch07.f.qc
236
7/24/00
5:44 PM
Page 236
Part II ✦ Bringing It All Together
✦ Java Behaviors. These are a collection of “Java-safe” behaviors that should be used if you will be outputting your Director movies as Java applets to be played over the Web. The Java behaviors are for advanced users and require a strong knowledge of Lingo. ✦ Media. You use the Media behaviors to control and add interactivity to Flash movies, QuickTime digital video, and audio that has been imported into your movies. The subcategories are divided according to the type of media that the behavior is designed to work with: Flash, QuickTime, or Sound. • You use Flash behaviors to add interactivity and control the playback size and quality of an entire Flash movie or individual Flash elements. • Use the QuickTime behaviors to create custom controls that will be used to play back a QuickTime movie. This subcategory contains a very useful behavior that you can use to create a custom VCR-like control panel that enables a user to control the way a QuickTime move is played. Another behavior enables you to create a custom slider bar that works the same way as the built-in controller that can be displayed with QuickTime video or audio movies. • Two Sound behaviors in this subcategory enable you play a linked or internal sound file. ✦ Navigation. You use the Navigation behaviors primarily in conjunction with the Control behaviors to determine where the movie will advance to when a user clicks on a sprite that contains a control behavior. Also, other behaviors control how long a movie loops on a particular frame. New Feature
Director now has a set of behaviors designed to create painting tools that enable users to paint on the screen while the movie is running.
✦ Paintbox. This new set of behaviors introduced in Director 8 is designed to create a painting application using Director. These behaviors control the basic functions needed to paint images on the screen, including selecting colors and brushes, erasing, and undoing an action. ✦ Text. Use these behaviors to format text as well as to create special effects with text, such as having the text appear to type automatically on the screen. Several behaviors in this category are for generating and displaying hypertext links for multimedia applications that will interact with the Web. Tip
If you momentarily hold the mouse over any behavior in the Library Palette, a ToolTip appears, giving a brief description of the behavior.
A detailed listing of all of the behaviors that ship with Director, as well as their uses, is in Appendix B, “Director’s Built-in Behaviors,” located at the back of this book.
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 237
Chapter 7 ✦ The Power of Behaviors
You work with several of these behaviors in this chapter. In each case, the action listed in the Action column occurs when a specified event occurs. When you set up the use of a behavior, you get to specify the event that triggers it.
Attaching predefined behaviors to objects To use a behavior from the Behavior Library requires just a few steps. 1. First, be sure that the Library Palette window is visible by choosing Window ➪ Library Palette. The Library Palette window appears (shown in Figure 7-1) and displays the behaviors stored in a single predefined external cast library stored in the Libs folder.
Behavior icon Library list button Library category Figure 7-1: All of Director’s predefined behaviors are contained in the Library Palette.
Scroll triangle Resize window tab
2. If the desired behavior is not visible, you can view other behaviors by using the Library List button, which is identified in Figure 7-1. Simply click the button, drag until the desired behavior library name is highlighted (such as Animation, Navigation, Media, and so on), and then release the mouse button. The behaviors contained in the selected category are displayed in the window. If more behaviors exist than can be displayed simultaneously in the Library Palette window, a scroll triangle appears at either the bottom or the top of the palette. You can use the scroll triangle to scroll toward the beginning or end of the list of behaviors in the current behavior library. Resize the entire window by clicking on the tab in the lower right corner and dragging the window to the desired size.
237
3486-6 ch07.f.qc
238
7/24/00
5:44 PM
Page 238
Part II ✦ Bringing It All Together
Note
In Director 6, a single Behavior Library .cst file contained all the prepackaged behaviors. Once opened, you had to scroll through cast member after cast member to locate the specific behavior that you wanted. Director 8’s Library Palette window organizes behaviors by their function, making it easier to locate the desired behavior.
3. After you have located and displayed the desired behavior in the Library Palette, click the behavior’s icon (identified in Figure 7-1) to select it. 4. Drag and drop the behavior by its icon onto a sprite (on the Stage) or onto the target cell (in the Score window’s script channel). 5. Some behaviors require parameters, called properties, which define the action or designate a target for the behavior’s action. For example, you can attach a behavior to a button that causes the playback head to jump to a specific frame. To make the jump, the behavior must be told the name or number of the target frame. If additional information is required, a Parameters dialog box in which you must enter the properties for the behavior appears. After you enter the requested parameters, click OK to close the dialog box. A behavior can be attached only to a sprite on the Stage or to a frame in the Score window. Behaviors that are dropped onto a sprite are called sprite scripts. You can attach multiple behaviors to a single sprite on the Stage to create a more complex action. Behaviors dropped onto a cell in the Score window are considered frame scripts. You can attach only a single behavior to a frame’s script channel. Note
In their most essential form, behaviors are Score scripts. Score scripts, as well as other types of scripts, are discussed throughout the Lingo section of this book.
Building a Better Movie Director is the hands-down favorite among graphic designers for creating portfolios, resumes, and promotional pieces. Version 8 of the program is sure to increase its popularity, because it offers so many code-free options for creating highly interactive presentations. Using the built-in behaviors that come with Director in your movies enables you to add sophisticated interactive and animation components, easily control how a movie downloads over the Internet, and even create chat rooms and multiuser games. You can add all of these components to your multimedia applications with little or no Lingo programming experience.
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 239
Chapter 7 ✦ The Power of Behaviors
Pushing all the right buttons When you get right down to it, creating an interactive interface boils down to creating buttons and then telling the program what to do when someone clicks them. It is these buttons, in fact, that make the interaction between user and application possible. With buttons, the graphical user interface (GUI) becomes more than simply a picture on the screen — it becomes a tactile experience. A good button invites the user to click it and serves to take the program’s illusion of reality one notch higher (see Figure 7-2). Figure 7-2: A well-designed button engages the user.
The exact definition of a button can vary widely, but for the most part includes these characteristics: ✦ A button is an object or spot on the screen that, when clicked, causes something to happen. ✦ A button typically simulates a real-life physical button, like those on an electronic appliance or computer. When you click the mouse on it, the button changes its appears (looks “raised” or “pressed”); when the mouse button is released again, the button returns to its former state (pressed or not pressed). This kind of button essentially transfers the physical action of the mouse click to the virtual action of a button click. ✦ A button may become highlighted (become brighter on the screen) or animated when the cursor moves over it, with or without the pressed appearance. ✦ A button can be rendered inactive so that it does not react at all to the mouse, and then be made active again when some external event takes place. Even though buttons are a staple of multimedia, they have always been notoriously difficult to pull off well in Director. Beginning with Director 6.x this has changed (and how!). Now you can implement buttons in three different ways: by employing standard system buttons on the Tool Palette, by using prepackaged behaviors (as shown in the next section), or by writing a navigational handler using Lingo. CrossReference
Chapter 14 discusses using Lingo to control a button’s behavior.
239
3486-6 ch07.f.qc
240
7/24/00
5:44 PM
Page 240
Part II ✦ Bringing It All Together
Using navigation behaviors to build buttons In the next few sections, you use Director’s predefined behaviors to accomplish some of the tasks that required Lingo scripting in prior versions of Director. To provide the user control over the flow of a movie, you must be able to put the playback head in a holding pattern on a specific frame and attach behaviors to buttons that, when clicked, forward the playback head to the next frame or a designated frame. Finally, you apply a behavior that sends a message to another sprite to trigger an animation. The Library Palette includes behaviors to accomplish these tasks, which you can drag and drop onto frames and sprites. To demonstrate this, you use the engine.dir movie for the exercises in this chapter. The engine.dir file is a partially built Director movie that simulates an interactive learning module that could be created as part of a multimedia application. Most of the cast members that will be used in this movie are already on the Stage. You will concentrate on adding behaviors to the sprites that will add the interactivity to the movie. When you look at the Score window, it is difficult to verify the names of cast members upon which each sprite is based, because almost all sprites in the movie are one frame in duration. To display the name for each sprite, you should make the Score the active window and move the mouse pointer over the sprite in question. If you leave the pointer there momentarily, a ToolTip appears, showing the sprite’s name. You can also determine the name and appearance of a sprite by clicking on its cell in the Score window, which causes a thumbnail of the cast member to appear in the upper-left corner of the Score window along with the sprite’s name, as shown in Figure 7-3. You can also assign a color to cells in the Score to make it easier to identify sprites. Simply select the cells in the Score to which you want to apply a color, and then click on a color swatch located in the lower-left corner of the Score window.
Tip
In the following exercise, you initially test the movie to determine whether it plays from the first frame to the last without pausing. Next, you open the Library Palette window with prescripted behaviors and add a behavior to the movie that causes it to pause and loop on frame 1. Note
On the CD-ROM
When you apply a behavior to a sprite from the Library Palette, the behavior is copied to the current cast window. For this exercise, you use a partially complete director movie (engine.dir) available on the companion CD-ROM in the EXERCISE:CH07 (EXERCISE\CH07) folder. You will be asked to save this movie to your hard drive at the end of this exercise so that you can add features to it in the other exercises in this chapter.
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 241
Chapter 7 ✦ The Power of Behaviors
Sprite thumbnail image
Sprite label Cell color swatches Figure 7-3: The Score window with a thumbnail of a sprite displayed.
Using a Behavior to Loop on the Current Frame 1. Open the engine.dir movie. 2. Be sure that the Score and Stage windows are visible. The Score will appear similar to Figure 7-3. 3. Rewind and play the movie. It plays from start to finish without stopping ( and may loop if the Control Panel Loop Playback button is selected. You see certain elements flashing on and off, which happens because some sprites are used only on single frames, while others (like the background sprite) are used in all of the frames of the movie. 4. Stop the movie and rewind it. 5. If the Library Palette window is not visible, click the Library Palette button on the toolbar or choose Window ➪ Library Palette. 6. When the Library Palette window appears, click the Library List button. When the pop-up list appears, select the Navigation category. 7. Locate the Hold on Current Frame behavior in the list of available behaviors, and then drag and drop it onto the Script channel in frame 1 of the Score window, as shown in Figure 7-4.
241
3486-6 ch07.f.qc
242
7/24/00
5:44 PM
Page 242
Part II ✦ Bringing It All Together
Script channel
Figure 7-4: Drag the Hold on Current Frame behavior to the script channel in frame 1.
8. Save the movie as engine1.dir. 9. Rewind the movie, close all open windows, and then play the movie. Tip
You can temporarily close all windows and play a movie if you hold down the Shift key and press Enter on the numeric keypad.
The engine1.dir movie now holds on the first frame of the movie. You can click the Next Screen, Enable Sound, and Launch Rocket buttons, but nothing happens in your movie . . . yet! 10. Stop the movie and rewind it. The Hold on Current Frame behavior accomplishes a single task: It causes the playback head to loop on the current frame until another event instructs the playback head to move on. It can be instructive to examine the script that causes this behavior to function. You’ll do that later in this chapter. At this point, the engine1.dir movie is waiting on the first frame for some kind of instruction that will tell it to proceed to the next frames of the movie. In the following steps, you attach the Go to Frame behavior to the Next Screen button and thus enable the playback head to escape from the frame 1 loop.
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 243
Chapter 7 ✦ The Power of Behaviors
Attaching a Behavior to Jump to a Specific Frame 1. Be sure that the engine1.dir movie and the Library Palette window are both open. 2. Locate the Go to Frame X behavior in the Library Palette window (it’s in Navigation group of behaviors). 3. Drag and drop the Go to Frame X behavior onto the Next Screen button sprite (colored yellow in the Score window) located in sprite channel 5. Because this behavior (unlike the Hold on Current Frame behavior) includes properties, the Parameters dialog box appears, as shown in Figure 7-5. You must specify the destination frame. Figure 7-5: Enter the frame number to which you want the movie to advance when a user clicks the button.
4. Enter 5 next to the Go to which frame on mouseUp prompt. Then click the OK button to return to Director’s main window. 5. Save the movie as engine2.dir, and then rewind and play the movie. 6. Click the Next Screen button to test the Go To Frame behavior. If the Loop Playback button on the Control Panel is turned off (so that the movie does not loop), the movie will jump to frame 5 and continue playing until the end. You need to add another Hold on Current Frame script to have the movie loop on frame 5. 7. To cause the movie to loop on frame 5 rather than automatically terminating, open the Cast window and drag the Hold on Current Frame behavior to the script channel in frame 5. This creates a copy of the behavior in frame 5. Caution
It’s possible to copy and paste a script; however, it’s generally not a good idea. If the behavior that you are copying has parameters applied to it, the same parameters will be applied to the new sprite or Score channel onto which it has been pasted. It’s usually safer to reapply a behavior that has parameters connected with it to the new sprite so that new parameters can be set for it. It is far safer to drag and drop a behavior from either the Cast window or the Library Palette into the Score window’s Script channel.
8. Save the movie again as engine2.dir, and then rewind and play the movie. After testing the Next button, stop the movie. The movie now loops on frame 1 until the Next Screen button is clicked, and then it advances to frame 5 and loops on that frame. The Next Screen button appears to be dimmed out. Because this button is no longer needed, a blend was applied to it to make it appear to be inactive.
243
3486-6 ch07.f.qc
244
7/24/00
5:44 PM
Page 244
Part II ✦ Bringing It All Together
Using the Behavior Inspector The Behavior Inspector, introduced with Director 6, provides a means for you to view and edit existing predefined behaviors and to create new ones in a cast. You cannot modify or delete behaviors in the Library Palette window, but you can view, edit, delete, or create a behavior in the Cast window. The Behavior Inspector, shown in Figure 7-6, provides easy access to information about the behavior, including the behavior’s name, type, its script, its description, the names and values of any parameters (properties) associated with the behavior, and the span of frames to which the Behavior is applied. You open the Behavior Inspector by choosing Window ➪ Inspectors ➪ Behavior Inspector or by pressing Command+Option+; (Ctrl+Alt+;).
Add behavior button Clear behavior button
Parameters button Script button
Editing pane
Description pane
Number of frames the behavior spans Sprite channel Behavior type Figure 7-6: The Behavior Inspector with both the editing and description panes expanded.
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 245
Chapter 7 ✦ The Power of Behaviors
The Behavior Inspector is built on a series of panes that can be collapsed or expanded as needed. In its default state, these panes are hidden. You click the two triangles on the left side of the Inspector to expand or collapse the panes. You’ll get a good look at these panes as you work through these sections. The Editing Pane contains the Events and Actions pop-up button. The Description Pane displays a description of what the behavior does; this may include information about properties and their roles, events that the behavior generates, and copyright information. At the top of the Behavior Inspector is the gear-shaped Parameters button, which opens the behavior’s Parameters dialog box. From it, you can change the behavior’s properties. The Script button, located next to the Parameters button, enables you to view and directly modify the Lingo script that is used for the behavior. At the bottom of the Behavior Inspector, you see the type of behavior, the sprite channel in which it’s located, and the span of frames to which the behavior has been applied. A button located in the lower-left corner of the window locks the currently selected behavior so that it is displayed no matter what sprite is chosen. This is useful if you need to view all of the properties that are applied to a series of sprites, although it can cause confusion, because there is no indication of what the displayed behaviors are applied to.
Viewing the script behind a behavior In Chapter 11, you explore the Script window and begin learning the basics of programming using Lingo, Director’s proprietary scripting language. For now, it’s helpful to glimpse behind the façade of the behavior and simply be aware that it’s just a series of instructions. By default, when you double-click on a behavior in the Cast window (either an internal or external cast), the Behavior Inspector opens so that you can edit it. You can change the default setting so that the Script window pops up rather than the Behavior Inspector. As you become proficient in Lingo scripting, you may prefer to have the Script window appear instead of the Behavior Inspector — although for now, the Behavior Inspector is more useful as you learn and experiment with codeless programming. To change which window appears for viewing or editing a behavior, you can choose File ➪ Preferences ➪ Editors. After the Editors Preferences dialog box appears, select Behavior from the list and click the Edit button. When the Select Editor for Behaviors dialog box appears, you can choose between the Script Window radio button or the Behavior Inspector radio button, and then click the OK button. Finally, click the OK button to close the Editors Preferences dialog box. For the duration of this lesson, we’ll assume that you have established the Behavior Inspector as the default editor for behaviors.
245
3486-6 ch07.f.qc
246
7/24/00
5:44 PM
Page 246
Part II ✦ Bringing It All Together
You can open the Behavior Inspector by using one of several methods: ✦ You can use the shortcut keys Command+Option+; (semicolon) on the Macintosh or Ctrl+Alt+; (semicolon) for Windows. ✦ You can click the Behavior button in the top-left part of the Score window (see Figure 7-7) or on the Director toolbar.
Figure 7-7: Open the Behavior Inspector by clicking on the Behavior icons located in the Score window or on the toolbar.
Director 8 introduces a stripped down version of the Behavior Inspector, shown in Figure 7-8, that is included in the new Property Inspector window. The primary purpose of the Behavior tab is to view and modify the parameters of the behavior that are applied to a sprite. The version contained in the Property Inspector does not contain the description window or the tools needed to create a new behavior. You can open the Behavior tab located in the Property Inspector by using one of two methods. ✦ If the Sprite Overlay is visible, you can click the Behavior icon (identified in Figure 7-7) to display the Behavior tab in the Property Inspector. ✦ Click on the Behavior tab in the Property Inspector when editing other properties of a sprite that has behaviors attached to it.
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 247
Chapter 7 ✦ The Power of Behaviors
Figure 7-8: The Property Inspector contains a “stripped down” version of the Behavior Inspector.
What’s the Sprite Overlay? When you click on a sprite to make it active, the Sprite Overlay appears with three icons: the Cast Member Properties icon, the Sprite Properties icon, and the Behavior Inspector icon. Clicking the Behavior Inspector icon opens the Behavior Inspector. You can toggle the Sprite Overlay between being visible and invisible by choosing View ➪ Sprite Overlay or by using these keystrokes: Ctrl+Shift+Alt+O (Windows) or Command+Shift+Option+O (Mac). This feature provides a summary of information on the currently selected sprite.
Tip
Caution
Dissecting someone else’s script or behavior can help you learn Lingo, but don’t change the behaviors until you understand what you are doing. A small change can cause a behavior not to function as intended.
In the next exercise, you open a behavior and display its “guts” using the Script window.
Examining the Hold on Current Frame Behavior 1. Open the engine2.dir movie that you modified in the preceding exercise. 2. Double-click the Hold on Current Frame behavior in the Cast window, and either the Script window or the Behavior Inspector appears. If the Behavior Inspector appears, click the Script button, identified in Figure 7-6, to display the Script window. 3. Use the scroll bar to scroll to the top of the script.
247
3486-6 ch07.f.qc
248
7/24/00
5:44 PM
Page 248
Part II ✦ Bringing It All Together
4. Review the script — and don’t panic over its initial complexity. Some of the script is composed of comments, that is, lines of text preceded by the double dash (--), as shown in Figure 7-9. When you examine the essence of this behavior (that is, the uncommented lines), it is composed of three lines, with its “heart” being a go the frame instruction).
Figure 7-9: The text of the Hold on Current Frame behavior script with the getBehaviorDescription instruction indicating that no parameters are required for this behavior.
5. Close the Script window and the Behavior Inspector.
Adding behaviors by using the Property Inspector You already know how to drop and drag a behavior onto a sprite, but you can also add a behavior to sprites by means of the Property Inspector. Unless you are creating a new Behavior — you do that later in this chapter — it saves time to add behaviors using the Property Inspector because you probably already have it open in order to adjust other properties in your movie. To do so, you need to: 1. Open the Library Palette by choosing Windows ➪ Library Palette. Select the behaviors that you want to use in your movie, and then drag them into the Cast window. 2. On the Stage, select a sprite to which you want to apply a behavior.
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 249
Chapter 7 ✦ The Power of Behaviors
3. Click the Behavior button on the Sprite Overlay. This launches the Property Inspector with the behavior tab active. 4. Choose a Behavior from the Behavior Pop-up button, as shown in Figure 7-10.
Behavior pop-up button Parameters button Script button Figure 7-10: The Property Inspector enables you to apply behaviors to sprites. You can also easily modify the parameters of the applied behavior.
Parameter listings Parameter settings
5. If the behavior you applied has parameters that need to be set, a menu appears, prompting you to choose them. After they have been set, the parameters are listed in the lower pane of the window. The parameters can be adjusted at any point during the creation process either by clicking the small arrow next to the parameter listing and choosing a new parameter setting from the pop-up menu, or by clicking on the Parameters button to display the Parameters dialog box. Note
While the Property Inspector is open, you can repeat the process and attach additional behaviors to the selected sprite on the Stage.
6. When you have finished adding properties to the selected sprite, you select another sprite on the Stage to edit, and then add behaviors to it. When you are finished adding behaviors, either close the Property Inspector or leave it “floating” open on your desktop.
249
3486-6 ch07.f.qc
250
7/24/00
5:44 PM
Page 250
Part II ✦ Bringing It All Together
Adding behaviors in the Score window In most situations, the fastest way to add behaviors to sprites is through the Score window. Usually when you are creating a movie in Director, you place all of the cast members on the Stage and position them, and then switch to the Score window to adjust the sprite span, add keyframes, and so on. The next logical step in the process is to add the behaviors to the sprites. Director enables you to do this without having to open the Property or Behavior Inspectors. Adding behaviors in the Score window doesn’t enable you to see the parameters that you have set; however, you can always view and adjust them at any time by using the Property or Behavior Inspectors. Follow these simple steps to add behaviors in the Score window: 1. Open the Score window and select a sprite. 2. Click on the Behaviors pop-up menu, shown in Figure 7-11, and choose from one of the available behaviors displayed in the list that are in your Cast windows. 3. If any parameters need to be set, a menu appears, prompting you to set them.
Behavior inspector button Behavior pop-up Figure 7-11: Applying a behavior to a sprite in the Score window
You can also clear all the behaviors applied to a sprite or create a new behavior. You can also click on the Behavior Inspector button in the Score window to launch the Behavior Inspector.
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 251
Chapter 7 ✦ The Power of Behaviors
Caution
Clicking the New Behavior option in the Score window pop-up menu launches the Script window, not the Behavior Inspector. This occurs even if you have chosen the Behavior Inspector as your default editor for behaviors.
Removing behaviors from a sprite If you change your mind, you can also use the Property Inspector to remove one or more behaviors. To delete a behavior, you must: 1. Locate and select the sprite on the Stage (from which you want to remove a behavior). 2. Click on the Behavior button located in the Sprite Overlay. 3. In the Behavior tab of the Property Inspector, click to highlight the behavior in the Behavior List pane, as shown in Figure 7-12.
Clear behavior button
Shuffle down
Shuffle up Selected behavior
Figure 7-12: The Property Inspector with multiple behaviors listed
4. Press the Clear Behavior button and choose the Remove Behavior option. You can also delete a selected behavior by pressing the Backspace or Delete key.
251
3486-6 ch07.f.qc
252
7/24/00
5:44 PM
Page 252
Part II ✦ Bringing It All Together
You can also delete all of the behaviors applied to a sprite by choosing the Remove All Behaviors option in the Clear Behavior pop-up menu.
Tip
Reordering behaviors attached to a sprite Behaviors are executed in the order in which they were originally attached to the sprite, unless you specifically change the order. To modify the execution order, you need to change the order in which behaviors are listed in the Behavior List pane in the Property Inspector or Behavior Inspector. To change the order of execution, using the Property Inspector, complete these steps: 1. Open the Property Inspector and click on the Behavior tab. 2. Locate and select the sprite on the Stage to which the behaviors are applied that you want to reorder. 3. In the Behavior List pane of the Property Inspector, highlight the behavior that you want to reorder. 4. After selecting it, click either the Shuffle Up or Shuffle Down arrow, which are identified in Figure 7-12, until the behaviors are listed in the desired execution order. In the following exercise, you add a second behavior to the Next button in the engine2.dir movie that you saved to your hard drive, and then you reorder the sequence in which the behaviors are executed. On the CD-ROM
In the next exercise, you use the engine2.dir movie you saved earlier in this chapter. You can also use the engine2.dir movie found on the CD-ROM in the EXERCISE:CH07 (EXERCISE\CH07) folder.
Adding Media Behaviors to a Movie 1. Open the engine2.dir movie. 2. Make sure the Cast window is open. Open the Library Palette window. 3. From the Library List pop-up menu, select the Sound subcategory under the Media category. Note
You need to drag behaviors located in the Library Palette into the Cast window before you can use the Behavior or Property Inspectors to apply them to a sprite.
4. Drag the Sound Beep behavior into the Cast window (see Figure 7-13). 5. Open the Score window and set the playback head to frame 1, and then click on the Next Screen button on the Stage.
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 253
Chapter 7 ✦ The Power of Behaviors
Figure 7-13: Drag the Sound Beep behavior from the Library Palette to the Cast window.
6. Click the Behavior button on the Sprite Overlay, and then select the Sound Beep behavior from the Behavior pop-up button in the Property Inspector. 7. Save the movie as engine3.dir. Rewind the movie and play it back. Click the Next Screen button. You will not hear the system beep, because the first behavior (go to frame 5) is executed before the second behavior’s actions can occur (Sound Beep). 8. Stop and rewind the movie. 9. Select the Next Screen button on the Stage, open the Property Inspector, and click on the Behavior tab if it is not already open. The Inspector should display the two behaviors attached to the Next button sprite. 10. In the Property Inspector, select (highlight) the Sound Beep behavior, and then click the Shuffle Up arrow. 11. Save the movie again. Rewind the movie and play it. 12. Click the Next Screen button; you will hear a system beep before the movie advances to frame 5. 13. Stop the movie. In the next few steps, you remove the behavior that plays a system beep and replace it with a behavior that plays an internal sound cast member (Click). You use the Property Inspector to accomplish these tasks.
253
3486-6 ch07.f.qc
254
7/24/00
5:44 PM
Page 254
Part II ✦ Bringing It All Together
CrossReference
Chapters 5 and 18 provide detail on importing sound, using sound channels, and controlling sound using Lingo. For now, enjoy the simplicity of using a behavior to add a sound to your movie.
Attaching and Deleting Media-Control Behaviors Using the Behavior Inspector 1. Open the engine3.dir movie that you saved in the preceding exercise and rewind it to frame 1, if necessary. Make sure the Cast window is open. 2. Open the Library Palette and select the Sound subcategory to display the Sound behaviors. Drag the Play Sound Member behavior into the Cast window. 3. Click the Next Screen button on the Stage and then click the Behavior button on the Sprite Overlay to open the Behavior tab in the Property Inspector. The two behaviors previously attached to the Next button sprite are displayed in the window. 4. Activate (click) the Sound Beep behavior. 5. Press Delete or Backspace to remove the highlighted behavior. 6. Click the Behavior pop-up button and select the Play Sound Member behavior. 7. The Parameters dialog box for the behavior appears, as shown in Figure 7-14. You must specify (from a list of possible settings) the sound to be played, the sound channel to use, the initializing event, and how many times the sound should loop. You set these options in the following steps.
Figure 7-14: The Parameters dialog box for the Play Sound Member behavior
8. The movie’s internal cast includes two sounds (Click and Audio Track). By default, the Sound to Play field (shown in Figure 7-14) lists the Click cast member, which is the first sound cast member in your movie. If you click on the Sound pop-up menu button, you’ll see all the sound cast members available in the current movie. 9. Leave the Sound Channel field set to 1 and the When to Play Sound field set to when the mouse clicks on the sprite (a friendly term for mouseDown). Leave the Number of Loops parameter set to 1 so that the sound will play only one time.
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 255
Chapter 7 ✦ The Power of Behaviors
10. Click OK to accept the current parameters and attach the behavior to the Next button sprite. 11. In the Property Inspector, make sure the Play Sound Member behavior is listed as the first behavior. If not, select the behavior and click the Shuffle Up arrow to cause it to be listed (and executed) first. 12. Save the movie as engine4.dir. 13. Close all windows. Rewind and play the movie. 14. Click Next, and you hear the Click sound cast member play; then the movie advances to frame 5. 15. Stop the movie and rewind it. In the following exercise, you use the drag-and-drop method to attach the Play Sound Member behavior to the Enable Sound button on the Stage. You can use this method to attach any of the behaviors in the Behavior Library Cast.
Dragging and Dropping a Media Behavior onto a Sprite 1. Open the engine4.dir movie that you created in the last exercise. Rewind the movie if needed. 2. With the Cast window open, locate the Play Sound Member behavior. 3. Drag and drop the Play Sound Member behavior onto the Enable Sound button on the Stage. 4. When the Parameters dialog box appears, which is similar to the one shown previously in Figure 7-14, you must specify the desired settings. 5. Choose the AudioTrack sound from the Sound to Play? pop-up menu. 6. Set the Sound Channel field to 2 and the When to Play Sound field to when the mouse is released over the sprite (a friendly term for mouseUp). You want the AudioTrack to play in sound channel 2 because the Click sound that you selected for the Next Screen button will play in sound channel 1. Set the Number of loops parameter to 0, which enables the member to loop indefinitely. Caution
Only one sound at a time can play in each sound channel. If you had specified sound channel 1 for the AudioTrack member, it would stop playing when the Next Screen button is clicked.
7. Click OK to finish setting the parameters for the behavior attached to Enable Sound sprite. 8. Save the movie as engine5.dir.
255
3486-6 ch07.f.qc
256
7/24/00
5:44 PM
Page 256
Part II ✦ Bringing It All Together
9. Close all windows. Then rewind and play the movie. Click the Enable Sound button, and the AudioTrack cast member plays when the mouse button is released. The click sound also plays if you click the Next Screen button. 10. Stop the movie and rewind it. You could have set the AudioTrack member property to loop instead of setting it with the parameter in the Play Sound Behavior. Setting the looping parameter in the behavior gives you more flexibility than setting the cast member property to loop, because you can use it in other places in the movie without having the sound loop. Caution
Setting a loop in the Play Sound Parameter can have very unexpected results if the member’s looping property has also been set. Use one or the other.
Using the interactive behaviors In addition to navigational and media behaviors, Director includes prescripted interactive animation behaviors. These behaviors alter the appearance of sprites on the Stage. In the following exercise, you add the Rollover Member Change behavior to the engine5.dir movie, which changes the appearance of a specific sprite when the mouse pointer rolls over it. In this example, three parts of the rocket engine (the Oxygen Tank, the Mixing Chamber, and the Hydrogen Tank) will highlight and display a label describing the specific engine part. The sprites are located in channels 11, 12, and 13 of frame 5 of the Score, and are named O2, mix, and hydro. On the CD-ROM
You can find the file engine5.dir on the companion CD-ROM in the EXERCISE:CH07 (EXERCISE\CH07) folder. You also can use the engine5.dir movie that you created in the preceding exercise in this chapter. You also use the Rollover Member Change behavior, which is in the Library Palette.
Adding a Behavior That Swaps One Sprite for Another 1. Open the engine5.dir movie. In the Score window, move the playback head to frame 5. Note that there are three sprites (in channels 11, 12, and 13) that are colored light blue. These are the sprites to which you will apply the Rollover Member Change behavior. 2. Be sure the Library Palette is open. Then choose Animation ➪ Interactive from the Library List pop-up menu. Locate the Rollover Member Change behavior. 3. Drag and drop the Rollover Member Change behavior from the Library Palette onto the O2 sprite, located on frame 5 in Sprite channel 11 of the Score, as shown in Figure 7-15.
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 257
Chapter 7 ✦ The Power of Behaviors
02 Sprite
Rollover member change behavior
Figure 7-15: You can drag a behavior from the Library Palette directly onto a sprite in the Score window.
4. When the Parameters dialog box appears, the cast member that is displayed in the cast member selection pop-up menu is called O2 on. This parameter always displays the next available cast member in the Cast window. Because the O2 on cast member is the one you want, click OK to return to Director’s main window. 5. Select the sprite in channel 12 (mix) and apply the Rollover Member Change behavior, using the behavior pop-up menu in the Score window. Select mix on as the rollover member. Repeat this step for the hydro sprite in channel 13, using hydro on as the rollover member. 6. Save the movie as engine6.dir. 7. Close all windows, and play the movie. If you rewound the movie, click on the Next Screen button to advance to frame 5. 8. Move the mouse pointer over the engine parts on the rocket. Each part becomes highlighted and a label describing the part appears. 9. Stop the movie.
257
3486-6 ch07.f.qc
258
7/24/00
5:44 PM
Page 258
Part II ✦ Bringing It All Together
Creating complex rollover cast members The effect created in the preceding exercise required some planning before the elements were brought into Director. By default, Director sets the registration point to the center of a cast member’s bounding box when it is imported into the program. Because the rollover cast members are larger than the ones that are on the Stage, they would have appeared to jump when you rolled over them with the cursor. I could have reset the registration point of the rollover cast members in the Paint window, but this would have been very time-consuming. The easier solution was to add the connecting lines and text labels to the cast members after importing them into Director using the Paint window. This technique assured that the registration point would be exactly the same for both the original and rollover cast members because they were the same exact size when they were imported into Director. The labels had to be created at some point in the process, so adding them in the Paint window after importing them into Director added no time to the process of creating the graphics, yet saved quite a bit time in Director by not having to manually re-register them.
Creating Your Own Basic Behaviors To this point, you have used the Behavior and Property Inspectors to add, remove, and view the behaviors attached to a specific sprite. You can also use the Behavior Inspector to create simple behaviors and still avoid the need to script or program interactivity from scratch. Tip
The Behavior Inspector operates similarly to a macro editor, where specific choices you make are converted to the required Lingo code. As you use the Behavior Inspector to create new behaviors, you may be tempted to examine the scripts that are generated — which is a good learning technique — but you probably want to read Chapter 11 first. You can learn a great deal by observing how the Behavior Inspector translates your choices into basic Lingo functions.
The process required to create a new behavior varies depending on the nature of the behavior. In general, you must complete these steps: 1. Open the Behavior Inspector by choosing Window ➪ Inspectors ➪ Behavior Inspector, or by clicking the Behavior Inspector button in the toolbar or Score window. 2. Click the Behavior pop-up button and select the New Behavior option. 3. When the Name Behavior dialog box appears, as shown in Figure 7-16, enter an appropriate, descriptive name for the behavior, and click OK. Figure 7-16: The Name Behavior dialog box
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 259
Chapter 7 ✦ The Power of Behaviors
Note
When you create a new behavior, it is stored either in the currently selected empty cast slot or in the next empty cast position, if the current slot is occupied.
4. If the editing pane is not visible, click the upper arrow to expand the Editing pane for the Behavior Inspector (identified in Figure 7-17). Note
The top arrow alternately contracts and expands the Editing Pane. The bottom arrow, identified in Figure 7-17, alternately expands and contracts the Description pane. The Editing pane displays the events and actions included in the current behavior. No events or actions appear when you first begin to create a new behavior.
Event pop-up button
Shuffle down
Shuffle up
Event pane (events & actions) Expand/Collapse pane
Description pane
Figure 7-17: The Behavior Inspector with the Editing and Description panes expanded
5. At this point, you can add events to the behavior by using the Event pop-up button and add actions by using the Action pop-up button. Each time you add an event, you must add a corresponding action (that occurs in response to the event). You can assign more than one action to each event. Note
The Actions available from the Action pop-up menu are grouped into six categories: Navigation, Wait, Sound, Frame, Sprite, and Cursor. A seventh option, New Event, enables you to create a new, user-defined event. This feature requires that you know how to create scripts using Lingo.
259
3486-6 ch07.f.qc
260
7/24/00
5:44 PM
Page 260
Part II ✦ Bringing It All Together
Tip
You can use a similar process to edit events and actions assigned to an existing behavior. Simply highlight the behavior, select the event from the list, and then add new actions or delete any existing actions from the actions list. To delete an event or action, select it and then press the Delete or Backspace key.
6. You can alter the sequence of actions within a behavior by using the Shuffle Up and Shuffle Down arrows just above the Editing pane. 7. When you have finished adding events and their corresponding actions, you can close the Behavior Inspector (or leave it open) and save your movie — which now includes the newly defined behavior. Unfortunately, there is no way to add a description to a behavior without having to resort to Lingo. Note
As you become familiar with Lingo (starting in Chapter 11), you’ll discover that the Behavior Inspector provides a transparent way of creating Lingo code. The syntax of event names in the Behavior Inspector is similar to the Lingo code used for these behaviors (Mouse Up = mouseUp, for example).
To get good at building your own behaviors, you need to understand what types of actions generate each event. The Event found in the pop-up menu and the actions that generate them are listed in Table 7-1.
Table 7-1 Standard Events Event
Action That Generates the Event
MouseUp
Occurs when the left mouse button is released after being pressed (clicked). It is called only once, and only if the mouse button is released while within the active area of a sprite (see MouseWithin).
MouseUp
Occurs when the left mouse button is pressed (clicked) but not released. Generally, it’s better to assume that the user has not made a selection (such as clicking on a menu item or button) until the mouse button is released. This gives users a chance to move the mouse pointer off an object if they have inadvertently pressed the mouse button over the wrong object.
MouseEnter
Occurs when the cursor moves into the active area of a sprite. This event is generated only once upon each entry into the sprite, after which MouseWithin events are generated. This is a good point at which to display highlight states for a button, write out status messages, call pop-up menus, and so forth.
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 261
Chapter 7 ✦ The Power of Behaviors
Event
Action That Generates the Event
MouseWithin
Occurs repeatedly while the cursor is within the active area of a sprite (that is, in the sprite’s bounding rectangle, unless the sprite is displayed with Matte ink). The actions generated by this event should be short and to the point, because when you write a script that traps (responds to) this event, it can slow system performance if the mouse stays within a sprite’s area for a prolonged period of time.
MouseLeave
The cursor moves out of the active area of a sprite; this is the only time this event is called. It’s a good point at which to set highlight states for buttons back to their base states, revert status messages to the background message, hide pop-up menus, and so forth.
KeyUp
Occurs each time a key is pressed and released. Works only for controls that have text field components, and only if the control currently has the focus. See Chapter 14 for more information about text fields.
KeyDown
Occurs each time a key is pressed but not released. Only works for controls that have text field components and only if the control currently has the focus. See Chapter 14 for more information about text fields.
RightMouseUp
Occurs when the right mouse button is released. This obviously applies primarily to Windows-based machines, because Macintosh mice have only one button. To simulate a mouse right-click on the Macintosh, Control+click.
RightMouseDown
Occurs when the right mouse button is pressed. This obviously applies primarily to Windows-based machines, because Macintosh mice have only one button. To simulate a mouse right-click on the Macintosh, Control+click.
PrepareFrame
Occurs after the playback head exits a frame and prior to the next frame being painted on the screen. This is a good place to check to whether a visible sprite needs to be invisible or vice versa.
ExitFrame
Called after the frame has been drawn and all sprites have been tested for events. This is a good point for navigating to different frames.
BeginSprite
Occurs when the playback head moves to a frame that contains the first instance of the sprite. This event occurs only once, even if the playback head is looping on the frame. Continued
261
3486-6 ch07.f.qc
262
7/24/00
5:44 PM
Page 262
Part II ✦ Bringing It All Together
Table 7-1 (continued) Event
Action That Generates the Event
EndSprite
Occurs when the playback head leaves the last frame containing the sprite and moves to a frame where the sprite no longer exists. The event is generated after exitFrame.
NewEvent
Gives you the ability to create a customized event handler for the behavior. Using this feature requires that you know how to script using Lingo and how to create a user-defined handler, which is explained later, in the Lingo section of this book.
Creating a New Behavior In the following exercises, you create a new behavior and then attach it to the Enable Sound button in the engine6.dir movie (after deleting a prepackaged behavior that plays a click sound when you click on the button). The new behavior applies the Add Pin ink to the sprite, making it appear to be highlighted when the mouse clicks on it and then reverses the ink back to the copy ink when the mouse button is released. The new behavior also plays the Click sound. You then add a mouse leave event that resets the sprite if the mouse rolls off the button before it is released. On the CD-ROM
The file engine6.dir is on the companion CD-ROM in the EXERCISE:CH07 (EXERCISE\ CH07) folder. Alternatively, you can use the version that you saved in the preceding exercise.
Building the mouseDown event 1. Open the engine6.dir movie and rewind it. 2. Click on an empty cell in frame 1 to deselect all sprites in the movie, or click an empty slot in the Cast window. Now open the Behavior Inspector. Caution
If a sprite is selected when you create a new behavior, the behavior will be applied to the sprite automatically.
3. If the Editing pane is not expanded, click the top arrow to expand it. The Behavior Inspector should appear empty, like the one shown in Figure 7-18. Tip
You can also resize the panes of the Behavior Inspector. To do so, move the mouse pointer to the horizontal lines (pane dividers) that divide the panes. When the cursor changes to a double-headed arrow (a resizing cursor), drag up or down to resize the pane.
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 263
Chapter 7 ✦ The Power of Behaviors
Pane dividers Figure 7-18: You can drag the pane dividers to resize the panes of the Behavior Inspector.
4. Click the Behavior pop-up button and select the New Behavior option. 5. When the Name Behavior dialog box appears, change the default behavior name to Better Button and click OK. 6. Click the Events pop-up button and select the Mouse Down option so that the Events pane matches Figure 7-19. Figure 7-19: Attaching the mouseDown event to the Better Button behavior
263
3486-6 ch07.f.qc
264
7/24/00
5:44 PM
Page 264
Part II ✦ Bringing It All Together
7. Click the Action pop-up button and then choose Sprite ➪ Change Ink. 8. When the Specify Ink dialog box appears, select the Add Pin ink effect from the pop-up menu, as shown in Figure 7-20. You’ll need to scroll down the list to find the Add Pin option. When the option is set, click OK to close the dialog box. Figure 7-20: Choose Add Pin for the Change Ink option.
9. To add a second action to the mouseDown action, click the Action pop-up button and choose Sound ➪ Play Cast Member. 10. When the Specify Sound Cast Member dialog box appears, set the Play Sound setting to Click, as shown in Figure 7-21. Next, click OK to close the dialog box. 11. Save the movie as engine7.dir. Figure 7-21: Choose Click for the sound cast member.
In the next exercise, you add a new event/action to the behavior, which causes the ink for the button to be reset to Copy on the Mouse Up action (when the user releases the mouse button).
Creating the mouseUp Event and Action 1. Open the engine7.dir movie, and double-click on the Better Button behavior in the Cast window to activate the Behavior Inspector. 2. Click the Events pop-up button, and select the mouseUp option. 3. Click the Action pop-up button, and choose Sprite ➪ Change Ink. 4. When the Specify Ink dialog box appears, make sure the Ink effect is set to Copy, and then click OK to close the dialog box. 5. With the Behavior Inspector still open, select the Enable Sound button sprite on the Stage. Click the Behavior pop-up button, and select the Better Button property.
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 265
Chapter 7 ✦ The Power of Behaviors
6. Click the Shuffle Up button so that the Better Button behavior will execute before the Play Sound Member behavior. 7. Save the movie as engine8.dir, rewind it, and play it. Click the Enable Sound button; you’ll notice the change in ink and you’ll hear the Click sound, and then the AudioTrack sound will play when the mouse is released over the button. 8. Now stop the movie, rewind it, and play it. This time, click the Enable Sound button, and with mouse button still down, drag the mouse off the sprite. Note that the button is still highlighted, as shown in Figure 7-22.
Figure 7-22: The Enable Sound button remains highlighted after the cursor is dragged off the sprite before releasing the mouse button.
If users drag the cursor off the Enable Sound sprite before letting go of the mouse button, they can become confused, because the button is still highlighted and might appear to a user as if it should be doing something. To correct this problem, add a mouseLeave event that resets the ink of the Enable Sound sprite back to Copy.
Creating the mouseLeave Event and Action 1. Open the engine8.dir from the preceding exercise, if it’s not already open. 2. Open the Better Button behavior in the Behavior Inspector.
265
3486-6 ch07.f.qc
266
7/24/00
5:44 PM
Page 266
Part II ✦ Bringing It All Together
3. Click the Add Event pop-up button, and select the mouseLeave event. In the Actions pane, choose the Change Ink option and set the ink to Copy. 4. Save the movie as engine9.dir, and then rewind and play it. Click the Enable Sound button and drag the cursor off the button without letting go of the mouse button. The ink changes back to Copy, restoring the sprite to its original state. Note
At this point, it’s a good idea to replace the behavior applied to the Next Screen with your new Better Button behavior to ensure that both buttons behave in similar fashion.
5. Rewind the movie and stop it, making sure that the playback head is in frame 1. With the Behavior Inspector still open, select the Next Screen button sprite on the Stage or in the Score window. 6. In the Behavior List pane, select the Play Sound Member behavior and delete it. 7. Click the Behavior pop-up button, and select the Better Button behavior to attach it, as shown in Figure 7-23. Figure 7-23: The modified behavior list
8. Shuffle the Better Button behavior so that it is first in the list of behaviors attached to the Next button. 9. Save the movie again as engine9.dir, and then rewind and play it. Click the Next Screen button and note the change in ink, the click sound, and that the playback head advances to frame 5.
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 267
Chapter 7 ✦ The Power of Behaviors
The Better Button behavior still lacks some behaviors commonly associated with a “well-behaved button.” In the next exercise, you add two more events/actions to the behavior that provide a visual cue to users when the mouse pointer moves over an active area on the Stage. You add an action to the new behavior that changes the cursor (mouse pointer) to a pointing finger when it moves over a button to which the behavior is attached. In Director, as in life, whatever is done must eventually be undone, so you also add a second behavior that restores the cursor to its normal state when the mouse pointer is not within the bounding box of the sprite (to which the behavior is attached).
Adding a Cursor Change to Your User-defined Behavior 1. With the engine9.dir movie and the Behavior Inspector still open from the preceding exercise, select the Better Button behavior in the Behavior List pane. 2. Click the Events pop-up button, and select the mouseWithin event. 3. Click the Action pop-up button, and then choose Cursor ➪ Change Cursor, as shown in Figure 7-24. Figure 7-24: Select the Cursor option from the Actions pop-up menu.
4. When the Specify Cursor dialog box appears, select the Finger option (see Figure 7-25). Click OK to close the dialog box. Figure 7-25: Choose the Finger cursor in the Specify Cursor dialog box.
267
3486-6 ch07.f.qc
268
7/24/00
5:44 PM
Page 268
Part II ✦ Bringing It All Together
5. To add a fourth event/action to the Better Button behavior, one that sets the cursor back to a pointer after the behavior is exited, be sure the Better Button behavior is still selected in the Behavior List pane of the Behavior Inspector. 6. Click the mouseLeave event that you added earlier. 7. Click the Action pop-up button and choose Cursor ➪ Restore Cursor. 8. Save the movie as engine10.dir. Rewind the movie, and then play it. Move the mouse pointer over the Sound and Next buttons (both have the Better Button behavior with the modified events attached). Note the change in the cursor when it is over the two buttons as compared to when it is not. Try out the Sound and Next buttons and note that all the previous actions assigned to this behavior still work. Director has almost any cursor type that you might need for your movies. Table 7-2 Shows each of the built-in cursors, as well as a description of the situation in which you should use them. Each cursor also has a number to which you can refer when creating Lingo scripts that call a particular cursor. Many programs use these cursors to indicate their tools and the cursors have come to mean specific kinds of operations. Note that switching to a specific cursor in your movie does not cause that cursor to perform that operation. You still have to develop the behaviors to do that. Note
The graphics of the cursors listed in Table 7-2 were taken from a Macintosh. Some cursors will look slightly different on Windows computers.
Table 7-2 Director’s Built-in Cursors Cursor
Name
Use
Cursor Number
Arrow
Standard Arrow pointer used to point on the screen. Usually the default cursor setting.
0
I-Beam
Used to indicate a text insertion point.
1
Crosshair
Used to indicate the starting point of a selection.
2
Crossbar
Denotes a selection that will be added to.
3
Watch
Usually used to indicate when the movie is paused in order to perform a read or write file activity.
4
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 269
Chapter 7 ✦ The Power of Behaviors
Cursor
Name
Use
Cursor Number
Blank
Hides the cursor. Used mainly for touch-screen applications.
200
Help
Used to point to an element on the screen that the user needs help using.
254
Finger
Indicates that some action can be taken if the user clicks on the element over which the cursor is positioned.
280
Hand
Enables the user to move the Canvas in much the same way that a piece of paper can be moved around a desktop.
260
Closed Hand
Used for when a user clicks on an element that can be dragged.
290
No Drop Hand
Indicates the element cannot be placed in the current position.
291
Copy Close Hand
Usually used with an Option (Alt) modifier key to drag a copy of an element.
292
Pencil
Used to draw a single pixel on the Stage. Often used with the Shift modifier key to constrain the selection horizontally, vertically, or to a 45-degree angle.
256
Eraser
Erases pixels that are under the cursor. Usually replaces them with the current background color. Often used with the Shift key to constrain the eraser horizontally, vertically, or to a 45-degree angle.
257
Select
Indicates that a rectangular bounding box can be created to make a selection. Often used with the Shift modifier key to constrain the selection to a square.
258
Bucket
Fills any connected pixels containing the same color that the icon is over.
259
Continued
269
3486-6 ch07.f.qc
270
7/24/00
5:44 PM
Page 270
Part II ✦ Bringing It All Together
Table 7-2 (continued) Cursor
Name
Use
Cursor Number
Lasso
Indicates that the user can create a free-form selection. Often used with the Shift modifier key to constrain the selection horizontally, vertically, or to a 45-degree angle.
272
Dropper
Used to indicate that the user can “suck” the color that is currently used under the cursor.
281
Air Brush
Used to indicate the user can spray pixels onto the screen, using a predetermined size and flow setting.
301
Zoom In
Indicates the screen will Zoom in by a predetermined increment from the chosen point.
302
Zoom Out
Indicates the screen will Zoom out by a predetermined increment from the chosen point.
303
Vertical Size
Usually used to indicate that a dialog box or window element can be sized vertically.
284
Horizontal Size
Usually used to indicate that a dialog box or window element can be sized horizontally.
285
Diagonal Size
Usually used to indicate that a dialog box or window element can be sized diagonally.
286
Creating Multi-State Buttons Until now, the button behaviors that you have created in this chapter have all used a single cast member. To enhance the look and feel of a button, you can create a multi-state button that consists of four different cast members that are assigned to the various states of the button. An effective multi-state button changes according to the event that is occurring in the life of the button. It should highlight when the mouse rolls over it, appear to be pressed while the mouse is being clicked on it, and then pop back up to its original state when the mouse button is released. In some situations, there should also be an inactive state that informs the user that
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 271
Chapter 7 ✦ The Power of Behaviors
the button is not available in the current context of your presentation. Adding a sound that plays when the button is clicked completes the user experience. Director has a couple of very useful behaviors that make it easier to create multistate buttons: the Push Button and the Multi-State Toggle behaviors. Although both behaviors enable you to assign a different cast member for each event, they each perform a different action. ✦ You use the Push Button behavior to create multi-state buttons that will either revert to their original state or that will appear to be inactive after they have been clicked. ✦ The Multi-State behavior acts like a toggle. You can vary the states of a single button between an on state and an off state. This behavior can also be applied to a group of buttons that will act like radio buttons. When one button in the group is set to its on state, the other buttons in the group are set to their off state.
Creating a push button In the next exercise, you apply the Push Button behavior to the Launch Rocket button and set the parameters of the behavior so that the button appears to light up when the mouse is rolled over it, and then appears to be pressed when it’s clicked on. You also add a click sound to the mouseDown and mouseUp states. You then apply the Rollover Cursor Change behavior so that the cursor changes to a finger when it is rolled over the sprite. This parameter works the same way as the change cursor event that you added to the Better Button behavior earlier in this chapter. On the CD-ROM
For the following exercise, you need to use the engine10.dir movie that you saved in the preceding exercise, or you can use the engine10.dir file found on the CD-ROM in the EXERCISE:CH07 (EXERCISE\CH07) folder.
Applying the Push Button Behavior 1. Open the engine10.dir movie, and then open the Library Palette. 2. Locate the Push Button behavior in the Controls category, and drag it onto the Launch Rocket sprite on the Stage. 3. The Parameters dialog box for this behavior appears. Note that the cast members were automatically assigned in the graphics options for this behavior. Like some of the other behaviors that you applied to other sprites, this behavior applies the cast members that follow the one to which the sprite is referring. Unless you have rearranged the cast members used for the Launch Rocket button, they should be in the correct order. The cast members that are applied to each event in the graphics options should be the ones shown in Figure 7-26.
271
3486-6 ch07.f.qc
272
7/24/00
5:44 PM
Page 272
Part II ✦ Bringing It All Together
Figure 7-26: A cast member is applied to each event in the graphics options parameters. Tip
In the Cast window, arrange the cast members in the order that they will appear in the behavior Parameters dialog box. This will save a lot of time if you are applying the behavior to several buttons. It’s also a good idea to add the name that is used for each state of the button (“roll,” “down,” “inert”) as the second word in the cast member’s name. This makes it much easier to find the correct cast member for each state of the button.
4. With the Parameters dialog box still open, select the Click sound cast member for both the Sound to play on mouseUp and the Sound to play on mouseDown options. Caution
If you choose to add a sound option to this behavior, make sure that you specify a sound cast member for both the mouseUp and mouseDown options; otherwise, this behavior will not function correctly.
5. Use the default settings for the last four options, because you want the button to be active on the Stage, and no sprites are covering the sprite to which this behavior is being applied. 6. Save the movie as engine11.dir. Rewind the movie and play it. Roll the mouse over the Launch Rocket button and click on it to see the different states that have been applied. 7. Stop the movie, and drag the Rollover Cursor Change behavior (choose Animation ➪ Interactive in the Library Palette) onto the Launch Button sprite on the Stage. 8. Make sure that the Finger cursor is selected in the Rollover Cursor dialog box, and then click OK to return to Director’s main window (see Figure 7-27).
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 273
Chapter 7 ✦ The Power of Behaviors
Figure 7-27: The Rollover Cursor change behavior enables you to change the cursor to a finger when it rolls over a sprite.
9. Save the movie again as engine11.dir, and then rewind the movie and play it. The cursor now changes to a finger when it is rolled over the Launch Rocket button. Later in this chapter, you add the navigation component to this button, which will advance the playback head to the frame in the Director movie where the sequence that launches the rocket occurs. In the next exercise, you rebuild the Enable Sound button, using the Multi-State button behavior, so that it acts as a toggle to turn the sound on or off.
Creating a multi-state toggle button You may have noticed that there is no way to turn off the AudioTrack sound other than by stopping the movie after it has started playing. You could create another button that turns off the sound, but this takes extra screen real estate, which is often at a premium in multimedia applications. A more effective way to turn the sound on and off is to have the Enable Sound button act as toggle — when the button is first clicked, the sound begins playing; if the button is clicked again, it stops the sound. The Enable Sound button should also have a visual cue informing the user that the button is either on or off.
273
3486-6 ch07.f.qc
274
7/24/00
5:44 PM
Page 274
Part II ✦ Bringing It All Together
The Multi-State Button behavior works in a way similar to the Push Button behavior in that you can specify different cast members for each event that occurs. The big difference is that you can specify cast members that respond to events for both the on and off states of the button. You can also assign a Lingo command that tells the button what operation to perform in the on and off states.
Adding the Multi-State Button Behavior 1. Open the Score window in the engine11.dir movie. Select the Sound button sprite in channel 6. 2. Open the Cast window, and expand the window so that the six cast members in slots 41 through 46 are visible. These are the cast members that you will use to build the new Enable Sound button (see Figure 7-28).
New enable sound button cast members Figure 7-28: The six cast members used for the Enable Sound button.
3. Select the cast member named soundOff normal in the Cast window, and choose Edit ➪ Exchange Cast Members or press Command+E (Ctrl+E) to switch the current cast member in sprite channel 6 with the soundOff normal cast member. Look at the Sprite Overlay for the Enable Button sprite on the Stage, and make sure that the soundOff normal cast member is listed in the cast member description. 4. Click on the Behavior button located on the Sprite Overlay for the soundOff normal sprite to open the Property Inspector. Select the behaviors that have been applied to the sprite, and then delete them. 5. Open the Library Palette and locate the Multi-State Button behavior in the Controls category, and then drag it onto the Enable Sound button sprite, either on the Stage or in the Score window.
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 275
Chapter 7 ✦ The Power of Behaviors
6. When the Parameters dialog box appears, note that the cast members have been automatically applied to the Standard, Rollover, and mouseDown events for both the off state and the on state options. The members that have been applied should match the ones shown in Figure 7-29. Note
If the cast members have been moved from their original order in the Cast window, you may need to select the correct cast members from the pop-up menus located next to each event option. The second word of each cast member name is the same as the state to which the cast member should be applied.
Figure 7-29: Make sure that the cast members that are shown here are the ones that are applied to the off state and on state events for the behavior.
7. After making sure that the correct cast members are assigned to the Parameters listed in the dialog box (see Figure 7-29), click OK or press Enter (or Return, if you’re using a Macintosh) to set the options and return to Director’s main window. Note
For now, you leave the COMMAND SENT and ID string parameters as they are. A Lingo command can be added to both the COMMAND SENT when switched ON and the COMMAND SENT when switched OFF parameters, shown in Figure 7-29, that can cause the button to perform a specific operation when the button is toggled to an on or off state. The default setting for these two parameters sends a message to all of the other sprites in the frame, notifying them of the current state (on or off) of the sprite that can be sent to other sprites on the Stage or to a Lingo movie script. For another sprite to take advantage of this command, it needs a behavior applied to it that contains a Lingo handler that can intercept the message. The ID string for the group parameter enables you to assign a group name to a series of buttons that will use this same behavior. This is useful for creating radio buttons. Because you are applying this behavior to only a single button, there is no need to enter a group name in this parameter.
275
3486-6 ch07.f.qc
276
7/24/00
5:44 PM
Page 276
Part II ✦ Bringing It All Together
8. Click on the behavior button of Enable Sound sprite to open the Property Inspector. Add the Rollover Cursor Change behavior to the sprite from the Behaviors pop-up menu. 9. Save the movie as engine12.dir. Then rewind the movie and play it back. Roll the cursor over the Enable Sound button and note that it becomes highlighted. When you click on the button, it changes to a different color, indicating that it’s active. When you click the button again, it reverts to its original state. When the Multi-State button behavior is applied to a group of buttons, the button that is clicked on is set to the ON state and all the other buttons are set to their OFF state. This behavior can enable you to create custom multi-state radio buttons that are more visually appealing than Director’s built-in radio buttons. In the next exercise, you add a very basic Lingo command that plays the AudioTrack sound cast member when the Enable Sound button is in its ON state, and then turns the sound off when the button is in its OFF state.
Adding a Lingo command to a behavior Several of the behaviors in the Library Palette enable you to add simple Lingo commands that perform specific operations, such as triggering a behavior that’s applied to a different sprite in the frame. You can also send messages to custombuilt Lingo handlers that can perform a variety of operations. You learn a great deal about Lingo commands and creating handlers beginning in Chapter 11 of this book. You don’t have to be a “power programmer” to use Lingo commands that increase the capabilities of a behavior. You use the puppetSound Lingo command to play the AudioTrack sound cast member when the Enable Sound button is toggled to its ON state, and then turn the sound off when the button is toggled to its OFF state. Playing sounds with Lingo is discussed in detail in Chapter 17. For now, you only need to know how to specify the sound channel that the sound will play in, specify the sound cast member that will play, then turn it off again.
Adding the puppetSound Lingo Command 1. Make sure the engine12.dir movie that you saved in the preceding exercise is open in Director. In the Cast window, select the Audio Track member, and click on the Properties button to open the Property Inspector. Click on the Loop check box to enable the sound file to loop whenever it is played. 2. With the Property Inspector window still open, select the Enable Audio sprite on the Stage or Score. You may need to click on the Behavior tab to make the Behavior window active. Click on the Parameters button in the Property Inspector to display the Parameters dialog box for the behavior.
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 277
Chapter 7 ✦ The Power of Behaviors
3. In the Command Sent When Switched On field, type puppetSound 2, “AudioTrack”. Make sure that you type this command exactly as shown in Figure 7-30, including the comma and quotation marks. This command tells Director to play the sound cast member called AudioTrack in sound channel 2 when the button is toggled to its ON state. 4. In the COMMAND SENT when switched OFF field, type puppetSound 2, 0 (see Figure 7-30). This command turns off the sound that’s playing in channel 2 when the button is toggled to its OFF state. The 0 in this Lingo statement is actually the equivalent of a FALSE command that acts as toggle to turn off the sound that is currently playing. You learn about true/false statements in Chapter 11. Note
True and false statements are Lingo’s way of turning a property on or off. They act like the on/off switch found on most electronic components. In fact, the symbol used for the on/off switch on most electronic equipment is a 1 or 0.
Lingo commands
Figure 7-30: Add the puppetSound Lingo command with statements that define the cast member and the sound channel, and turn off the sound.
5. Save the movie as engine13.dir. Rewind the movie and play it. Click on the Enable Sound button. The button toggles to its ON state and the AudioTrack sound cast member plays. Click the button again, and the sound stops playing and the button toggles to its OFF state. Adding simple Lingo commands is one way to greatly expand the capabilities of a behavior. As you learn more about Lingo in the second half of this book, you will be able to combine custom-built Lingo scripts with Director’s built-in behaviors to create very powerful multimedia applications.
277
3486-6 ch07.f.qc
278
7/24/00
5:44 PM
Page 278
Part II ✦ Bringing It All Together
Navigating with Markers Earlier we mentioned that multi-state buttons are far more useful if they actually do something when you click them. Fortunately, Director gives you an abundant collection of options as to what these buttons can do. One of the simplest and most useful roles for a multi-state button is providing the capability to jump to a different location in the Score. In earlier chapters, we briefly discussed markers, showing you how to use them to organize the Score. Markers are also indispensable for creating Director movies that will play back nonlinearly. After you begin learning scripting behaviors (in Chapter 11), you’ll discover that a simple instruction can direct the playback head to a frame number or a marker.
Adding markers to your movie Most of Director’s basic navigational commands and navigational behaviors make use of markers within a movie. As you learned earlier, markers are labels that you attach to specific frames. The steps to adding a marker are: 1. In the Score window, locate the Markers channel. As shown in Figure 7-31, the Markers Channel is immediately above the Effects channels.
Marker symbol Markers menu
Marker name
Markers channel
Figure 7-31: The Markers channel in the Score window
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 279
Chapter 7 ✦ The Power of Behaviors
2. Click in the Markers channel, above the frame where you want to add a marker. A symbol appears for the marker, as shown in Figure 7-31, along with a default marker name (New Marker). 3. You typically want to use a more specific marker name, such as Start. Just type it in, and the name you type replaces the default New Marker name. Tip
You can move a marker to a new location by dragging the marker symbol to a different frame.
To delete a marker, click on the triangular marker symbol and drag up or down off the Markers channel. You can choose from three different methods to display a list of all the markers in your movie: ✦ Choose Window ➪ Markers. In the Markers window, double-clicking on a marker name jumps the playback head to that marker. ✦ Click the Markers menu (see Figure 7-31) to display a pop-up menu of all markers. On the Markers menu, click the desired marker name to jump to that marker in your movie. ✦ Press Command+Shift+M (Ctrl+Shift+M) or choose Window ➪ Markers to display the Markers window shown in Figure 7-32.
Add new marker Previous marker Next marker
Marker frame indicator
Marker name Marker editing pane Figure 7-32: Use the Markers window to view all of the markers in your movie.
279
3486-6 ch07.f.qc
280
7/24/00
5:44 PM
Page 280
Part II ✦ Bringing It All Together
Now that you can add markers to your movies, you can use them to control the flow of your movie. You can combine button behaviors with frame and marker navigation to really enliven your interactive presentations. In the next series of exercises, you add markers to the engine13.dir movie, and then add a jump to marker behavior to the Launch Rocket button. On the CD-ROM
You use the engine13.dir movie that you saved in the previous exercise, or you can use the engine13.dir movie on the CD-ROM in the EXERCISE:CH07 (EXERCISE\ CH07) folder.
Adding Markers for Navigation 1. Open the engine13.dir movie in Director; then make sure the Score window is active. 2. Click in frame 1 of the Marker channel. Type Start. 3. Click anywhere in the Marker channel. Type Rollovers, and then drag the marker to frame 10. 4. Click anywhere in the marker channel and add a marker named Launch rocket. Then drag it to frame 15. The Score should look like Figure 7-33.
Figure 7-33: Click on a marker in the Marker window to move the movie’s playback head to the frame that contains the selected marker.
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 281
Chapter 7 ✦ The Power of Behaviors
5. Open the Markers window by choosing Window ➪ Markers or by pressing Command+Shift+M (Ctrl+Shift+M). Make sure that frames that have sprites in them are visible in the Score window, as shown in Figure 7-33. Click on one of the markers in the Marker window and the playback head jumps to the frame that contains the marker you selected. 6. Save the movie as engine14.dir. Now you need to add a behavior to the Launch Rocket button that jumps to the marker called Launch Rocket. The behavior you will add is called the Jump to Marker Button and is in the Controls category in the Library Palette.
Using the Jump to Marker behavior The Jump to Marker Button is a very flexible behavior that makes it easy to add navigation elements to your buttons. Like most other behaviors, it can be added to other behaviors that have already been applied to the sprite. This behavior automatically creates a list of the markers that are contained in the movie so that you can quickly choose any marker from the pop-menu that’s presented in the Parameter dialog box. Tip
It’s a good idea to add markers to your movie as early as possible in the production process. You can always delete them, add new ones, or move them around later. Not only does this make the movie easier to navigate while you’re building it, but it takes advantage of the Jump to Marker Button behavior’s capability to create a list of the markers contained in the movie.
Adding the Jump to Marker Button Behavior 1. Make sure that the engine14.dir movie that you saved in the preceding exercise is open in Director. Open the Library Palette, and choose the Controls category from the Library List button. 2. Locate the Jump to Marker Button behavior, and drag it into the Launch Rocket Button on the Stage. 3. The Parameters dialog box appears, as shown in Figure 7-34. For the On mouseUp, jump to marker parameter, six items appear in the list. The first three, Previous, Loop, and Next, enable you to jump to the next marker, the previous marker, or loop on the current marker. The last three items (Start, Rollovers, and Launch rocket) are the markers that are contained in the movie. Select the Launch rocket item from this list.
281
3486-6 ch07.f.qc
282
7/24/00
5:44 PM
Page 282
Part II ✦ Bringing It All Together
Figure 7-34: The dialog box for the Jump to Marker Button behavior enables you to specify a marker, determine how the movie goes to the marker, and set a parameter that remembers the frame from which the movie jumped.
4. Use the default Go to option for the Jump Mode parameter. You can uncheck the Remember current marker for Back button, although it won’t affect the behavior in any way if you leave it checked. Click OK to return to Director’s main window. 5. Click the Parameters button to display the Parameters dialog box for the behavior (see Figure 7-34). Note
There are two options in the Jump Mode pop-up menu. They are Go to, which jumps to the specified marker, and Play and Return, which is used when you want to go to a marker to perform some activity and then jump back to the marker that you came from. If you choose the Play and Return option, you will probably want to make sure that the check box located next to the Remember current marker for Back button is checked. This enables the behavior to remember which markers have been visited.
6. Now you need to add a Hold on Current Frame behavior to frame 10 (under the Launch rocket marker) so that the movie loops on that frame. Open the Score window and click in frame 10 of the script channel. 7. Select the Hold on Current Frame behavior from the Behavior pop-up list in the Score window, as shown in Figure 7-35. Note
To perform the operation in Step 7, you may have to enable the Sprite toolbar in the Score window by Control+clicking (Alt+clicking) the Frame bar and choosing the Sprite Toolbar option.
8. Save the movie as engine15.dir. Rewind the movie and play it back. Click on the Launch Rocket button. It now jumps to the marker called Launch rocket. Caution
Try to avoid having two markers with the same name. The Jump to Marker Button behavior jumps to the first marker that contains the name specified. If you have two markers with the same name, you might have unexpected results.
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 283
Chapter 7 ✦ The Power of Behaviors
Figure 7-35: Apply a behavior to the script channel or a sprite in the Score window from the Behaviors pop-up menu.
When you use the Jump to Marker Button behavior in combination with the Jump Back behavior, you can have a button jump to a specific marker and then jump to frame that it came from. Most of the other button navigation behaviors found in the controls category act similarly to the Jump to Marker Button behavior. You can use the other button behaviors in the Controls category to jump to a different movie, and then return to the previous movie. By now you have learned that Director’s built-in behaviors are very powerful, enabling you to add sophisticated interactivity to your movies. You can add multiple behaviors to a sprite that add layers of interactivity and good user interface design to the navigation elements in your movies. The movie to which you have been adding these behaviors is pretty simple; there aren’t too many buttons that need to have multiple behaviors applied to them. In a large project, applying many individual behaviors to each sprite can be a timeconsuming task. This is where Lingo comes to the rescue: You can create custom behaviors that combine the events and parameters of several different behaviors.
Where Did that Behavior Come From? As mentioned earlier, behaviors are scripts (and you’ll learn a great deal more about scripts in Chapter 11). Unlike many other development languages, Director’s scripts are actually kept as a resource. Specifically, the script is a cast member that contains the text of the script, as well as the internal code that stores the script when played at run-time. From the standpoint of the developer, a script is an autonomous entity, and behaviors are especially independent.
283
3486-6 ch07.f.qc
284
7/24/00
5:44 PM
Page 284
Part II ✦ Bringing It All Together
The independent nature of scripts and behaviors means that they can be collected in a cast and used in a variety of projects. An external cast can really include any kind of cast member (bitmap, text, script, video, and so on). The Library Palette is really just a collection of external casts that are stored in the Libs folder located in the Director Application folder. Although the Library Palette as shipped with Director contains only behaviors, you can add to the Library Palette any kind of cast member that can be contained in a Cast window. For instance, if you’re using a logo that appears in all of your movies, you can put the logo into an external cast and then move it into the Libs folder; it will appear in the Library Palette. A custom multi-state button behavior we call the MultiPurpose Button behavior was developed specifically for this book, although it might be useful to you in a variety of circumstances. Along with the MultiPurpose Button behavior, we also include several types of multi-state button cast members, and several sounds that were optimized for use with buttons. These elements are contained in a Cast Library called coolbuttons.cst. You can link them to your own movies and use them royalty-free, although you should read the comments (included as a text cast member in the Library) for more details. On the CD-ROM
The coolbuttons.cst Cast Library is on the CD-ROM in the EXERCISE:CH07 (EXERCISE/CH07) folder. There is also a folder in the Goodies section of the CD-ROM called COOLBUTTONS, which contains all of the original artwork created for the buttons found in the coolbuttons.cst Cast Library. They are supplied in both Photoshop 5.0 and Fireworks 2.0 formats, which you can modify using either of these two programs. Last but not least, is a folder called Buttons that you can drag into your Libs folder; it includes the buttons arranged by convenient categories in your Library Palette.
Cool button factories The artwork that was created for all of the buttons in the coolbuttons.cst Cast Library started life as Photoshop 5.0 artwork. Both Photoshop and Fireworks have the capability to create graphic documents that contain many layers. You can take advantage of this capability by creating what this author calls factories, which have layers containing all of the states of a button in a single document. There are several advantages to this technique. The first is that you need to manage fewer documents for the original artwork that you create for your movies. A second advantage is that you can view how the different states of the button look by turning on and off each layer that contains the different button state graphic. After you are satisfied with each state of your button, you can create the individual cast members by turning on the appropriate layers and performing a Save As operation in Photoshop or Exporting in Fireworks. Spend some time looking at the button factories to get a better idea of the power of this technique. In fact, after you become familiar with the factories, feel free to modify them (by adding text labels, for example) for your own movies.
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 285
Chapter 7 ✦ The Power of Behaviors
Cast libraries In traditional programming languages such as C and C++, creating an application is sometimes a challenge. Many developers manage the overall project by breaking it up into distinct tasks — that is, by separating the application into modules. Director originally didn’t support this method — everything had to be contained in a single movie, and that typically meant a lot of duplication if one movie needed to have the same resources as another. Cast Libraries were Director 5.0’s answer to the demands of developers for a more efficient container of resources. A Cast Library is a separate and discrete entity. It has its own cast members and can be used to store any cast members that the normal internal cast can use. There’s no real limit to the number of Cast Libraries a movie can open (although certainly system limitations will limit the number). Cast Libraries come with some drawbacks. Because they are linked as an external source, you need to be careful not to move either the director movie that is using the library or the Cast Library itself to another location. You also need to include any external Cast Libraries that are used in a movie when outputting a Director movie as a Projector, Shockwave movie, or Java applet. It also possible to accidentally modify an element in a linked cast and then save over the original Cast Library, thus losing the original element forever. If you have elements such as scripts, behaviors, or graphics that you want to preserve in their original state, you might want to put the casts into the Libs folder so that they will appear in Library Palette. As you know by now, when you modify a behavior (or any other element that can be contained in the Library Palette), you are actually modifying a copy of the element that has been placed into an internal Cast window.
Adding a custom-built behavior to your movie We have created an external Cast Library called coolbuttons.cst that contains a very useful, all-purpose button behavior that combines the button states, cursor change, and navigation parameters into a single behavior. There are also several multi-state button graphics that you can use royalty-free in your Director movies. You will link the coolbuttons.cst Cast Library to your movie, and then replace the three behaviors that have been applied to the Launch Rocket button with the custom-built behavior called the MultiPurpose Button behavior. On the CD-ROM
The coolbuttons.cst is on the CD-ROM that came with the book in the EXERCISE: CH07 (EXERCISE\CH07) folder.
285
3486-6 ch07.f.qc
286
7/24/00
5:44 PM
Page 286
Part II ✦ Bringing It All Together
Linking Cast Libraries to Movies 1. Copy the coolbuttons.cst external Cast Library to a personal folder (where you saved your other Director movies) on your local hard drive. 2. Open the engine15.dir movie. 3. Choose Modify ➪ Movie ➪ Casts, or press Command+Shift+C (Ctrl+Shift+C) to display the Movie Casts dialog box (see Figure 7-36). Figure 7-36: The Movie Casts dialog box enables you to link Cast Libraries to your current movie.
4. Click the Link button. This displays an Open (file) dialog box, where you can select a Cast Library (any file with the .cst or .cxt extension). Locate the coolbuttons.cst external cast and double-click on it to link it to the current movie. After the cast is linked, you can access it through the Cast window. Note
If you have the CD-ROM in your CD-ROM drive, you can link to coolbuttons.cst on the CD-ROM located in the EXERCISE:CH07 (EXERCISE\CH07) folder, or if you’ve copied it to your local drive, you can locate it there.
5. Click OK to close the dialog box. 6. If the Cast window is not visible, open it by pressing Command+3 (Ctrl+3). 7. Click the Choose Cast button (the button in the upper-left corner of the Cast window), and a list of the active Cast Libraries for the current movie appears (see Figure 7-37). 8. Select CoolButtons to make the library available to the current Director movie. 9. Click the Cast Library button again and set the cast back to Internal, which is the default cast for a movie. This setting ensures that any new cast members you add will be added to the Internal cast rather than to the imported (CoolButtons) cast. 10. Save the movie as engine16.dir. You can also incorporate the coolbuttons Cast Library into the Library Palette. Just drag the coolbuttons.cst into the LIB folder found in the application folder for Director 8. This will enable you to access the MultiPurpose Button behavior and all of the button bitmap and sound cast members from the Library Palette. The
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 287
Chapter 7 ✦ The Power of Behaviors
advantage to this approach is that the behavior, button bitmap, and sound cast members will automatically be included in your movies.
Figure 7-37: Clicking the Cast Library button brings up a list of all the current Cast Libraries.
Still another way of accessing the cast members of a library is to place the Cast Library in the Xtras folder located in the application folder containing your copy of Director. This technique makes the cast available from the Xtras menu. For example, if you drag the coolbuttons.cst into the Xtras folder, you’ll see a CoolButtons entry in the Xtras menu. Note, however, that the cast is not actually linked to the file. You have to physically drag one or more cast members from the cast into your movie’s internal cast to make them work. If you use this method, Director prompts you whether to link the external cast or just transfer the selected cast members to the internal cast.
A cast library case study Two of the authors of this book were building a Director-based engine for an interactive news journal that would be updated on a daily basis. This was a huge undertaking that required several programmers and multimedia authors working simultaneously to meet the ever tightening deadline for the release of the product. The Director templates and interface elements being built for the application were being produced at the same time that the code was being written, so we had to have a way to update all of the different components. Cast Libraries came to our rescue. We divided up the components into several shared Cast Libraries that were stored in a specific location on the network, and then linked to the Director the movies that the multimedia authors were building. Because the source code was stored as several components in a linked Cast Library, new functionality and bug fixes were globally updated in all of the individual Director movies. It was an amazing sight to see a bug magically fixed on four different Director movies running on four different computers at the same time. We also used this approach to create custom authoring tools that were developed for the application.
287
3486-6 ch07.f.qc
288
7/24/00
5:44 PM
Page 288
Part II ✦ Bringing It All Together
Now that you have the Coolbuttons Cast Library attached to your movie, it’s time to replace the behaviors attached to the Launch Rocket button with the MultiPurpose Button behavior that was custom-built using Lingo. The advantage to the MultiPurpose Button behavior is that it replaces the Push Button, Rollover Cursor Change, and Jump to Marker Button behaviors with a single behavior that enables you to set all of the parameters used for the three behaviors that were previously applied to the sprite.
Adding a Custom Built Behavior 1. Open the engine16.dir movie in Director. Click on the Launch Rocket sprite on the Stage, and then click on the Behavior button in the Sprite Overlay to open the Property Inspector. 2. Delete the three behaviors that are applied to the sprite. 3. Add the MultiPurpose Button behavior from the Behavior List button. 4. When the Parameters dialog box appears, make sure the cast members selected for Up State, Down State, Roll State, and Inert State are the launchButton cast members shown in Figure 7-38. Tip
If you add the name of the state to which the cast member will be applied, it makes it much easier to locate them when it comes time to apply the cast member’s parameters to a multi-state button.
Figure 7-38: All of the cast members, except for the Up state, have the name of the state they are designed for as the second word in the cast member name.
5. Click on the Inert after use? check box so that the button will be inactive after it has been clicked. 6. Select the Click sound cast member for the sound parameter. 7. Click on the Action pop-up menus, and choose the go “Launch rocket” option. This behavior creates a list of the markers that are contained in the movie and adds them as options for the Action parameter.
3486-6 ch07.f.qc
7/24/00
5:44 PM
Page 289
Chapter 7 ✦ The Power of Behaviors
8. Make sure that the Finger option is set for the Use which cursor? parameter. If you click on the pop-up menu for this parameter, you will see a list of all the built-in cursors for Director. 9. Save the movie as engine17.dir. Rewind the movie and play it, and then click on the Launch Rocket button. The Launch Rocket button acts the same way as it did when it had the three different behaviors applied to it. Note
You can activate the button after it has been set to an inert (inactive) state by double-clicking on it. You can also activate the button by sending a custom message called the #enable message to the sprite with Lingo.
The MultiPurpose Button behavior was completely written in Director using Lingo. If you had to add the three original behaviors that were applied to the Launch Rocket button to 50 or 60 other buttons, it would be very time-consuming and would probably require a lot of debugging. This is a situation in which a custom-built behavior such as the MultiPurpose Button can save you a lot of creation time as well as prevent a swollen mouse finger. There are many situations where a well-designed custom behavior will save a tremendous amount of time building a Director movie. Suppose that you are building an application in which you want to test the user’s comprehension of the subject matter at different points in the Director movie. To accomplish this goal, you want to build a quiz in which the user drags pictures next to the words that define them. You could design a behavior in Lingo where you assign the matching graphic and text cast members, and add a parameter to apply sound cast members for positive and negative feedback sounds. There could also be a field where you could type in a custom message that will appear as a custom alert message. Combining all of these events into one single behavior would enable you to spend most of your time creating high-quality visuals for the quizzes instead of linking all of the pieces together with a series of individual Lingo scripts that would have to be modified for every quiz.
Sending a Message from One Behavior to Another Many of Director’s built-in behaviors can send a message to other sprites, behaviors, frame scripts, and cast member scripts. These messages are usually sent to a Lingo handler — a set of instructions that tells Director what to do when an event occurs. A message can be sent to a specific sprite, to all the sprites in the frame, to a specific behavior, to a frame script, or to a movie script. You learn how to send messages with Lingo starting in Chapter 11. In this chapter, we look at sending simple messages from one behavior to another.
289
3486-6 ch07.f.qc
290
7/24/00
5:44 PM
Page 290
Part II ✦ Bringing It All Together
You can find out whether a behavior can send or receive a message by looking at the behavior’s description in the Behavior Inspector. Director’s built-in behaviors will describe the message that can be sent to or from the behavior. Figure 7-39 shows the message that can be used to activate the SlideIn/Out behavior. There is a parameter setting for this behavior that can activate the behavior when the playback head enters the frame, by clicking on the sprite to which the behavior is attached, or by sending the mSlideActivate message from another behavior or Lingo script. Figure 7-39: The descriptions for Director’s built-in behaviors will list any specific messages that can be sent to and from the behavior.
Message to activate the behavior
Note
You have to drag a behavior from the Library Palette into the Cast window before you can view the behavior’s description in the Behavior Inspector.
The mSlideActivate message shown in Figure 7-39 activates the Slide In/Out behavior. When the behavior receives the message, it causes the rest of the events in the behavior to execute.
Sending a message from a behavior One of Director’s built-in behaviors that can be activated by a message sent from another behavior is the Countdown Timer behavior. This behavior is located in the text category of the Library Palette. The Countdown Timer behavior can be applied to a text or field cast member to create a digital clock that counts from a predetermined time down to zero. A message or command can be sent from this behavior to activate a behavior applied to another sprite when the timer reaches zero. In the next two exercises, you apply the Countdown Timer behavior to a text cast member that will execute when the movie enters the Launch Rocket frame. When
3486-6 ch07.f.qc
7/24/00
5:45 PM
Page 291
Chapter 7 ✦ The Power of Behaviors
the timer sprite reaches zero, it sends a message that initiates the Slide In/Out behavior that has been applied to the Rocket sprite, causing the rocket sprite to fly off the top of the Stage. On the CD-ROM
You need the engine17.dir Director movie for the next exercise. You can use the one that you saved in the preceding exercise or use the engine17.dir file on the CD-ROM in the EXERCISE:CH07 (EXERCISE\CH07) folder.
Creating a Countdown Timer 1. Open the engine17.dir movie in Director, and make sure the Cast window is active. 2. Open the Library Palette (choose Window ➪ Library Palette). Click on the Library List button, and select the Text category. Locate the Countdown Timer behavior and drag it into the Cast window. 3. Choose Animation ➪ Automatic in the Library Palette, locate the Slide In/Out behavior, and drag it into the Cast window. You can close the Library Palette to get it out of the way. Note
You will be sending a message from the Countdown Timer behavior to the Slide In/Out behavior, so you need to find out what message the Slide In/Out behavior requires to initialize it.
4. Locate the Slide In/Out behavior in the Cast window and double-click on the cast member to open it in the Behavior Inspector. In the Description pane is a sentence that describes how the behavior can be activated (see Figure 7-40). One of the options listed informs you that this behavior can be sent a message called mSlideActiviate. Double-click on the mSlideActiviate text in the Description pane to select it, and copy it to the Clipboard. Figure 7-40: The sentence describing the options that activate this behavior is highlighted.
291
3486-6 ch07.f.qc
292
7/24/00
5:45 PM
Page 292
Part II ✦ Bringing It All Together
Note
If the behavior opens in the script window, you should adjust the preferences so that behaviors open in the Behavior Inspector. Choose File ➪ Preferences ➪ Editors and then select the Behavior Inspector as the editor for behaviors.
5. Close the Behavior Inspector. In the Score window, advance the playback head to frame 10, and then on the Stage, select the text sprite called Countdown Timer. Drag the Countdown Timer behavior onto the sprite. The Parameters dialog box for the Countdown Timer behavior appears, as shown in Figure 7-41.
Figure 7-41: The parameters for the Countdown Timer behavior should be set as they are shown in this figure.
6. Note that this behavior can also be initialized by a message that is sent to it; however, in this situation, you will want the behavior to be activated when the playback head enters the frame where the sprite is located. Use the default setting for the Initializing event parameter. 7. Choose Hundredths from the Smallest time unit parameter pop-up menu. This choice displays the timer in hundredths of a second. 8. Move down to the Seconds to count down slider, and click on the advance arrow until the slider displays 10 seconds. You can also drag the slider to 10 seconds if you prefer. 9. Double-click the text in the field located next to the Message to send after countdown parameter to select it. Paste the mSlideActivate message, which you copied to the Clipboard earlier in this exercise, into the field. You can also type the mSlideActivate message into this field, but be careful that you type the message correctly.
3486-6 ch07.f.qc
7/24/00
5:45 PM
Page 293
Chapter 7 ✦ The Power of Behaviors
Tip
Whenever possible, it is better to select the actual message, copy it to the Clipboard, and paste the message into the field where you want the message to appear. This avoids the possibility of introducing a typing error that could cause the behavior to work incorrectly.
10. Use the default setting of all sprites for the Where to send message parameter, because you will be sending the message to another sprite. There is no need to check the Broadcast countdown time parameter in this situation. Note
The Broadcast countdown time parameter constantly sends the current time to all of the other sprites on the Stage. You are concerned only about sending a message when the timer reaches zero, so enabling this parameter will have no effect.
11. Click OK to set the parameters and return to Director’s main window. Save the movie as engine18.dir. Rewind the movie and play it. Click on the Launch Rocket button, and you will see the countdown sprite ticking off the seconds until it reaches zero. Even though the mSlideActivate message is being sent from the Countdown Timer behavior, nothing happens when the timer reaches zero seconds. The Slide In/Out behavior that this message will activate needs to be added to the rocket sprite before anything can happen. In the next exercise, you add the Slide In/Out behavior to the rocket sprite and set the parameter to activate the behavior when the behavior receives the mSlideActivate message.
Receiving a message from another behavior As you know, you can activate several of Director’s built-in behaviors by means of a custom message sent from a behavior applied to a sprite or to a Lingo script contained in the movie. Having a behavior be activated when a message is sent to it enables you to create very dynamic, event-driven animations that can happen in a single frame of your movie. This can save a lot of space in the Score window as well as make your movies more compact. You can create very complex Lingo movie scripts that can globally intercept messages that have been sent from behaviors, and then send the messages to appropriate sprites on the Stage to activate the behaviors that are applied to them. Combining Director’s built-in behaviors with custom Lingo scripts can save quite a bit of development time, because you would only create Lingo scripts that would interpret and distribute the messages. You can learn more about sending and receiving messages to and from sprites beginning in Chapter 11; this concept is used throughout the Lingo section of the book.
293
3486-6 ch07.f.qc
294
7/24/00
5:45 PM
Page 294
Part II ✦ Bringing It All Together
You can still take advantage of the messaging capabilities of a behavior without having any Lingo programming knowledge to execute them. There are many situations in which simply selecting the Activate with Message parameter for a behavior will accomplish the task that you need the sprite to perform. In the next exercise, you apply Director’s Slide In/Out behavior to the rocket sprite and set a parameter that initializes the behavior when the it receives the mSlideActivate message that is sent from the Countdown Timer behavior. When the behavior is activated, the rocket sprite automatically flies off the top of the frame.
Using a Message to Activate a Behavior 1. Open the engine18.dir movie that you saved in the preceding exercise in Director. In the Score window, advance the playback head to frame 10. 2. On the Stage, select the rocket sprite, and then drag the Slide In/Out behavior from the Cast window onto the sprite. The Parameters dialog box for the behavior appears (see Figure 7-42). The parameters for this behavior can be set to determine whether the sprite will slide in or out of the frame, and the direction that the sprite will slide. You can set a point to which you want the sprite to slide, determine how the behavior will be activated, select how many times the behavior will execute, and define the time period over which the sprite will slide.
Figure 7-42: The Slide In/Out behavior contains several parameters that can be set to control how the animation occurs.
3. Select the Out option from the Slide In or Out pop-up menu. This choice causes the sprite to move off the frame when the behavior is activated. 4. Select the Top option from the Automatic Slide Direction parameter’s pop-up menu so that the Sprite slides off the top of the frame. Note
You use the Horizontal and Vertical point values if you select the Point option for the Automatic Slide Direction parameter. You can set the Horizontal and Vertical points on the Stage to (or from) which you want the sprite to slide, depending on the Slide In or Out option that you selected.
3486-6 ch07.f.qc
7/24/00
5:45 PM
Page 295
Chapter 7 ✦ The Power of Behaviors
5. Choose the Message option from the pop-up menu next to the Start automatically, when clicked, or by message parameter. This behavior contains a Lingo handler that intercepts the mSlideActivate message sent from the Countdown Timer behavior and activates the rest of the behavior. 6. Use the default setting ( 0 ) for the Slide cycles parameter, because you want the sprite to animate only one time. 7. You can use the slider controls next to the Time period for slide parameter to set the amount of time that the animation will use to slide the sprite to its end position. 8. Click OK when you have selected the parameters that you want for the behavior to return to Director’s main window. 9. Save the movie as engine19.dir. Rewind and play it. Click on the Launch Rocket button. The Countdown Timer activates and begins counting down to zero. When the timer reaches zero, it sends the mSlideActivate message to the Slide In/Out behavior. This activates the behavior and causes the rocket to appear to fly off the top of the frame. As you can now see, Director’s built-in behaviors provide a very powerful way to add interactivity to your Director movies using very little or no Lingo. Although you’ve worked with only a few of Director’s built-in behaviors (so many behaviors are shipped with the application that a whole book could be written on this subject alone), you should have a good idea of how to use behaviors in your movies. It’s worth taking some time on your own to familiarize yourself with the behaviors found in the Library Palette. It’s an investment that could save you untold hours of movie-creation time. We’ve provided more information about Director’s built-in behaviors in Appendix B. This appendix has descriptions of all the behaviors found in the Library Palette.
Summary This chapter taught you how to add interactivity to your Director movies using behaviors that enable you to create sophisticated buttons to navigate your movies, as well as to create animated special effects. Before moving on to the next chapter to learn about the various ways the movies that you created in Director can be output, review some of the important features about behaviors that were discussed in this chapter: ✦ Director ships with a variety of useful behaviors that are contained in the Library Palette. ✦ Behaviors are a collection of event handlers, and each handler contains one or more actions. The Behavior Inspector translates these behaviors, events, and actions into scripts, handlers, and statements.
295
3486-6 ch07.f.qc
296
7/24/00
5:45 PM
Page 296
Part II ✦ Bringing It All Together
✦ Behaviors contain parameters that you can set to control the way a behavior will work, as well as how a behavior is activated. ✦ Messages can be sent to some behaviors that then can activate them. Several behaviors are also capable of sending messages that can be interpreted by Lingo scripts and other behaviors. In Chapter 8, you learn how to fine-tune and then output your movies so that they can be played back without having to use Director.
✦
✦
✦
3486-6 ch08.f.qc
7/24/00
5:45 PM
Page 297
8
C H A P T E R
Fine-Tuning and Outputting Your Movies
F
ine-tuning your Director project can make the difference between a successful project and one that lacks that certain sophistication that distinguishes your movie from others. Adjusting the tempo, adding transitions between scenes, and animating palettes to add polish to your movie are all refinements that help make your Director projects successful. After you’ve added the finishing touches to your movie, you can create a projector, a Shockwave movie, or a Java applet of your Director project. The success of your projector, Shockwave movie, or Java applet starts long before you get to that point, however. A successful project depends upon the planning stages that occur before you even start Director. In this chapter, you learn to apply finishing touches and to prepare your movies for distribution.
Changing the Tempo The human eye can see minute differences in objects and motion. This capability is tempered, however, by perception. What we see is not the same as what we perceive. We mentally filter images to meet our perception of reality, based upon what we’ve learned to expect. The mind fills in gaps between events and skews the perception, to better understand the images it receives. For you to create animation, it’s not necessary to become an expert on perception. It is helpful, though, if you understand that you can make perception work for you when you are creating an animation project.
✦
✦
✦
✦
In This Chapter Changing the tempo Working with transitions Color palettes Building projectors Shocking your movies Using the Publish settings Exporting movies as Java applets
✦
✦
✦
✦
3486-6 ch08.f.qc
298
7/24/00
5:45 PM
Page 298
Part II ✦ Bringing It All Together
The tempo of a Director movie has a great deal to do with perception of motion. Tempo is the frame rate at which an animation sequence moves. The major television technical standards used throughout the world are NTSC (National Television Standards Committee), PAL (Phase Alternation Line), and SECAM (Sequential Couleur Avec Mémoire). NTSC video or broadcast-quality video displays at a rate of 30 fps (frames per second). PAL and SECAM display video at 25 fps. Although it might seem ideal for your Director movies to display at these frame rates, or even at the maximum speed of 999 fps, it’s unrealistic and unnecessary for them to do so. Because of the way we perceive motion, if a Director movie is well designed, it’s doubtful that most people will notice the difference between a movie at 15 fps and one at 60 fps. It takes a computer with substantial resources to render images at 999 fps, or even at 30 fps. High-end computers with fast processors, large amounts of RAM, and fast video systems might be able to render images at this rate. These machines are generally found on the desks of computer professionals, however, and they don’t represent the typical user. The average home computer can reasonably expect to render images at a rate between 10 and 15 fps. Director provides three ways to adjust the frame rate of a movie: through the Control Panel, in the Score window, and using Lingo commands. Regardless of which method you use to adjust the frame rate of your movies, it’s important to understand that the frame rate is a theoretical maximum. For example, if you were to set the frame rate of a movie to 60 fps, it wouldn’t mean your movie would play at that speed. The actual speed of the movie would automatically drop to whatever frame rate the computer is capable of displaying.
Operating the Control Panel The Control Panel operates much like a VCR. Using the Control Panel’s controls, you can view and control the playback of your movie. Choose Window ➪ Control Panel, or press Command+2 (Ctrl+2), to display the Control Panel (see Figure 8-1). Figure 8-1: The Control Panel enables you to view and control the playback of your movie.
Each of the buttons and windows on the Control Panel has a specific function (see Table 8-1) to help you quickly adjust a variety of playback options. Changes you make using the Control Panel are global changes. Any settings you make here affect the entire movie, and can only be overwritten by settings made in the Score window or by using Lingo.
3486-6 ch08.f.qc
7/24/00
5:45 PM
Page 299
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
Table 8-1 Control Panel Functions Control
Description Steps back one frame. Steps forward one frame. Frame counter: Displays the frame in the Score on which the playback head is sitting or through which it is passing currently. Enables you to choose whether to display frame rate as fps or as seconds per frame. Click the corner arrow to make your selection. Frame rate control: Enables you to adjust the frame rate of your movie. Click the up and down arrows to select a frame rate, or type a new frame rate into the box. In this position, the Loop Playback button is toggled to play a movie to the end and then stop. In this position, the Loop Playback button is toggled to play a movie to the end, loop back to the beginning, and play it again. Volume control: Click the arrow in the lower right corner, and choose a volume level. Rewinds your movie to frame 1. Pauses or stops your movie. Plays your movie or the selected range of frames. Displays the current frame rate. This is an instantaneous reading, not an average speed, and may vary widely depending on the content of the Stage at any moment. In this position, the Selected Frames Only button is toggled to play only the selected frames of a movie. In this position, the Selected Frames Only button is toggled to play all frames of a movie.
299
3486-6 ch08.f.qc
300
7/24/00
5:45 PM
Page 300
Part II ✦ Bringing It All Together
Tip
Checking for consistency: A valuable item on the Control Panel is the display of the current frame rate of your movie during playback. While you’re testing a movie, it’s a good idea to keep the Control Panel open and compare the current frame rate with the animation on the screen. Ideally, the frame rate of your movie should be consistent. The animation should move smoothly and at a consistent pace. Watch for fluctuations in the frame rate: Small ones are normal, but a dramatic change could indicate that you need to make an adjustment.
Specifying tempo settings in the Score window Tempo is a design consideration whenever you create a Director movie. You may be aiming for anything from the relaxed pace of a slideshow presentation, to the “warp” speed of a starship racing across the galaxy. By specifying tempo settings in the Score window, you can ✦ Determine the maximum speed for your movie. ✦ Pause your movie for a specified period of time. ✦ Tell Director to wait for user interaction before continuing the movie. ✦ Wait for a cue point in a digital video or sound file. (Chapters 5 and 6 discuss cue points.) The tempo in a Director movie can be changed as often as necessary. It’s a good idea to set the base tempo at the start of your movie, however. This helps you to control the frame rate and reduce fluctuations in the playback of your movie. If you don’t specify a tempo at the beginning, Director plays the movie at the maximum default frame rate of 30 fps. This can cause some significant fluctuations in the actual frame rate, depending on the available resources of the computer used to play the movie and the complexity of the movie. Although you can’t completely eliminate fluctuations in the frame rate, you can minimize their visual impact in your movie by slowing the frame rate of more complex animation sequences.
Compensating for a slow playback When you create an animation sequence in Director, you use a set of keyframes to describe the major movements of the object being animated. Suppose that you are animating the movement of the minute hand on a clock. If you create images that display the minute hand at the 12-, 3-, 6-, and 9-o’clock positions, you can use those images as keyframes for the animation sequence. Tweening between the keyframes simulates the movement of the minute hand. When the tempo of your movie slows, animation sequences can become jerky. It might not be appropriate or possible to increase the frame rate, but you can compensate for jerky animation either by adding more tween steps or by increasing the number of keyframes. In the clock example, increasing the number of tween steps between the keyframes of the animation smoothes the motion of the minute hand. You can also obtain a smoother motion by creating keyframes every 10 minutes instead of every 15 minutes.
3486-6 ch08.f.qc
7/24/00
5:45 PM
Page 301
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
Specifying a frame rate Controlling tempo is always important — and sometimes critical — to your movie. A polka would sound very strange if it were played to a disco beat. Similarly, if you are trying to build a suspenseful moment in your movie, you might want to slow the tempo of your movie over a selected range of frames. As mentioned earlier, to help ensure a consistent tempo throughout your movie you can select a median frame rate at the beginning of your movie. In this first exercise, you do just that. Note
Whenever you specify a tempo setting, that tempo setting remains in effect until you change it.
On the CD-ROM
You can use the marspics.dir Director movie on the companion CD-ROM for the next exercise. The marspics.dir movie is located in the EXERCISE:CH08 (EXERCISE\ CH08) folder.
Setting the Base Tempo 1. Open the marspics.dir or any other movie in Director. 2. Choose Window ➪ Score to display the Score window. 3. Click the Hide/Show Effects Channels button to expand the Score window to display the Effects channels, if necessary. 4. Double-click the Tempo channel in the first frame of your movie (the Tempo channel is the one with a small clock icon). This displays the Frame Properties: Tempo dialog box (see Figure 8-2). You can also choose Modify ➪ Frame ➪ Tempo to get this dialog box.
Figure 8-2: Use the Frame Properties: Tempo dialog box to specify the frame rate for your movie.
5. Select the Tempo radio button, and click the left and right arrows to slow down or speed up the frame rate for your movie. A frame rate of 15 fps is a good median rate.
301
3486-6 ch08.f.qc
302
7/24/00
5:45 PM
Page 302
Part II ✦ Bringing It All Together
6. Click OK to complete the operation and return to Director’s main window. The frame rate stays at 15 fps (or whatever setting you selected) until you change it in a later frame of the Score or through a Lingo command. You can create a dramatic moment in your movie by slowing the frame rate to 2 to 4 fps in the frames where you want the slowdown. Suppose that you want to show a heavy weight being hoisted to the top of a building and then dropping to the ground. By slowing the frame rate during the frames in which the weight is rising to the top of the building, you reinforce the illusion of weight. The drama of the event is further enhanced when the weight falls back to the ground at the normal (or faster) frame rate. Tip
Tempo settings don’t affect the duration of any transitions that you’ve set in the transition channel, and they don’t control the speed at which a sound plays. They control the maximum speed at which the playback head moves from frame to frame.
Pausing a movie Pausing a movie for a specified period is a useful technique if you are creating a presentation, and you want to stop the movie briefly while the user views the contents of the frame. A typical use for a tempo pause is a noninteractive kiosk presentation of a product line. During the three- to five-second pause while each product appears on the screen, the viewer sees an entire product line in a slideshow presentation.
Specifying a Pause in Your Movie 1. Open the marspics.dir or any other movie in Director. 2. In the Score window, double-click the Tempo channel in the frame where you want to insert a pause. 3. In the Frame Properties: Tempo dialog box, select the Wait radio button, and click the left or right arrows to specify the number of seconds you want your movie to pause (see Figure 8-3).
Figure 8-3: The Wait option pauses the move for a specified amount of time.
3486-6 ch08.f.qc
7/24/00
5:45 PM
Page 303
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
4. Click OK to complete the operation and return to Director’s main window. 5. Rewind your movie and click the Play button to test the pause time. Tip
If you want to duplicate your pause setting in another frame, you can quickly copy the tempo cell in the Score window by pressing Command+C (Ctrl+C). Then click the other frame and paste the tempo by pressing Command+V (Ctrl+V).
You might need to test and change the pause time to get the right pause length. What you’re aiming for in this case is to give the user long enough to view the contents of the frame, without making the wait too long before the movie continues. Generally, a pause of three seconds is more than adequate for viewing a graphic. If you are creating a pause for a frame that contains text, you need to specify a longer time. Tip
It’s a good idea to have the frame reviewed by someone who’s unfamiliar with the text. You probably know the text well and, as a result, may be inclined to set an insufficient pause time. Getting another point of view reduces the risk of this happening, and it allows for the variation in the speed at which people read.
Waiting for user intervention Another tempo option is when you want to enable the user to control the pace. You can arrange for user control of a range of frames by using a wait setting in the Frame Properties: Tempo dialog box. A wait setting pauses your movie until the user presses a key or clicks the mouse button. Wait settings are especially useful if you need to display multiple frames with text and want the user to control the pace.
Specifying a Wait Setting 1. Open the marspics.dir or any other movie in Director. 2. Double-click the Tempo channel in the frame where you want to specify a wait setting. 3. In the Frame Properties: Tempo dialog box, select Wait for Mouse Click or Key Press (see Figure 8-4).
Figure 8-4: Selecting the Wait for Mouse Click or Key Press option pauses the movie until the mouse is clicked or a key is pressed.
303
3486-6 ch08.f.qc
304
7/24/00
5:45 PM
Page 304
Part II ✦ Bringing It All Together
4. Click OK to complete the operation and return to Director’s main window. 5. Rewind your movie and click the Play button to test your wait setting. The Wait for Mouse Click or Key Press setting works well for a Director movie that is used as a speaker support in a presentation. The Wait for Mouse Click or Key Press option enables the presenter to discreetly cue the next image by pressing a key or using a special “Air Mouse” (a mouse that doesn’t need to be physically wired to the computer). One drawback to specifying a wait setting in the Score window is that the user can click anywhere on the screen or press any key to continue the movie. If you want the user to click a special button or a specific key, you need to use a behavior or create a Lingo script. CrossReference
For more information about using Lingo scripting to specify a wait setting, see Chapters 7 and 11.
Working with Transitions Very few things can startle the viewer of a movie more than an abrupt change from one scene to the next. You can eliminate this problem by creating a transition between the frames. A transition is a technique by which some sort of passage connects two sequential frames in a movie. Figure 8-5 illustrates a transition; it shows two intermediate images that make up part of the passage between the starting and ending images. The transition in the figure uses a Dissolve effect, to create a blend of the two images as the intermediary Stages in the passage. Like many other elements in your Director movies, transitions are represented both in the Score window and as cast members in the Cast window. There are two methods for creating transitions in Director. The first, choosing Transition in the Effects channel of the Score window, has been with the program since the very beginning. Director 8 introduces a new way of creating transitions: using the new Imaging Lingo feature. These transitions are actually applied to Sprites and are created with Lingo. Director 8 has several built-in sprite transitions that you can find in the Library Palette, where you choose Animation ➪ Sprite Transitions Category. Unlike the transitions applied in the Score window, these new sprite transitions can be applied to individual sprites on the Stage, allowing for some interesting effects that would have been very difficult to achieve in earlier versions of the program. CrossReference
You learn to create your own sprite transitions, as well as many other dazzling effects, by using Director’s new Imaging Lingo in Chapter 27.
Choosing a transition is mostly a matter of aesthetics. You can choose from a variety of transitions, ranging from the subtle to the dramatic.
3486-6 ch08.f.qc
7/24/00
5:45 PM
Page 305
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
Figure 8-5: Transition effects transform one image into another.
Choosing a transition Although a complete transition effect takes only the span of a single frame in a Director movie, you can specify the amount of time for the transition and the smoothness of the transformation. You choose the effect you want to use from the library of transitions included with Director (see Table 8-2). Transitions in Director are grouped by category for ease of selection and use, but each transition is unique in the way it appears. In addition, some transitions — such as Dissolve and those in the Other category — consume more of the computer’s resources than other transitions do. Because they require more memory to render the images to the screen, they can cause performance problems if your entire movie is resource intensive overall, or if your movie is playing on a computer with limited resources.
305
3486-6 ch08.f.qc
306
7/24/00
5:45 PM
Page 306
Part II ✦ Bringing It All Together
Table 8-2 Transition Effects Transition Category
Description and Available Options
Cover
Covers the first image with the image in the subsequent frame by sliding the image over it. You can specify the direction of the transition, the smoothness, the amount of time, and whether the transition applies to the changing area only or to the entire Stage.
Dissolve*
Dissolves from one image to the image of the subsequent frame, with a pixelated transition. You can choose the type of pixelation, the smoothness, the amount of time, and whether the transition applies to the changing area only or to the entire Stage.
Other
Uses one of a miscellaneous collection of transitions, including checkerboard, random columns, random rows, blinds, and zoom effects, to change from one image to the image in the subsequent frame. You can choose the type, the smoothness, the amount of time, and whether the transition applies to the changing area only or to the entire Stage.
Push
Pushes one image from view using the image from the subsequent frame. You can choose the type, the smoothness, the amount of time, and whether the transition applies to the changing area only or to the entire Stage.
Reveal
Strips away one image to reveal the image in the subsequent frame. You can choose the direction, the smoothness, the amount of time, and whether the transition applies to the changing area only or to the entire Stage.
Strips
Removes one image, a strip at a time, to reveal the image in the subsequent frame. You can choose the direction, the smoothness, the amount of time, and whether the transition applies to the changing area only or to the entire Stage.
Wipe
Smoothly wipes one image away to reveal the image in the subsequent frame. You can choose the direction, the smoothness, the amount of time, and whether the transition applies to the changing area only or to the entire Stage.
*Dissolve transitions have a different appearance on the Macintosh and in Windows. If you are creating a crossplatform movie, you should test the transition on both platforms.
In addition to the transitions packaged with Director, a number of third-party vendors offer additional transitions that you can add to Director as Xtras. Xtra transitions are indicated with special icons in the Frame Properties: Transitions dialog box. You
3486-6 ch08.f.qc
7/24/00
5:45 PM
Page 307
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
install Xtra transitions by placing them in the XTRAS folder in the Director application folder (see Chapter 24 for more information). After they are used in the Score’s transition channel, they appear in the Cast window just like any other cast member. Note
Transition Xtras, like other Xtras, must be included with your movie when it’s distributed.
Applying and controlling a transition Transitions — like tempos, palettes, and sounds — have a channel set aside for them in the Score and are placed in the frame where you want the transition to begin. Before you select the frame in which you want to set a transition, it’s important to understand how transitions work. Note
A transition always takes place between the end of the current frame and the beginning of the frame where the transition is set. If you want to add a transition between two scenes, you must place the transition in the first frame of the second scene, not in the last frame of the first scene.
Tip
If you want to use sound during a transition, place the sound in a frame earlier than where the transition is placed. This gives the sound time to decompress and load prior to the rendering of the transition. It makes for a smoother transition.
When you apply a transition, you can set a variety of options that affect the appearance of the transition. Each transition has a particular set of options; only the options available for a specific transition are available in the Frame Properties: Transition dialog box. (The Description column of Table 8-2 includes the options available for each category of transition.) Descriptions of the available controls in the Frame Properties: Transition dialog box are: ✦ Duration: You can specify the amount of time, in seconds, over which you want the transition to render to screen. Shorter transition duration creates more abrupt changes; longer duration creates gradual changes and is more resource intensive. ✦ Smoothness: By adjusting the smoothness, you can control the chunk size of the transition. Chunk size is the number of pixels affected at a time. (Although the Smoothness slider in the Frame Properties: Transition dialog box doesn’t reflect numbers, you are actually choosing a chunk size between 1 pixel and 128 pixels.) You adjust the Smoothness slider to the right to reduce the number of pixels and increase the smoothness of your transition. Adjust the slider to the left to increase the number of pixels in the chunk size. Smoother transitions use up more resources and render more slowly than transitions that use a larger chunk size.
307
3486-6 ch08.f.qc
308
7/24/00
5:45 PM
Page 308
Part II ✦ Bringing It All Together
✦ Affects: Entire Stage: This option changes the entire Stage. Although this is a slower and more resource-intensive transition, it is more attractive when the background is a bitmap image. ✦ Affects: Changing Area Only: This option changes only that portion of the Stage that actually changes. It is a good choice when transitioning to a digital video, or when changing text on the Stage. To increase the speed of a transition, consider enlarging the chunk size of the transition instead of reducing the duration. The number of pixels has more impact on speed than does the number of seconds for the transition.
Tip
In addition to these options, others may be available if you are using an Xtra as a transition. If an Xtra has other options, the Options button is highlighted in the Frame Properties: Transition dialog box. On the CD-ROM
You can use any movie you want for the next exercise, or you can use the marspics.dir movie on the CD-ROM in the EXERCISE:CH08 (EXERCISE\CHO8) folder.
Adding a Transition 1. Open your movie in Director if it’s not already open. 2. Open the Score window by choosing Window ➪ Score. 3. Double-click the Transition channel in the frame in which you want to place a transition. The Frame Properties: Transition dialog box appears (see Figure 8-6).
Figure 8-6: Select and control transitions in the Frame Properties: Transition dialog box.
4. Choose the transition category and transition you want to use. If you click All in the Categories list box, all the available transitions appear in alphabetical order in the Transitions list. 5. Set the Duration, Smoothness, and Affects options.
3486-6 ch08.f.qc
7/24/00
5:45 PM
Page 309
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
6. Click OK to complete the operation and return to Director’s main window. 7. Rewind your movie and click the Play button to test your transition. If you want to change the transition, double-click the transition in the Score window, and make any changes you want. After you set a transition, it appears in the Cast window as well as in the Score. If you want to reuse the transition later in your movie, simply drag the transition from the Cast window to the Transition channel of the frame in which you want the transition to start. If you double-click the transition member in the Cast window, you can modify settings for the transition. This globally changes the settings to every transition in the Score window that is based on the selected cast member. It’s also a good practice to give the transition cast member a more meaningful name to make it easier to identify the transition later on in the movie-creation process.
Tip
Caution
Transitions may not be preserved if you are exporting your file to digital video, and they are ignored when used with movies in a window (MIAWs). To ensure the successful distribution of your movie, test your transitions carefully to make sure they function in a digital video. For more information about transitions and MIAWs, see Chapter 23.
Sprite transitions Until the release of Director 8, users of the program were limited to using the builtin transitions or relied on Xtras to add some variety to their movies. If you wanted to create a transition such as a soft edge-wipe, where one image wipes on top of another as a series of blended images (a technique used often in the days of large multiprojector slide shows), you had to build each transition as a series of composited bitmaps that were then played over several frames in the movie. Not only did it take hours to hand-build these effects, but it greatly increased the movie’s file size, because each transition was made up of several large bitmap images. Then you hoped and prayed the art director didn’t decide to change one of the images in a transition, causing you hours of rework. New Feature
The Sprite Transition behaviors are built using Director’s new Imaging Lingo. You can use these Lingo commands to manipulate individual pixels of bitmap images. This new feature is so comprehensive that all of Chapter 26 is dedicated to it.
Director comes with several behaviors that you can find by choosing Animation ➪ Sprite Transitions Category in the Library palette. Unlike the built-in transitions that you apply in the effects channel, sprite transitions are applied to individual sprites. Each transition contains parameters that control when the transition appears, its duration, and other specific attributes that control the way it acts. Unlike transitions applied in the effects channel, the sprite transition behaviors occur over a span of frames in your movies. One advantage to using sprite transitions is that several transitions can be used simultaneously.
309
3486-6 ch08.f.qc
310
7/24/00
5:45 PM
Page 310
Part II ✦ Bringing It All Together
In the next exercise, you apply the Pixelate Sprite Transition behavior to two sprites in order to create the illusion of two images pixelating from one to another. You also apply the Soft Edge Wipe Sprite Transition behavior to a sprite to give the illusion of a vertical row of lights turning on from the bottom to the top, and then turning off from the top to the bottom. On the CD-ROM
For the following exercise, you need to use the spritetrans.dir movie on the CD-ROM, in the EXERCISE:CH08 (EXERCISE\CHO8) folder. The spritetrans.dir movie is a partially complete movie that already includes the Pixelate and Soft Edge Wipe behaviors, which you can find by choosing Animation ➪ Sprite Transitions Category of the Library Palette.
Using Sprite Transitions 1. Open the spritetrans.dir movie, and then open the Score window. 2. Select the Sprite called Noctis Labyrinthus, click on the Behavior pop-up menu in the Score window, and choose the Pixelate behavior. 3. When the Parameters dialog box appears, set the following parameters, as shown in Figure 8-7. The Transition should be set to appear at the End of Sprite for a duration of 10 frames. The Lowest resolution for both the horizontal and vertical directions should be set to 5, and the Minimum Pixel Dimension should be set to 25.
Figure 8-7: Set the parameters for the Pixelate behavior.
4. Select the Olympus Mons sprite in the Score window and apply the Pixelate behavior. Set the parameters to the same values as the ones set in Step 3 except for the When Transition Appears parameter; set it to Beginning of Sprite. 5. Select the first Light On sprite in channel 10 of the Score window, and choose the Soft Edge Wipe behavior from the Behavior pop-up menu. 6. In the Parameters dialog box that appears, choose Bottom to Top, as shown in Figure 8-8, for the direction. You can leave the rest of the parameters at their default settings. 7. Now select the next Lights On sprite in channel 10 of the Score window, and apply the Soft Edge Wipe behavior. This time, choose top to bottom as the direction and click OK.
3486-6 ch08.f.qc
7/24/00
5:45 PM
Page 311
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
Figure 8-8: Set the direction that the effect will travel to bottom to top.
8. Rewind the movie and play it back. Press the Next button and note how the images appear to pixelate and the vertical bar of lights light up from the bottom to the top and then from the top to the bottom. 9. Try different settings in the parameters, using either the Property Inspector or the Behavior Inspector, and play the movie back to see how they affect the transitions. If you stopped the movie before it finished executing the transitions, you may have noticed several cast members in the Cast window that were not previously there. This is happening because Director is creating a series of new cast members for the transition. It then deletes them from the Cast window after the transition executes. Caution
If you stop the movie before a sprite transition has finished executing, you should delete the cast members that were created. If you don’t, your movie’s file size could be dramatically increased.
You need to be very careful using sprite transition behaviors, because they can be very resource intensive, especially if you are using them on large bitmaps. Used sparingly, they can be a great way to quickly create some fantastic illusions in your movies.
Working with Color Color is one of the most complex and least understood topics in computer graphics. Among the myriad color issues that affect Director, one of the most critical is crossplatform color shifting. The bad news is that every platform, monitor, video adapter, computer, and piece of software interprets color just a little differently from the rest. The result can be like trying to find identical snowflakes in a blizzard. The primary determining factor for all color issues is your audience. By accurately assessing your audience, color issues become a matter of matching color considerations with the viewers’ needs and resources. To begin the process of addressing your specific audience, you must first understand how color and color palettes work.
311
3486-6 ch08.f.qc
312
7/24/00
5:45 PM
Page 312
Part II ✦ Bringing It All Together
Movies for a Director book audience Most of the Director movies created for this book were created using Director’s RGB color space and use quite a few 24- and 32-bit images with alpha channels. Before deciding on this approach, we first considered the audience — multimedia authors, graphic designers, and programmers — who typically use more powerful computers than the average home user. We also knew that the Director movies that we were building for the book were going to be fairly short, because each movie was built to concentrate on a specific feature in Director. These combined factors helped us determine that using high-quality 24- and 32-bit images for the Director movies was the best approach for this audience.
First, a little color theory Computers read data in bits. A bit is the smallest unit of binary data. At its simplest level, a computer interprets color as either 0 (off), or 1 (on), or 1-bit color. Normally, 1-bit color is black and white. In reality, all color is described in 0s and 1s — 2-bit color, for example, creates four possible color choices: black, white, and two shades of gray. Color is created by translating and interpreting each bit, using a color table of possible colors. As the number of bits increases, there is geometric growth in the permutations of colors that can be achieved. Director supports a variety of color depths, as listed in Table 8-3.
Table 8-3 Color Depths and Supported Colors Color Depth
Number of Colors Supported
1-bit
2 colors (black and white)
2-bit
4 colors (usually black, white, and two grays)
4-bit
16 colors
8-bit
256 colors
16-bit
65,535 colors
24-bit
16.7 million colors
32-bit
16.7 million colors with a 256-grayscale alpha channel
3486-6 ch08.f.qc
7/24/00
5:45 PM
Page 313
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
The file size of an image grows in proportion to increases in the color depth and the number of colors. If file size is an issue, reducing the color depth of a bitmap can represent huge savings in storage space, as well as improve the Stage refresh rate of your movie. Large files take longer to import, load, and render to screen. They may also be unnecessarily larger than what is required for optimum output. A 32-bit or 24-bit color image looks wonderful and enables you to take advantage of alpha channels, but if you intend to use it in a Director movie that is to be played back over the Web, you need to consider the price in file size and download time.
RGB color versus Palette Index color Director 8 has two ways of using and displaying colors in a movie: RGB (red, green, blue) color and Palette Index, which is the color space that was used in previous versions of Director. The Palette Index method of displaying colors assigned each color to a specific position in a 256-color palette. RGB color assigns a hexadecimal number to each color that specifies the amounts red, green, and blue needed create the color. When a movie plays in thousands or millions of colors, Director always displays the RGB colors correctly. When a movie plays in 256 colors, Director uses the closest color in the current palette to approximate the original RGB color. At first, RGB color takes a little getting used to (especially if you are an experienced Director user accustomed to the Palette Index color space). The best way to understand RGB color is to show you how it works. Note
For the next exercise, set the color depth of your monitor to 256 colors.
Comparing Index Palette Color and RGB 1. With your monitor set to display 256 colors, create a new movie in Director. 2. Open the Movie Properties dialog box by choosing Modify ➪ Movie ➪ Properties, or press Command+Shift+D (Ctrl+Shift+D). You can also select the Movie Properties by clicking the Movie tab in the Property Inspector. 3. In the Property Inspector, select System – Mac as the default palette, and then click the Palette Index radio button. The movie now uses the Macintosh 256-color System Palette to assign colors to an element. 4. Open the Floating Tool Palette by choosing Window ➪ Tool Palette, or press Command+7 (Ctrl+7), and draw a filled shape on the Stage. 5. Make sure that the shape is still selected, and choose the dark blue color (Index 240) located in the bottom-left corner of the color palette for the shape, as shown in Figure 8-9.
313
3486-6 ch08.f.qc
314
7/24/00
5:45 PM
Page 314
Part II ✦ Bringing It All Together
Index palette color number
Figure 8-9: When using Index Palette color, Director uses an index color number to define the color.
6. Open the Score window (you might need to click the Hide/Show Effects button to display the Effects channels), and double-click the Palette Effects channel in frame 1 to display the Frame Properties: Palette dialog box. Select the System – Win palette from the Palette pop-up menu, and then click OK to return to Director’s main window. Note
The Palette channel is located in channel 2 of the Effects channels.
7. The shape has now changed to a salmon pink color. Because the shape is assigned a color number (color number 240 in this case), it applies to the shape whatever color is currently present in position 240 of the designated palette. 8. Delete the Windows System Palette from the Palette effects channel by clicking it and pressing the Delete key. Select the shape again, and it turns back to its original color. You may need to move the playback head to clear the previous palette from memory. Note
Now you are going to set the movie to RGB color. This time, Director defines the selected color as an RGB color. When you apply a different palette, Director reassigns the RGB color to the Palette Index color that most closely matches the original RGB color. It’s also important to understand that this visual interaction between RGB color and indexed palette color is only relevant when the computer monitor’s color depth is set to 8 bits or lower. At 16 bits or higher, all colors on the Stage are displayed in RGB, regardless of any setting in the Palette Effects channel.
9. Open the Movie Properties dialog box and click the RGB radio button.
3486-6 ch08.f.qc
7/24/00
5:45 PM
Page 315
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
10. Select the shape on the Stage, and then click on the Forecolor swatch in the Tool Palette. This time, the color number is displayed as an RGB color number, as shown in Figure 8-10. 11. Repeat Step 6 to apply the Windows System palette to the Palette Effects channel in frame 1.
RGB hexadecimal color number
Figure 8-10: The color number is now assigned an RGB color number.
12. Note that the shape did not change to a new color. With the shape selected, click the Foreground color swatch on the Tool Palette. The color that has been applied to the shape has been remapped to the color in the Windows System palette that is the nearest match (exact in this case) to the original RGB color (see Figure 8-11).
Remapped color Figure 8-11: Director finds the color in the current palette that is the nearest match to the RGB color values.
315
3486-6 ch08.f.qc
316
7/24/00
5:45 PM
Page 316
Part II ✦ Bringing It All Together
If you are an experienced Director user, you know that RGB color is a vast improvement over the Palette Index color space that was the only option in earlier versions of the program. Using RGB color doesn’t mean that you can now ignore color palettes. Eight-bit bitmaps that are mapped to a specific palette still might have unexpected color shifts if they are mapped to a different palette, even if you are using RGB color. Because RGB colors are mapped to the current palette, Director has to find a color in the current palette that approximates the original RGB color. Quite often, you still have to use images that are indexed to a color palette for most of your movies, if for no other reason than to trim the file size of your movies so that they play back smoothly. Director movies that consist entirely of 24- and 32-bit images will bring most lower end or older computers to their knees.
Assigning images to color palettes Director’s color palettes are far more than virtual boxes of crayons. Frequently, palettes are designed and intended for a specific purpose. The NTSC palette, for example, was designed to provide a standardized palette for the broadcast video industry. Other palettes, such as the system palettes for Macintosh and Windows, are the default palettes for those platforms. Director enables you to assign a specific color palette (called remapping) to your images when you import the images. If your image was created using a custom (adaptive) color palette and you choose not to remap the image, the palette is imported with the image and placed in the Cast window. We don’t recommend the use of custom or adaptive color palettes, however. When Director encounters a custom palette in a frame of your movie, it remaps all of the active Stage elements to that palette. A palette that was perfect for one element in your movie might look positively horrid when applied to other elements. If you want to use a custom palette, be sure to test it thoroughly with the other elements in your movie, as well as on the anticipated target platforms. Tip
Caution
If you do want to use custom palettes in your movies, one of the best ways to create a custom palette is to use a graphics-processing program such as Equilibrium’s Debabelizer. Debabelizer can create what it calls a Super Palette — essentially a single palette that uses the common colors found in a series of images — that can be used for all of the images that are in your movie. Director can display only a single palette in any given frame of your movie. If the elements of your movie use different palettes, you run the risk of conflicts. Your movie may crash if a palette conflict occurs due to images that use multiple palettes in a frame.
3486-6 ch08.f.qc
7/24/00
5:45 PM
Page 317
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
Macintosh or Windows or both? Macintosh and Windows don’t display color in the same way. If you are creating a crossplatform movie, you’ll notice a dramatic difference between the way your movie looks on the Macintosh versus the way it looks in Windows. The main reason for this is that both platforms use a different Gamma (light intensity) to display color. Although you can’t change the way the two platforms differ in color interpretation, you can minimize the impact on your movies. When you are creating a cross-platform movie, it’s a good idea to select one palette and use it for the images on both the Macintosh and Windows versions of your movie. At the risk of starting a platform war, we generally think it’s best to use the Macintosh system palette. The reasoning behind this choice is simple: The Macintosh system palette has a broader range of colors than the Windows palette.
On the CD-ROM
In the next exercise, you import images into Director and remap the colors. We have provided several images that you can use for this exercise. You can find them on the CD-ROM in the EXERCISE:CH08:IMAGES (EXERCISE\CH08\IMAGES) folder.
Note
To be prompted to set a color palette for the images that you are about to import into your movie during the following exercise, your monitor must be set to display 256 colors. The color depth setting of your monitor determines the Stage color depth in Director, which determines whether Director needs to attach an indexed color palette to the image.
Remapping Images When Importing 1. Open a new movie in Director by choosing File ➪ New ➪ Movie. 2. Choose File ➪ Import to display the Import Files dialog box (shown Figure 8-12), or click the Import button on Director’s toolbar. 3. Select the files you want to import, and click the Add button to move them to the file list. You can also double-click a filename to automatically add it to the file list. 4. Click Import. The Image Options dialog box appears (see Figure 8-13). 5. Choose the palette options that you want to use. If you want to remap your image to a specific palette, choose the palette from the drop-down palette list, and then click the Remap to radio button.
317
3486-6 ch08.f.qc
318
7/24/00
5:45 PM
Page 318
Part II ✦ Bringing It All Together
Figure 8-12: Select the files that you want to import.
6. If you want all of the images to be imported using the same options, check the Same Settings for Remaining Images checkbox.
Figure 8-13: Select the Image Options that you want to use.
7. Click OK to import the images and return to Director’s main window. Caution
If you remap 32-bit images that contain alpha channels (transparency) to 8-bit color, the images no longer contain an alpha channel when they are imported into Director.
Remapping images on import enables you to quickly change the palette for bitmap images before they are placed in the Cast window. You can also change the palette of existing bitmap cast members, using the Transform Bitmap command. With this command, you can choose to remap the image or specify dithering. If you choose Dither, Director attempts to match the existing colors of the image as closely as possible to the existing palette by interspersing multiple colors from the new
3486-6 ch08.f.qc
7/24/00
5:45 PM
Page 319
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
palette that closely match the original single color. In addition to changing the palette an image uses, the Transform Bitmap command enables you to change the color depth and size of the image. Caution
The Transform Bitmap command can’t be undone. If you are unhappy with the results, you need to reimport the image into the cast.
Transforming Bitmaps 1. In Director, open a movie that contains images you want to remap, if it’s not already open. 2. Choose Window ➪ Cast to display the Cast window. 3. In the Cast window, select the bitmap cast members you want to transform. 4. Choose Modify ➪ Transform Bitmap to display the Transform Bitmap dialog box (see Figure 8-14).
Figure 8-14: Changing the color depth, size, and palette for your image
5. Select a palette from the Palette list. 6. Click either the Remap Colors radio button or the Dither radio button. 7. To resize your image, either enter a new value in the Scale percentage box or type new values into the Width and Height boxes. If you check Maintain Proportions, you need to enter only one value; Director calculates the other (width or height) values to maintain the aspect ratio of the image. 8. Click OK to transform the bitmap. A warning box appears that tells you the operation is irreversible, and asks you to confirm your command. Click Transform to continue or Cancel to quit. The Transform Bitmap command is useful for quickly modifying your bitmap images. If you’re reducing the size of an image by a small percentage (25 percent or less), Transform Bitmap is an effective choice. If you need to make larger changes or enlarge an image, resize the image in an external editor, such as Adobe Photoshop.
319
3486-6 ch08.f.qc
320
7/24/00
5:46 PM
Page 320
Part II ✦ Bringing It All Together
Color palettes and the Web When playing in a Web browser, Shockwave movies don’t control the color palette of a user’s system as projectors do. Shockwave remaps the colors in Director movies to the most similar colors in the active palette of the user’s system. Generally, the active palette is that of the user’s browser. Therefore, you can get the best color results from your Shockwave movies if you map all the images in your movie to the Web 216 palette that is built into Director.
Modifying palettes In addition to the standard palettes that come with Director, you can duplicate existing palettes and then modify them to create your own custom palettes. This is useful when a movie’s cast members use only a few out of a broad range of colors. For example, if the cast members are using only 24 solid colors out of the 256-color palette, you could create a custom palette, remap all of the cast members to the new palette, thereby reducing the rendering time and file size of the entire movie. Caution
This technique doesn’t work as well for images containing gradient fills.
Note
You can’t modify or edit any of Director’s standard palettes.
Creating a Modified Palette 1. Choose Window ➪ Color Palettes, or press Command+Option+7 (Ctrl+Alt+7). This action displays the Color Palettes window, with the active platform palette in the palette window. In Figure 8-15, the Windows System palette is chosen (in a Macintosh window). 2. To modify the colors in the palette, select a color square and use the up- and down-arrow buttons at the bottom of the window to change the color’s HSB (Hue, Saturation, Brightness). 3. The Create Palette dialog box appears, enabling you to rename the palette (see Figure 8-16). Enter a new name — it’s a good idea to enter a name associated with the cast members in your movie. This makes it easier to remember the palette’s use later. 4. Click OK to return to the Color Palettes window. The new palette appears, with the name displayed in the list box at the top of the window (see Figure 8-17). 5. You can repeat Step 2 and modify any other colors in the custom palette.
3486-6 ch08.f.qc
7/24/00
5:46 PM
Page 321
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
Current Palette Figure 8-15: The Color Palettes window enables you to modify color palettes.
Adjust Hue
System color picker
Adjust saturation Adjust brightness
Figure 8-16: Enter a name for your new color palette in the Create Palette dialog box.
Figure 8-17: The modified color palette’s name appears in the list box at the top of the Color Palettes window.
6. After modifying a palette, be sure to save your movie to preserve the changes you’ve made to the palette.
321
3486-6 ch08.f.qc
322
7/24/00
5:46 PM
Page 322
Part II ✦ Bringing It All Together
You’ve now created the basis for a modified palette. You can edit the palette as needed in a variety of ways, using the tools and command buttons in the Color Palettes window. Table 8-4 describes these tools and their functions in editing your color palettes. Caution
You can map cast members to your modified palette as you would to one of Director’s standard palettes. Be cautious when remapping cast members to a palette, however, because these changes are irreversible.
Table 8-4 Tools and Functions in the Color Palettes Window Icon
Description
Function
Reserve Selected Colors
Reserves selected colors and prevents their use. Useful for restricting effects, such as cycling colors to a selected group of colors.
Select Reserved Colors
Selects colors you have reserved in the active color palette.
Select Used Colors
Scans the cast members to select just those colors used by the cast.
Invert Selection
Reverses the selection. For example, if the selected colors in the palette are those used by your cast, this option reverses that selection and selects the colors that were not used by the cast.
Sort
Enables you to sort colors by Hue, Saturation, or Brightness. Select a range of colors and then click the Sort button to choose the desired parameter from the dialog box that appears.
Reverse Sequence
Reverses the order of the selected colors in the Color Palettes window.
Cycle
Cycles selected colors one square to the left. Creates an effect similar to color cycling. Note: This option is only available for 256-color palettes.
3486-6 ch08.f.qc
7/24/00
5:46 PM
Page 323
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
Icon
Description
Function
Blend
Creates a blend of a selected range of colors. Useful for creating a range of blended colors for use as a gradient. Select a range of colors and then click the Blend button to create the blended range.
Arrow Tool
Selects colors and options in the Color Palettes window. Click a color to select it. Drag to select a range of colors.
Hand Tool
Enables you to drag colors and rearrange their order in the Color Palettes window.
Eyedropper
Enables you to replace a color in the Color Palettes window by selecting the color and then dragging the Eyedropper to the desired color on the Stage.
Hue, Saturation, and Brightness
Adjusts the Hue, Saturation, and Brightness of a color.
Color Picker
Enables you to select colors from the Color dialog box.
Creating effects with palettes You can create effects with palettes much as you can with other sprites in your movie. For instance, using settings in the Frame Properties: Palette dialog box, you can fade a palette to black or white. Fading to black or white is useful for adding closure scenes to your movies. Instead of abruptly ending the movie, the scene gradually fades away. You can also create color-cycling effects. Color cycling works well for a variety of uses, such as making a cartoon character blush by degrees from pink to red, or for creating a headline banner that cycles through several colors. Note
Palette-fading and color-cycling effects are available only if you are using an 8-bit, 256-color palette. You can’t create these effects with higher color depths.
323
3486-6 ch08.f.qc
324
7/24/00
5:46 PM
Page 324
Part II ✦ Bringing It All Together
On the CD-ROM
Note
Try both of these effects in the next two exercises. Use the mplane.dir movie in both sets of steps. The mplane.dir movie is on the CD-ROM in the EXERCISE:CH08 (EXERCISE\CH08) folder.
For the next two exercises, set your monitor to display 256 colors.
Creating a Fade to Black or White 1. Open the mplane.dir movie in Director. 2. To add a palette fade at the end of the movie (from frame 40 to frame 60), click once in the Palettes channel in frame 40. Hold down the Shift key and click in frame 60; this selects all frames from 40 through 60. 3. Choose Modify ➪ Frame ➪ Palette to display the Frame Properties: Palette dialog box (see Figure 8-18).
Figure 8-18: The Frame Properties: Palette dialog box enables you to set up various palette effects.
4. Select the Palette Transition radio button and the Span Selected Frames radio button. 5. In the Options area at the bottom of the dialog box, choose either Fade to Black or Fade to White. 6. Click OK to complete the operation and return to Director’s main window. 7. Save the movie as mplane1.dir. 8. Be sure the Loop Playback button on the Control panel is turned off, so that the movie doesn’t recycle. 9. Rewind the movie, click the Play button, and watch the palette fade.
3486-6 ch08.f.qc
7/24/00
5:46 PM
Page 325
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
Although not specifically a transition like those available through the Frame Properties: Transition dialog box, you can use palette fades to create color transitions both at the end of your movie and between scenes in your movie. Now let’s work with color cycling.
Cycling Colors in Your Movie Caution
Remember that color cycling, like the palette fade, works only when using an 8-bit, 256-color palette. Furthermore, if your monitor is set to use a high-color (16-bit) or true-color palette (24-bit or 32-bit), these effects do not appear.
1. Make sure the mplane1.dir movie is open in Director. 2. Double-click on the System – Mac palette in frames 40 to 60 of the Palette channel to display the Frame Properties: Palette dialog box. 3. Select the Color Cycling radio button and the Span Selected Frames radio button. 4. Leave Options set to Loop. 5. On the color palette in the dialog box, drag across a range of colors to select the colors you want for the cycle. Click OK to complete the operation and close the dialog box (see Figure 8-19).
Figure 8-19: Select the range of colors that you want to cycle through.
6. Save the movie as mplane2.dir. 7. Be sure the Loop Playback button on the Control panel is turned off, so that the movie doesn’t recycle. 8. Rewind the movie, click the Play button, and watch the palette cycle.
325
3486-6 ch08.f.qc
326
7/24/00
5:46 PM
Page 326
Part II ✦ Bringing It All Together
Color cycling can create effects from muted to spectacular, depending on the colors you select to cycle. To quickly highlight and call attention to text in your movie, consider selecting two contrasting colors for the text, and cycle between them with Color Cycling enabled in the Frame Properties: Palette dialog box.
Tip
Building Projectors After you’ve created a movie, you can play it in Director or share it with others who have Director installed on their computers. None of the available media players support Director movies, however. If you want to distribute your Director movie for others to use, you need to create a projector of your movie. A projector is a stand-alone application containing the Director movie packaged with all of the elements required for playing it on a given platform. Director doesn’t need to be installed for the projector to play. Projectors are platform-specific. A projector created on a Macintosh won’t run in Windows. A projector created in Windows 98/NT won’t run on a Macintosh. If you’re creating a movie for cross-platform distribution, you need to create the projector on the platform for which it’s designed to play. This means it’s possible to create two projectors: one for each platform. Projectors are distinct files that bundle your movie, sounds, Xtras, filters, and the run-time engine into one file. Unlike the original Director movies from which they are created, projectors are executable files, which means that the movie starts when you double-click the filename. Caution
Windows users: Projector files have an .EXE extension. The Macintosh OS doesn’t routinely put extensions on files, so you should be careful not to overwrite your Director movie by giving your projector the same name as your Director movie.
Projector movies are, by their nature, larger than their original Director movies. The reason for the difference in size has to do with the number and types of files included in a projector, plus the executable code that plays the movie. It’s not uncommon for a projector to be two to three times the size of its associated Director movie. Note
In Director 8, you can only create projectors with movies that are created with version 8 of Director. If you are including Director movies from a previous version of the program, you need to update them by using the Update Movies Xtra explained later in this section.
3486-6 ch08.f.qc
7/24/00
5:46 PM
Page 327
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
Creating a projector Before creating a projector, it’s a good idea to play your movie one last time to check all the elements of your movie. Although your original Director movie isn’t altered when you create a projector, you cannot edit the projector itself. When you are creating a projector, make sure that any Xtras you used to create the movie are included with the projector. If you are missing an Xtra, your movies may not play properly. You can add Xtras the same way you add movies when creating a projector (covered later in this section), or you can add Xtras with the Movie Xtras dialog box. Follow these steps to add Xtras with the Xtras Movie dialog box: 1. Open the Movie Xtras dialog box by choosing Modify ➪ Movie ➪ Xtras. Most of the commonly needed Xtras are already included, as shown in Figure 8-20. 2. If you need to add an Xtra, click the Add button and choose the Xtras you want to include.
Figure 8-20: The Movie Xtras dialog box enables you to select the Xtras to be included in your projector.
3. Remove any Xtras that you don’t want by selecting them and then clicking the Remove button. This reduces the size of the projector. 4. Select an Xtra and then click the Info button to get information on the Xtras function. Note
When you click the Info button for most of the Xtras, Director launches your Web browser and gets the information from the Macromedia Web site.
5. If you click Download if Needed, the viewer of your movie is prompted to download the Xtra from the Web if it is not on the viewer’s system.
327
3486-6 ch08.f.qc
328
7/24/00
5:46 PM
Page 328
Part II ✦ Bringing It All Together
Another way to include Xtras with your movies is to create an XTRAS folder that contains the Xtras that you are using for your movie(s), creating it in the same folder as the projector. This approach is actually preferred by most professionals. This approach enables you to see which Xtras are included with the movie without having to open the movie in Director. Make sure you do not include the Xtras in the projector if you are using this technique, because the movie crashes if there are two sets of Xtras included.
Tip
When you create a projector, Director asks you to add the movies you want associated with the projector. You can choose to add one or more movies to the list. In addition, you can add cast libraries, Xtras, and other files needed in association with the projector. You can even create a projector that runs several movies in a sequence. Caution
Be careful when adding several movies and files to the projector list. Movies are played back in the same order in which they’re listed. This point is especially critical for projectors that contain movies that play in a separate window (called MIAWs), in which the host movie calls other movies to play. If the order is incorrect, your MIAW could finish playing before its host movie starts, causing the projector to fail. To prevent this from happening, make sure that any host movie that is calling an MIAW is higher in the list than the MIAW.
You can specify a variety of options when you create a projector. These options, accessed through the Options button in the Create Projector dialog box, determine the appearance of the projector and the way the projector is stored for distribution. Table 8-5 lists and describes the various options for creating a projector.
Table 8-5 Options for Creating a Projector Option
Description
Playback: Play Every Movie
When you’re creating a projector that contains multiple movies, choosing this option ensures that every movie plays in turn; otherwise, only the first movie plays. Note: For a projector of an MIAW, do not select this option. If you do, the child movie is left on the screen when the projector has finished playing.
Playback: Animate in Background
Plays your projector regardless of what other applications are active. If you don’t select this option, when you start another application the projector pauses until you click it to restart it.
Options: Full Screen
Blanks out the screen of all other applications and plays the projector full screen. If the Stage does not fill the entire screen, the area outside the Stage is filled with the starting Stage color.
3486-6 ch08.f.qc
7/24/00
5:46 PM
Page 329
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
Option
Description
Options: Show Title Bar
You can select this option only if your projector is playing in a window; the projector displays a title bar with the projector’s name. This also enables the window to be moved.
Stage Size: Use Movie Settings
Causes each movie in the projector to be displayed at its creation size (when the projector contains multiple movies).
Stage Size: Match First Movie
Causes successive movies to be resized to match the Stage size of the first movie in the play order. Be careful when you use this option, because it can cause distortion in your movies. This option is most effective when the Stage size for all movies is the same.
Center
Centers the movie on the screen.
Reset Monitor to Match Movie’s Color Depth (Macintosh only)
Resets the monitor’s color depth to match the color depth setting used for the Director movie.
Media: Compress (Shockwave Format)
Compresses projectors, using the Shockwave compression scheme. This keeps the file size as small as possible, but it increases the load time because the file has to decompress before playing. Shockwave compression can be used for any projector to reduce its size.
Player: Standard
Creates the largest projector but loads the movies the fastest, because the player file does not have to be decompressed.
Player: Compressed
Compresses the player code included with the projector. This substantially reduces the size of the projector. The projector will need more time to launch, because it has to decompress the player file.
Player: Shockwave
Eliminates the need for a player file, because it uses the Shockwave player. If Shockwave is not installed on a user’s system, it automatically prompts the user to download the player from the Web.
Memory: Use System Temporary Memory (Macintosh only)
Enables a movie to use available system memory when the projector’s own memory partition is full.
329
3486-6 ch08.f.qc
330
7/24/00
5:46 PM
Page 330
Part II ✦ Bringing It All Together
On the CD-ROM
For the next exercise, you can use the engine.dir movie found on the CD-ROM in the EXERCISE:CH08 (EXERCISE\CH08) folder.
Creating a Projector 1. Open engine.dir in Director. Choose File ➪ Save and Compact. This operation removes redundant and fragmented data in your movie so that it performs better when it’s played. 2. Choose File ➪ Create Projector to display the Create Projector dialog box (see Figure 8-21).
Figure 8-21: Use the Create Projector dialog box to specify the movies and options that you want to include in a projector.
3. Navigate to and select engine.dir, and then click the Add button to add it to the playback order list at the right of the dialog box. Note
You can also add Xtras by using this method. Locate the folder that contains the Xtras, and add them just as you would a movie.
4. If you are making a projector for more than one movie, you must verify the order in which the movies appear in the Playback Order list box. Click the Move Up or Move Down buttons as needed to reposition selected movies in the list. Remember that movies must be listed in the order in which you want them to play. 5. Click the Options button to display the Projector Options dialog box (see Figure 8-22).
3486-6 ch08.f.qc
7/24/00
5:46 PM
Page 331
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
Figure 8-22: The Projector Options dialog box enables you to select the options you want to use with your projector.
6. Select the options (see Table 8-5) you want to use with your projector, and then click OK to return to the Create Projector dialog box. 7. Click Create to display the Save Projector As dialog box. 8. Enter a filename (such as engine) and a location for your projector, and then click OK to continue. Depending on the size and complexity of your movie, it may take Director a couple minutes to create your projector. After the projector is completed, minimize or close Director and then double-click your projector file to test the projector.
Creating a more efficient projector It’s not really necessary to include in the projector all the movies that will be used in your multimedia application. A projector can call other Director movies that are external to the projector. This means you could build a small Director movie that contains only a Lingo script that calls the first Director movie that you are using in your multimedia application. If you take this approach, it’s a good idea to have the projector file at the same directory level as the rest of the Director movies that will be called from the projector. You might want to protect the Director movies that are external to the projector so that users will not be able to open the movies in Director.
331
3486-6 ch08.f.qc
332
7/24/00
5:46 PM
Page 332
Part II ✦ Bringing It All Together
Distributing a projector Projectors tend to be large — even a small projector file is usually larger than what fits on a single floppy disk. Although you can use a compression utility such as StuffIt or PKZip to compress and store your projector on multiple disks, we don’t recommend it. A projector movie contains many component parts, but it is considered a single file, and it’s not a good policy to span a single file across multiple disks. If a single archive disk fails, then your projector becomes worthless. You can use a variety of storage media to distribute your projectors. Only two of them are practical, however. You can either distribute the projector via the Internet as a download, or you can create a CD-ROM containing the projector. If you choose to distribute your projector over the Internet, be aware that the user has to download the file and play it offline. The only way the user can view your movies online is if you create a Shockwave movie (see the “Shocking Your Movies” section below). A CD-ROM capable of holding almost 650MB of data may seem like overkill if you have a 3MB projector, but the potential audience — given the number of people who own CD-ROM drives — might warrant using that medium for distribution. CD-ROM recorders and media are becoming inexpensive and are reasonably easy to operate.
Using the Update Movies Xtra Because you can create projectors with Director 8 movies only, you need to update movies created with previous versions of Director. As well as enabling you to update movies, the Update Movies Xtra performs these functions: ✦ Compresses your movies for faster downloading over the Web. ✦ Removes fragmented data in your movies. The Save and Compact command performs this same operation. ✦ Protects movies to prevent users from opening them. ✦ Batch processes the preceding operations for multiple movies and cast files. To update movies with the Update Movies Xtra, follow these steps: 1. Open the Update Movies Xtra by choosing Xtras ➪ Update Movies. This brings up the Update Movies dialog box, as shown in Figure 8-23. 2. Click one of the three radio buttons next to the Action option — Update, Protect, or Convert to Shockwave Movie(s) — to select the particular operation that you want to perform. • Choose the Update option to update movies that were created with earlier versions of Director.
3486-6 ch08.f.qc
7/24/00
5:46 PM
Page 333
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
• Choose the Protect option to create Director movies that cannot be opened again in Director. • Choose the Convert to Shockwave Movie(s) option to convert your Director movies to Shockwave movies. This option works the same way as the Save as Shockwave command, explained later in this chapter. 3. Select an option that tells Director what to do with the original files. You can choose Back Up into Folder or Delete. Caution
If you select Delete, Director deletes the source movies you have chosen. This is a quick and easy way to lose many hours of work if you don’t have the original movies backed up to another location.
Figure 8-23: The Update Movies dialog box enables you to specify the Update operation that you want to perform on your Director movies.
4. If you choose the Back Up Into Folder option (we strongly suggest that you always use this option), click the Browse button and select the folder to which you want Director to back up the original movies. Caution
You should always back up the movies into a different folder than the one where the original movies are currently located. When Director updates the original movies, it overwrites the original files with the same name so that the links and references to other movies remain intact. This is especially important if you are creating Protected or Shockwave movies, because you can’t edit them after the movies are updated.
5. Click the OK button when you have chosen the options you want. When the Choose Files to Update dialog box appears, as shown in Figure 8-24, select the movies and cast libraries on which you want to perform the operations. • Click the Add button to add a single file to the list. • Click the Add All button to add all the files in the current folder to the list.
333
3486-6 ch08.f.qc
334
7/24/00
5:46 PM
Page 334
Part II ✦ Bringing It All Together
• To remove a file from the list, select the file and then click the Remove button. • Click the “Add All” Includes Folders check box before choosing the Add All option if you want to include files that are contained inside folders that are located in the Directory that you have chosen. Figure 8-24: Choose the movies and cast libraries that you want to update.
6. When you have added all the files on which you want to perform the operation, click the Update button. Director begins processing the files. It may take several minutes to update the files if you are processing a large number of files. Director saves the new versions of the movies with the same names and locations as the original movies. This ensures that all the links and references that were in your original movies function correctly. If you chose the Backup Into Folder option, Director puts the original movies into the backup folder that you selected.
Shocking Your Movies Shockwave — one of the fastest growing technological advances to hit the Internet — helps Web authors add animation and interactivity to Web pages. Shockwave is now a system-level component (similar to QuickTime) that enables you to play movies over the Web and from the desktop. Shockwave can also play your projectors if you chose that option when creating them. Shockwave 8 is now much easier to install, giving the user more feedback during the installation process. It also automatically updates components as needed. Xtras can now be downloaded from a secure server if they are not installed on the user’s system.
3486-6 ch08.f.qc
7/24/00
5:46 PM
Page 335
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
Director has also included several capabilities that enable you to create multiuser Shockwave applications, such as games and chat rooms. These new features combine to make Shockwave one of the most powerful technologies on the Web.
Designing for the Web Before you create a Shockwave movie, it’s a good idea to check with your ISP (Internet service provider) to be sure that they support the Shockwave file format. The server at your ISP must be able to send information to a user’s Web browser, telling the browser how to deal with files. If your provider doesn’t support the Director or Shockwave MIME-type, users won’t be able to view your movie online. (For more information about Shockwave and the Internet, see Chapter 24.) Caution
The Internet and World Wide Web don’t support multiple windows. For that reason, you can’t use MIAWs in a Web page.
A Shockwave movie can be presented using either Netscape Navigator 3.0 and later or Internet Explorer 3.0 and later (4.01 or later for the Macintosh). When you embed a Shockwave movie in a Web page, you need to create code specific to one or both of these browsers. Director 8 uses the new Publish command to generate the HTML code needed to display your Shockwave movies in a Web page. The Publish command replaces the features found in the Aftershock utility that was shipped with previous versions of the program. If you use Macromedia’s Flash 4, you are probably familiar with the Publish command, because it is nearly identical to the one in Director 8. One big problem with Director movies has always been controlling the speed at which your movie will play across a wide range of computer platforms. This is especially a problem when playing Shockwave movies over the Web, because you compound the problem by adding the user’s connection speed to the Internet into the equation. You can control some of these issues by setting the Playback properties for the movie that lock the frame rate to assure that the movie will play the same across a wide variety of conditions. Director has several built-in behaviors contained in the Library Palette that you can use to control the way a Shockwave movie is downloaded without having to know how to use Lingo programming. For example, you can have the movie loop on an animation in the first frame until the rest of the movie is available. You can also have buttons that are inactive until the frames of the movie to which the buttons navigate are downloaded. There is also a behavior that creates a progress bar that informs the user of the status of the download. You can learn more about these behaviors in Appendix B.
335
3486-6 ch08.f.qc
336
7/24/00
5:46 PM
Page 336
Part II ✦ Bringing It All Together
Compressing individual cast members When creating movies that will be played back over the Web as Shockwave applications, you need to pay special attention to the file size of your movies. Although high-speed connections, such as cable modems and digital subscriber lines (DSLs), are starting to become more widespread, a majority of home Internet users are still using 28.8K through 56K modem connections to view Web content. Most users will ignore even the most compelling Shockwave application if they have to wait more than a few minutes to download it. Director now has a menu item called Optimize in Fireworks that opens a cast member in Fireworks 2.0 or greater, enabling you to use Fireworks to choose and preview the best compression setting for an individual graphic. This feature requires that you have Fireworks 2.0 or greater installed on your system.
New Feature
Graphics usually take up most of the file size in your movies. In previous versions of Director, the only compression option was the default compression used when you created the Shockwave movie. Director 8 has introduced several new methods for compressing the bitmap elements that are contained in the movie. You can set different JPEG compression settings for each individual graphic element, as well as assign global compression for all of the graphics by using Director’s built-in compression scheme. If you have Macromedia’s Fireworks 2.0 or greater installed on your system, you can use the Optimize in Fireworks option, which uses Fireworks’ superior optimizing and preview compression utilities. On the CD-ROM
There are several images found in the EXERCISE:CH08:IMAGES (EXERCISE\CH08\ IMAGES) folder that you can import into a movie to compress.
Optimizing a Bitmap Cast Member 1. In the Cast window, select a bitmap cast member, and then click the Properties button to display the Property Inspector. Click the Bitmap tab if it is not the active window. 2. The Bitmap tab shown in Figure 8-25 has a series of settings, located in the Compression list box, that control the compression for the chosen cast member. Choose from the following options: • Movie Setting: This setting uses the compression setting chosen from the Publish Settings dialog box, which you find by choosing File ➪ Publish Settings. This feature is covered in the “Creating a Shockwave movie” section. • Standard: Uses Director’s standard compression setting. • JPEG: Uses JPEG compression, which you can set via the slider located below the Compression setting list box. The compression settings range from 0 (lowest quality, highest amount of compression) to 100 (highest quality, least amount of compression).
3486-6 ch08.f.qc
7/24/00
5:46 PM
Page 337
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
Figure 8-25: Control the compression setting for a cast member in the Bitmap tab of the Property Inspector.
If you have Fireworks installed on your computer, you can click the Optimize in Fireworks button to open the graphic in Fireworks’ export menu, enabling you to choose and view several different compression schemes simultaneously. On the CD-ROM
The next exercise requires that you have Fireworks 2.0 or greater installed on your system. If you don’t have Fireworks, you can find a Fireworks 3.0 demo on the companion CD-ROM in the GOODIES:MACROMEDIA:FIREWORKS (GOODIES\ MACROMEDIA\FIREWORKS) folder.
Optimizing a Bitmap by Using Fireworks 1. In the Cast window, select a bitmap cast member and then click the Properties button to display the Property Inspector. Make sure that the Bitmap tab is active by clicking on it if needed. 2. Click the Optimize in Fireworks button. The Mix Editing In Progress dialog box appears. 3. Another prompt appears, asking if you want to edit an existing Fireworks graphic (see Figure 8-26). If the cast member you are using was originally created in Fireworks and is linked to the movie, click Yes. If you want to edit the cast member that is currently in your movie, click No. 4. The graphic is displayed in the Fireworks Export window, as shown in Figure 8-27. Choose a preset compression setting from the pop-up menu located above the image preview. You can then refine that setting by using the Options tab on the left. If you want to view several settings in order to compare them, click one of the Preview Window buttons located below the image preview.
337
3486-6 ch08.f.qc
338
7/24/00
5:46 PM
Page 338
Part II ✦ Bringing It All Together
Figure 8-26: A dialog box appears, prompting you to choose a graphic created in Fireworks or to use the existing graphic in your movie.
Image settings window
Preview window
File format
Saved preset
Save preset
View tools Export to size wizard Export wizard Transparency Settings
Preview window settings Update and return to Director Frame advance and reverse controls
Figure 8-27: Fireworks enables you to view several different compression settings applied to the same graphic in order to choose the best setting.
3486-6 ch08.f.qc
7/24/00
5:46 PM
Page 339
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
5. When you are satisfied with the compression setting, click the Update button. Fireworks closes and returns you to Director. Click the Done button in the Mix Editing In Progress dialog box to finish the operation. When you choose the Optimize in Fireworks button, you have access to the Fireworks Export window only. The editing and creation tools are not available. If you set Fireworks as the default editor for bitmaps, you can double-click a cast member and edit by using the entire toolset available in the program.
The Publish settings To display your Shockwave movie in a Web browser, you need to build an HTML page that contains at the very minimum the EMBED tags needed to recognize and load the DCR file that is created when you publish a Director movie as a Shockwave file. In previous versions of Director, you had to accomplish this by creating the HTML code by hand or with an application specifically used to create HTML documents. Director 6.5 introduced a utility called Aftershock, which enabled you to create HTML code that handled your Shockwave movies in a variety of circumstances. Director 8 now has the functionality that used to come with Aftershock built right into the program. Choose File ➪ Publish Settings and use those settings to quickly and easily create very complex HTML documents that set a variety of parameters to control the way a Shockwave movie plays in a Web page. You can set options that automatically download the plug-in or ActiveX control if they are not already installed on a user’s system, display a JPEG image of your movie, or play your movies as Java applets. The Publish Settings menu also enables you to set a global compression setting that is applied to all of the bitmap graphics in your movies that have their compression property set to use the movie’s compression settings. Access the Publish Settings menu by choosing File ➪ Publish Settings. Depending on the HTML template you have selected, up to six tabs are visible in the menu, as shown in Figure 8-28. You can modify individual settings applied to an HTML template by adjusting the properties found in the tabs that are enabled for each template. Figure 8-28: Use the Publish Settings menu to control how your Shockwave movies will be displayed in a Web browser.
339
3486-6 ch08.f.qc
340
7/24/00
5:46 PM
Page 340
Part II ✦ Bringing It All Together
You use the six tabs listed in the Publish Settings menu — Formats, General, Shockwave, Compression, Shockwave Save, and Image — to control various aspects that determine the way the Shockwave movie plays in a browser window.
The Formats tab Use the Formats tab to: ✦ Select an HTML template that the Shockwave movie will use, or create a Shockwave movie without an HTML document. Table 8-6 explains each of the HTML templates. ✦ View a short description of the currently selected HTML template. ✦ Set the path to where the Shockwave, HTML, and Image files are to be saved. If you want to assign a new path, either type in the path name or click the Browse button and select the folder in which you want to save the files. ✦ Determine whether the file will automatically launch in a Web browser when it is output.
Table 8-6 HTML Templates for Embedding Shockwave Movies Template Name
Description
No HTML Template
Creates a Shockwave movie with no associated HTML template.
Shockwave Default
Creates an HTML document that contains the basic OBJECT and EMBED tags needed to display the Shockwave movie in a browser.
Detect Shockwave
Creates an HTML document that uses JavaScript and VBScript to detect the Shockwave plug-in or ActiveX control. If the correct version is not present on the user’s system, the viewer is advised to update the viewer’s Shockwave installation.
Fill Browser Window
Generates HTML code that enables a Shockwave movie to expand in size to entirely fill a browser window.
Java
Creates HTML code that enables the movie to be loaded into a Web browser as a Java applet. Note: Many Director features are not supported in Java.
Loader Game
Displays a Breakout-style game with progress bar while the Shockwave movie is preloading.
Progress Bar With Image
Enables you to assign a background JPEG image that is displayed behind a progress bar while the movie is loading.
3486-6 ch08.f.qc
7/24/00
5:46 PM
Page 341
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
Template Name
Description
Shockwave With Image
Creates an HTML document that automatically substitutes a JPEG image if Shockwave is not installed on a user’s system.
Simple Progress Bar
Displays the Macromedia logo over a progress bar while the movie is loading.
Center Shockwave
Creates an HTML document that puts the Shockwave file in a table in order to center the movie on the Web page.
The General tab You use the General tab, shown in Figure 8-29, to set the dimensions of the Shockwave movie and to set the background color that will be used in the HTML page. Choose from the following Dimensions options: ✦ Match Movie: This setting matches the dimensions that are used for the Director movie that is being output as a Shockwave file. ✦ Pixels: When you choose this setting, the Shockwave movie’s dimensions are set to the exact pixel dimensions typed into the Width and Height fields. ✦ Percentage of Browser Window: This setting displays the Shockwave movie, using the percentages entered into the Width and Height fields. This setting has no effect if No Stretching is selected in the Stretch Style Option of the Shockwave tab. Caution
If you are using the Percentage of Browser Window option, the graphic elements used in your movie should largely be comprised of vector shapes that can scale up and down. Bitmap graphics could appear distorted if you use this option.
Figure 8-29: Use the General settings to set the dimensions of the movie and the background color used for the HTML page that displays the Shockwave movie.
341
3486-6 ch08.f.qc
342
7/24/00
5:46 PM
Page 342
Part II ✦ Bringing It All Together
Choose the color used for the page background from the color swatch, or type a hexadecimal color number into the text field.
The Shockwave tab You use the Shockwave tab, shown in Figure 8-30, to set the properties of your Shockwave movie, which determine how the movie will play back. You can control the way the movie will load. You set the Stretch style (how it fills the browser window) of the movie. You can choose the background color of the window in which the movie is displayed. In addition, you can select an option that enables the movie to use external JavaScripts. Figure 8-30: The Shockwave tab enables you to set properties that determine how the Shockwave movie loads and plays in a Web browser.
Set the following properties in the Playback controls section: ✦ Volume Control: This option enables users to adjust the volume of the audio. ✦ Transport Control: Add a transport controller that enables users to Rewind, Stop, Start, and step through the movie. ✦ Zooming: You must select this option if you want the movie to be stretchable. ✦ Save Local: Enable this option if you want users to able to save the movie to their computer’s hard drive so that they can play it back using Macromedia’s local Shockwave player, which is called Shockmachine. The Loading properties set the elements shown in the movie while it is downloading: ✦ Display Progress Bar: Setting this option displays a progress bar that indicates how much of the movie has downloaded. ✦ Display Logo: This option displays the Macromedia logo along with the progress bar while the movie is downloading. The Stretch Style settings control the way the movie will be displayed in the Web Browser: ✦ No Stretching: The movie plays at its original size.
3486-6 ch08.f.qc
7/24/00
5:46 PM
Page 343
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
✦ Preserve Proportions: This option displays the movie at its original aspect ratio, no matter what size it scales to fill the user’s browser window. The movie originates both horizontally and vertically from the settings used in the Stretch Positions pop-up menu. Note: Zooming must be enabled. ✦ Stretch to Fill: The movie stretches to fill the height and width variables set in the HTML document used to embed the movie. If the height and width are not proportional to the original movie, sprites on the Stage could appear distorted. Note: Zooming must be enabled. ✦ Expand Stage Size: This option sets the movie’s Stage size to the height and width variables set in the HTML document. The sprites remain at their original size. The movie originates both horizontally and vertically from the settings used in the Stretch Positions pop-up menu. Note: Zooming must be enabled. You use the Stretch Position settings to determine alignment of the movie when one of the Stretch features is enabled. Choose from Left, Center, or Right for the Horizontal alignment, and from Top, Center, or Bottom for the vertical alignment. You use the Background color setting to set a background color that is displayed in the window that contains the actual Shockwave movie (not the HTML page that contains the movie) while the movie is downloading. Select a color by clicking on the color swatch and choosing a color from the menu or by typing in a hexadecimal color number. If your movie is using JavaScript, you need to enable the JavaScript property. This creates a flag for the Netscape browser to start Java when the movie loads.
The Compression tab The Compression tab, shown in Figure 8-31, is where you set the default compression for the bitmap and audio elements in a movie. Bitmaps that use custom compression set with Property Inspector are not affected by these settings. Figure 8-31: The Compression tab sets the default compression used for the movie.
343
3486-6 ch08.f.qc
344
7/24/00
5:46 PM
Page 344
Part II ✦ Bringing It All Together
Choose from the following settings for Image Compression: ✦ Standard: This setting uses the compression techniques that were used by Director versions 4 through 7. ✦ JPEG: This setting uses JPEG compression for all of the images used in the movie. Adjust the slider to set the amount of compression. The 0 setting yields the highest amount of compression but the lowest image quality, and 100 results in the least amount of compression but the highest image quality. You can apply Shockwave’s audio compression to all of the audio elements in your movie by enabling Compression and choosing the level of compression from the kBits/second pop-up menu. The higher numbers result in less compression and yield better audio quality. You can convert all stereo audio to mono (this cuts most audio file sizes in half). If the cast members contain comment text entered in the Comments field of the Property Inspector, you can have them included in the Shockwave movie by enabling the Comments property. You need to use Lingo to access the comments included in the movie.
The Shockwave Save tab The information in the Shockwave Save tab, shown in Figure 8-32, is used when you are creating a movie that will be downloaded and used locally by Shockmachine. Some of the properties require an understanding of Lingo as well as Java and XML. Following is an explanation of each field in the Shockwave Save tab: ✦ Context Menu: Enable this property if you want to display the standard Shockwave contextual menu when the user Option+clicks (Right+clicks) on the movie while it is playing. ✦ Suggested Category: Type in a Shockmachine category, such as Games, into this field. ✦ Shockwave Title: Enter a title, which then appears in the Shockmachine interface. ✦ Send URL: This setting enables you to specify and override the URL that Shockmachine detects. If nothing is entered, Shockmachine detects the URL of the HTML page that contains the Shockwave movie. ✦ Icon File: Use this field to specify the path and filename of a BMP icon image used by Shockmachine. ✦ Package File: Enter the URL of a text file that is used to provide a list of the URLs that contain all the support files that need to be downloaded with the movie to make it fully enabled on the user’s local machine. ✦ Total Title Size: Enter the number, in bytes, of all the files included with your movie.
3486-6 ch08.f.qc
7/24/00
5:46 PM
Page 345
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
Figure 8-32: The Shockwave Save tab is where you enter information needed to enable your movies to be played locally on a user’s computer using Shockmachine.
The Image tab The Image tab, shown in Figure 8-33, is only available if you have chosen the Image HTML template in the Formats tab. The Image tab is where you select an image from a frame of your movie to be displayed for users who don’t have Shockwave or ActiveX control on their systems. You type in the frame number of your movie that contains the image that you want to use and set the JPEG compression using the slider. You can also determine whether the image will be downloaded all at once or progressively. Figure 8-33: Use the Image tab to select an image that will be displayed for users who don’t have Shockwave or the ActiveX control installed on their computers.
Setting the playback options Two more things to consider when creating a Shockwave movie are how the movie will stream, and what the ideal frame rate will be for your movie. Shockwave movies can stream, meaning that the movie does not have to be completely downloaded before it starts playing. When creating a Director movie that will be output as Shockwave, you can design it so that some of content can download first and then become active while the rest of the content is
345
3486-6 ch08.f.qc
346
7/24/00
5:46 PM
Page 346
Part II ✦ Bringing It All Together
still downloading. Director has several built-in behaviors that control the way elements of a Shockwave movie will be downloaded. See Appendix B for a detailed description of these behaviors. You can also control the way the movie streams by using the Playback Properties window (choose Modify ➪ Movie ➪ Playback). The Playback Properties window also enables you to lock the frame rate of the movie to the current tempo set in the Tempo channel of the score. You can also have the movie pause when the window that contains the movie is inactive. This feature is useful if you have hyperlinks in your movie that will open another browser window. The movie will be paused while the user has the second window open, and then resume where they left off when they make the window that contains the Shockwave movie active again.
Setting the Movie Playback Properties 1. Open a movie in Director, and choose Modify ➪ Movie ➪ Playback. The Movie Playback Properties window appears, as shown in Figure 8-34. 2. Under the General heading, select the Lock Frame Durations check box to lock the movie’s frame rate to the Tempo settings. Select the Pause When Window Inactive check box to have the movie pause if it is in an inactive window. 3. To have the movie begin playing while it is downloading, select the Play While Downloading Movie option. In the field located below the Play While Downloading Movie option, type in the number of frames in your movie that you want to download before the movie is to begin playing. 4. If you want placeholders to appear in place of any elements that have not been downloaded yet, click the Show Placeholders option.
Figure 8-34: The Movie Playback Properties control the frame rate and streaming aspects of the Shockwave movie.
Publish your movie as a Shockwave movie Now that you have a good understanding of the various ways that you set up your movies to play back in a Web browser, you still need to publish the movie as a Shockwave movie. When you save a movie as a Shockwave movie, it creates
3486-6 ch08.f.qc
7/24/00
5:46 PM
Page 347
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
a DCR file that contains the actual code and media elements contained in the movie. An HTML file is also generated, using the HTML template specified in the Publish Settings window that contains the OBJECT and EMBED tags and JavaScript that calls the DCR file. You can preview your movies in a Web browser at any time during the moviecreation process by choosing File ➪ Preview in Browser. This launches the movie using the default Web Browser chosen in File ➪ Preferences ➪ Network.
Tip
It’s a good idea to preview your movie in a Browser window to test all of its functionality before you create your Shockwave movie. Caution
If your movie contains linked media, it may not be displayed properly. This is due to a security limitation that prevents Web browsers from reading files stored on a local computer’s hard drive. If you have linked media, you need to put the movie and all of its linked content in a folder called dswmedia. You can include subfolders in the dswmedia folder as long as the relative path names have not changed. This entire folder — with the finished movie(s) and linked content — will need to be uploaded to a Web server when you are ready to put the project online.
Publishing a Movie 1. Open a movie in Director and set the desired Publish settings, using the Publish Settings menu as described in the Publish Settings section of this chapter. You may want to adjust the Movie Playback settings described earlier. 2. Save and compact the movie by choosing File ➪ Save and Compact. 3. Choose File ➪ Publish. This process may take a minute or two, especially if the movie contains linked casts. 4. If you chose the View in Browser option in the Publish Settings menu, the default Web browser will launch and display the Shockwave movie. Unless you chose a different path in the Publish Settings menu, the Shockwave DCR and HTML files are saved in the same folder where you saved the Director movie from which you made them. After you have created the final Shockwave movie and HTML file, it’s a good idea to test in both Internet Explorer and Netscape. Your movie may work properly in Explorer, yet function differently in Netscape. Further, you should check the movie in Netscape and Internet Explorer on both the Macintosh and Windows operating systems.
347
3486-6 ch08.f.qc
348
7/24/00
5:46 PM
Page 348
Part II ✦ Bringing It All Together
Director’s Shockmachine With Director 7, Macromedia made Shockwave a system-level component similar to QuickTime, which enabled Shockwave movies to be viewed from the user’s hard drive as well as in a Web page. Shockmachine, shown in Figure 8-35, is a Macromediadeveloped application that loosely resembles a game console for playing Shockwave movies. Shockmachine enables users to download and play Shockwave content from their local hard drive. Shockwave was developed primarily to complement their Shockwave.com Web site (http://www.shockwave.com), which contains scores of Shockwave games and animated movies. Originally, Director charged a small fee for Shockmachine; recently, however, the company has made it available free of charge.
Figure 8-35: Shockmachine enables Shockwave movies to be downloaded and played locally from a person’s hard drive.
Creating Java Applets of Your Movies Version 6.5 of Director introduced the capability to create Java files of your movies. Java applets are platform independent and don’t require a special plug-in or ActiveX control. Because Java is an environment separate from Director, there are many features in Director that are not supported by Java. If you are going to create Director movies that are to become Java Applets, you need to be careful about using Lingo code and other features, such as ink effects and transitions, that are not supported in the Java format. Fortunately, Director warns you of any components in the movie that are not supported by Java when you begin to create an applet.
3486-6 ch08.f.qc
7/24/00
5:46 PM
Page 349
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
Creating Java applets of your Director movies can be a somewhat convoluted process. Unfortunately, there is very little documentation about creating Java applets in Director’s online help and manuals, although you can download a PDF document from the Director Developers center on the Macromedia Web site at http://www. macromedia.com. Even though it’s possible to create Java applets without having any Lingo or Java scripting knowledge, you might want to read Chapter 25 to learn some of Java’s basics. There is a profusion of good Java books on the market, as well as many good Web sites dedicated to the subject. Tip
When creating a Director movie that is to become a Java applet, it’s a good idea to use Director’s built-in behaviors — located on the Library Palette in the Java Behaviors category — for the Lingo scripts that are to be used in the movie. These behaviors are Java-safe and save a lot of debugging time when you output the move as a Java applet. You can find more information about the Java behaviors in Appendix B.
You can expect a Java applet to take an additional 10K to 50K of disk space, as compared to a DCR (Shockwave) file. The maximum size for a Director player for Java should not be larger than 100K. Also, keep in mind that Java applets run much more slowly than Shockwave (DCR) movies.
The best uses for Java applets Unless you are both an experienced Lingo and Java programmer, you might want to avoid creating Java applets of complex movies that contain a significant amount of interactivity and animation. However, there are several good uses for Java applets that you can quickly and easily create using Director that require very little or no Lingo and Java programming experience. Use Java applets to: ✦ Create animated Web banner ads. ✦ Build a scrolling ticker tape applet that can contain information that updates while the movie plays. ✦ Create simple animations that require no user interaction.
Saving as Java When you use the Save as Java command, Director creates two files that contain a media file and a class file — these files contain instructions for the player and the movie’s internal data. The media file contains all of the movie’s internal cast members and Score information, such as tempo settings, scripts, and ink effects. The media file has the same name as the Director movie and uses a .DJR extension. The class file contains the movie’s Lingo scripts and the startup code needed to run the movie. If you choose the Create as Source Java option, the class file has a .JAVA extension. If you choose the Compiled Java option, the class file has a .CLASS extension. The illustration in Figure 8-36 shows the process that Director goes through to create a Java applet.
349
3486-6 ch08.f.qc
350
7/24/00
5:46 PM
Page 350
Part II ✦ Bringing It All Together
Source Director movie
Director Export for Java Xtra
Player Files (.class)
movieName.class
Linked Cast Members
movieName.djr
Applet Figure 8-36: The process that Director uses to create Java files.
Director also creates several other files when it creates a Java applet of your movie. The files that have a .CLASS extension are the player files that are needed to run the movie. Director also generates an HTML file that contains the EMBED information and is used to check the movie in a Web browser. Make sure that all of these files are contained in a single directory. Creating a Java applet is a very simple process. When you save your movie as a Java applet, Director generates all the files needed to run the Java applet, including an HTML document that contains the EMBED tag for the applet. The difficult part of creating Java applets is stripping out or substituting features in your movie that are not supported by Java. Follow these steps to output your movie as a Java applet: 1. In Director, open a movie that you want to export. Choose the Java HTML template from the Publish Settings menu. Choose File ➪ Save as Java; the Save as Java dialog box appears, as shown in Figure 8-37. Make sure that any external media that are included in the movie are located in the same folder as the source Director movie.
3486-6 ch08.f.qc
7/24/00
5:46 PM
Page 351
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
Figure 8-37: The Save as Java dialog box
2. There are two options that you can choose to create a Java Applet: Source Java and Compiled Java. The default setting is Compiled Java. This option converts the Java source files into class files, an intermediate, platform-independent language that can be read by the Java engine contained in a Web browser, and converts the code into a language that the computer understands. The Source Java option creates text files that are essentially the same as a programmer would write. If you are going to add your own Java code to the movie, use the Source Java Option. Note
The Minimize Player Size option removes the code for the features that are not used in your movie. It takes longer to compile the Java applet if you choose this option. The Embed Linked Media option includes linked media in the applet and enables all the elements of the Java applet to be contained in a single download.
3. Click the Options button; the Options dialog box appears (see Figure 8-38), enabling you to set the JPEG quality of the images that are used for the Java applet; determine whether the movie loops or pauses at the end; and set specific optimizations. Click OK after you have chosen the options that you want. Figure 8-38: Set options that determine the image quality, playback options, and optimization settings for the Java applet.
351
3486-6 ch08.f.qc
352
7/24/00
5:46 PM
Page 352
Part II ✦ Bringing It All Together
Caution
The optimization options can alter the way the Java applet plays back. Most of the settings determine how lists contained in the movie are used in the Java applet. To learn more about these settings and how they can affect a Java Applet, see Chapter 24.
4. Click the Check button to have Director examine the movie and report any errors that occur in the Java applet (see Figure 8-39). Director displays a list of features contained in the movie that are not supported in Java. Click an item in the list, and then click the View button. Director then displays the sprite, script, or effect that’s not supported. Click the Next button to display the next error in the movie. Click the Done button after you have viewed all of the errors. When creating a Director movie that is to become a Java applet, select the Save as Java option and click the Check button as often as possible to find any features contained in your movie that are not supported in Java.
Tip
Figure 8-39: When you click the Check button, Director examines the movie and then displays any features that are not supported in Java.
5. Click the Save button, and Director compiles the movie and creates the files needed for the Java applet. 6. Click the Run button to view the movie in a Web browser. Caution
You must have enough RAM to run Director and your Web browser simultaneously to take advantage of this operation.
You should package the entire set of files as ZIP, CAB, and JAR files to ensure that they play back on different Web browsers. These file formats are compression schemes that are supported by the different browsers. The CAB file is for Internet Explorer, the JAR file is for Netscape 4+, and the ZIP file is for Netscape 3. You can get free utilities from the Web that compress the files into these formats.
3486-6 ch08.f.qc
7/24/00
5:46 PM
Page 353
Chapter 8 ✦ Fine-Tuning and Outputting Your Movies
If you are creating Director movies that primarily will be used as Java applets, you should learn more about the Java programming language. Although many features of a Director movie are supported in Java, plenty of them aren’t. Knowing how to use Java enables you to substitute pure Java code for the features that Director doesn’t support.
Summary In Director, you can use a number of techniques to add the finishing touches to a project before outputting movies that can be viewed in multiple media: ✦ Change the tempo of your movie to help create smooth animation sequences and add dramatic pacing to your movie. ✦ The Control Panel provides a quick method of controlling the playback and frame rate of your movie. ✦ You can pause a movie to wait for the user to click the mouse or press a key. ✦ Add transitions to the movie to help it move smoothly from one scene to the next. ✦ You can remap graphic elements in your movie to existing or custom palettes. ✦ By adding fades and using color cycling, you can create transitional effects with color palettes. ✦ Projectors enable others who don’t own Director to see your movies. ✦ You can create Shockwave movies to distribute your projects on the Web. ✦ Create Java applets of your movies that don’t require the Shockwave plug-in or ActiveX control to be viewed in a Web browser. ✦ Use the Publish settings to create robust HTML documents to play your movies over the Web. Now it’s time to move on and use the knowledge you have gained so far to build a fully functional multimedia application.
✦
✦
✦
353
3486-6 ch08.f.qc
7/24/00
5:46 PM
Page 354
3486-6 ch09.f.qc
7/24/00
5:46 PM
Page 355
9
C H A P T E R
Creating an Interactive Presentation
C
reating a Director movie requires advance planning to ensure its success; planning ahead also reduces the amount of debugging and editing required throughout the development of the movie. This chapter examines the anatomy of a movie, from a planning point of view, by creating an interactive presentation. This chapter also shows you other ways to integrate the techniques and operations covered in previous chapters.
Designing an Interface A powerful aspect of Director is its capability to create interactive multimedia applications that give users control over how they want to view the content. Of course, this makes creating your movies much more difficult because you have to consider these aspects: ✦ How to break down the content into parts that make sense to the user ✦ How the user navigates through the content ✦ How to avoid leading the user to a “dead end” from which the user can’t return easily ✦ The number of levels the user will have to navigate The complexity of these issues compounds as the amount of content included in your application grows larger. Here’s a good rule of thumb for creating navigation: The user should not have to click more than three buttons to get to any of the content. If you have a large amount of content to include in your movie, keeping the navigation to three levels can be a daunting task.
✦
✦
✦
✦
In This Chapter Designing an interface Using Guides Using QuickTime VR Using HTML in Director Importing a PowerPoint presentation Launching external movies
✦
✦
✦
✦
3486-6 ch09.f.qc
356
7/24/00
5:46 PM
Page 356
Part II ✦ Bringing It All Together
Another big challenge when designing an interface is that it’s almost impossible to predict how each individual will navigate through the content. Unless you are creating a computer-based learning application or a speaker-support presentation, you should generally avoid presenting your content in a linear fashion. On the other hand, if you have a lot of content, you need to be careful not to create a navigation scheme that looks like the cockpit of a 747 airliner, which simply overwhelms most users. A good interface takes a great deal of thought. If you are creating a multimedia application that contains a large amount of content, you should consider building a rough prototype of the interface and have it tested by your target users. You’ll be surprised at some of the ways users want to navigate through the content.
Creating a flow chart One of the best techniques for creating the navigation scheme for your movie is to create an outline. Most word processors have the capability to create outlines. The advantage to using an outline is that you can easily move subjects to different levels as well as insert new ideas as they occur to you. After you have created an outline, you should create a flow chart of the navigation structure. This gives you an easy way to visualize the navigation structure that the movie is to use. Figure 9-1 shows the flow chart that was created for the movie that you build in this chapter.
Explore Mars Navigation Flowchart Opening Animation
Virtual Tour
QTVR 1
QTVR 2
Mars Lander Game (external movie)
FactFinder
QTVR 3
Mars Facts Screen 1
Web Links
Mars Facts Screen 2 Mars Facts Screen 3 Figure 9-1: A flow chart provides a picture of the navigation that you’ll use for your movie.
3486-6 ch09.f.qc
7/24/00
5:46 PM
Page 357
Chapter 9 ✦ Creating an Interactive Presentation
There are three levels of content in this movie. The first level is an animated opener that introduces users to the content and entices them to venture further into the movie. From the opening animation, the user can choose between three different sections: a QuickTime VR tour of Mars, a section that contains facts and figures about Mars, and a game called the Lander Pilot. The VR Tour and FactFinder screens each contain an introduction to the section and navigation elements that enable users to select any third level of content that most interests them. Because the Lander Pilot game does not have any third level content, there is no need to build an intermediate screen. Even though the navigation for this movie is fairly simple, it’s still a good practice to use a flow chart to visualize the navigation. This is especially important if more than one person is building the application, because it gives everyone a common reference and avoids a lot of confusion later in the project. It also provides an excellent starting point for the next step in the process of building an interactive application — designing the look and feel of the user interface.
Designing the navigation After you have created a navigation flow chart, the next step is to determine how the user navigates to and from each section. The best way to begin is to determine how the navigation structure works. In this situation, we broke down the navigation into two main areas that serve very distinct functions: ✦ The first level of navigation enables the user to jump to the top level of any section from almost any point in the movie. This is accomplished by creating a static area at the top of the screen that’s visible during most of the movie. This area contains buttons that go to the top level of each section — the Virtual Tour, FactFinder, and Mars Lander Game. This area also contains a text header that labels each section. ✦ There are two second-level areas — the Virtual Tour and FactFinder — with options from which the user can choose that lead to third-level content. The navigation elements that enable the user to view the content contained in these sections are located on the left side of the screen. This approach enables a user to navigate through the content in a very nonlinear fashion, and it also ensures that a user is never more than three mouse clicks away from any other third level of content. We intentionally added two elements that present navigation problems into this project. The Mars Lander game is actually a separate Director movie. Although it would be possible to re-create the Navigation bar at the top of the original movie for the Lander Pilot game, it would be very distracting when a user is playing the game. To solve this problem, users drop back into the original movie when they quit the game, to the same place where they chose to play the game.
357
3486-6 ch09.f.qc
358
7/24/00
5:46 PM
Page 358
Part II ✦ Bringing It All Together
The other navigation problem is in the Mars Facts level located below the main level of the FactFinder. The Mars Facts section is actually a PowerPoint presentation that contains three different screens. Because there are only three screens at this level, it shouldn’t be too disturbing to the user to navigate sequentially through the section. After the user navigates to the Mars Facts section, you introduce Next and Previous buttons that enable the user to move forward and back through the three screens.
Laying Out the Project Now that the navigation issues are solved, it’s time to begin laying out the interface. You assign areas on the screen real estate that are dedicated to particular functions; for instance, you should assign a part of the screen as the place where the Quit button is located. Having a main navigation element move to a different position throughout a movie is not very user friendly. When you need to use a secondary level of navigation specific to a section, you still want to present that navigation in a consistent manner. In the VR Tour and FactFinder sections you build later in this chapter, there is a secondary level of navigation buttons that lead to the third level of content. Even though the buttons in each of these main levels leads to a different third-level section, you place them in the same area of the screen and give them an identical look and feel. The only aspect that is different for each of these buttons is the label that informs the user where the button leads when the user clicks it.
Carving up the screen Before you begin creating the movie in Director, you need to carve up the screen, defining the areas of the screen that hold your navigation elements, content, and any special elements in your movie. This can be done with the old No. 2 pencil as a rough sketch (that’s usually the best place to begin), but Adobe Photoshop is an excellent tool for this process. Chances are that you need to create at least some artwork to be used in your movie with an external graphics editor, so you might as well take advantage of Photoshop’s rulers and guides to precisely align the elements designed for the layout of the elements. This approach offers several advantages — the biggest one is that you can actually create the art elements for your movie at the same time as you lay out the project. At the very least, you probably want to design several layouts in a graphics editor that shows what the screens in your movie look like at each level of navigation, as shown in Figure 9-2. If you are creating a large project that involves several team members, you might want to lay out every screen in your graphics editor before it is built in Director. This gives everyone working on the project an exact picture of every screen layout to be produced for the movie.
3486-6 ch09.f.qc
7/24/00
5:46 PM
Page 359
Chapter 9 ✦ Creating an Interactive Presentation
Figure 9-2: Using guides in Photoshop enables you to easily carve out the space needed for the individual elements to appear in your movie.
Creating graphics factories A Director movie can contain hundreds and, oftentimes, thousands of individual graphic elements, especially if you are using multistate buttons and animation composed of many small pieces. Keeping track of all of these elements and ensuring that they are consistent with each other can be one of the most difficult aspects of creating a Director movie. Using a graphics editor, such as Adobe Photoshop, that enables you to store graphic elements in layers, makes your life much easier. You can break down your art elements into different categories, or factories — such as headers, buttons, labels — and then you can create a file for each category that contains all the individual elements needed for each category. Use this technique to create a file that contains each button state as a separate layer. Not only does this help you manage the files, but it also enables you to preview each state of the button (before you bring it into Director) by turning on and off the different layers that contain the state of the button.
359
3486-6 ch09.f.qc
360
7/24/00
5:46 PM
Page 360
Part II ✦ Bringing It All Together
Tip
After you’ve created your layered Photoshop documents, you can copy and paste each layer into Director; or better yet, you can use the PhotoCaster Xtra by Media Lab to automatically import each layer of your Photoshop document into Director as individual cast members.
Getting organized in Director The movie you build in this chapter is actually quite small compared to most Director projects, but there are still over 100 individual elements that make up the final version of the movie. Piling all of these elements into a single Cast window makes creating a movie a very frustrating experience, and you can end up wasting your valuable time trying to find cast members instead of concentrating on the creative aspects of the movie. A better approach is to create several Cast windows that contain specific types of elements that will be used in the movie. There are no hard and fast rules as to how you should structure the Cast windows — whatever method works best for you is fine. The movie you build in this chapter contains the Internal and three additional Cast windows. A description of the Cast windows and a brief explanation of their content is as follows: ✦ Internal: Use the Internal Cast window to store the text, bitmap, and video cast members that are the actual content elements for the VR Tour and FactFinder sections. ✦ Interface: The Interface Cast window contains all the graphic and text cast members that make up the navigation for the movie, including all the buttons, Section headers, button labels, button sound, and navigation bar graphics. ✦ Behaviors: This window contains (obviously) the behaviors and Lingo scripts in the movie. ✦ PowerPoint: This Cast window contains all the cast members that are created when you import the PowerPoint presentation into Director. Tip
Build a directory structure on your hard drive that mirrors the Cast windows used for your movie to store all of the elements to import into Director. This not only keeps you more organized, but it also speeds up importing the elements into Director. You need to be careful about linked media such as digital video — it’s easy for Director to lose track of a linked file that is not located at the same level as the movie. You should keep files that will be externally linked at the same directory level as the Director movie. Alternatively, you can group all the digital video files together in a subfolder within the same directory.
You might be wondering why we didn’t put the PowerPoint cast members in the internal Cast window with the rest of the content elements. When you import a PowerPoint file, Director creates individual cast members for each line of text, transition, and graphic element of the original PowerPoint presentation. This can be quite a few cast members. Having the PowerPoint cast members contained
3486-6 ch09.f.qc
7/24/00
5:46 PM
Page 361
Chapter 9 ✦ Creating an Interactive Presentation
in a separate Cast window makes it easier to identify the elements used for the PowerPoint presentation. You learn how to import a PowerPoint presentation and incorporate it into an existing movie later in this chapter. Now that you have a basic understanding of navigation structure and content, it’s time to begin creating the movie in Director.
Dissecting the movie If you are experienced in Director, you probably already have begun forming a mental picture of the structure of the movie you are about to create. At this point, open the final version of the movie and spend a little time getting familiar with the components before beginning to build the movie. On the CD-ROM
The explore_complete.dir movie is a completed version of the movie you build. You can find this movie on the CD-ROM in the folder EXERCISE:CH09 (EXERCISE\ CH09). You also want to make sure that QuickTime 4.1 is installed on your computer. If you don’t have QuickTime installed, use the QuickTime 4.1 installer on the CD-ROM in the GOODIES:QUICKTIME (GOODIES\QUICKTIME) folder.
Looking Over the Project 1. Open the explore_complete.dir movie in Director. Rewind the movie and play it. 2. Spend a few minutes navigating through all the sections of the movie to familiarize yourself with the way the navigation functions. 3. When you feel comfortable with the way the movie works, click the Quit button. The movie stops playing, but Director is still open. 4. Open the Score window. The first 10 sprite channels are colored orange (see Figure 9-3). These sprite channels contain the main navigation elements for the movie. The sprites that begin in sprite channel 12 are secondary navigation elements. Sprites starting in channel 24 are content elements that are specific to each section of the movie. Tip
When creating movies in Director, carve up the Score window by dedicating certain channels for specific types of elements. For example, sprite channels 1 through 10 could be used for the navigation elements, and content could always begin in channel 15. This makes it easier to locate an individual element later in the project, because you have a general idea of the channel in which it is located. This is a very useful technique to employ if several authors are working on the same project.
361
3486-6 ch09.f.qc
362
7/24/00
5:46 PM
Page 362
Part II ✦ Bringing It All Together
Primary Navigation Elements
Secondary Navigation Elements
Content Elements Figure 9-3: The Score is divided into different sections that contain specific types of elements used for the movie.
Creating the Opening Animation When building an interactive presentation, an important component is the introduction. This is the first thing users see when they launch the application, so it needs to set the scene for the movie as well as entice users to explore the content. The opening animation for the movie you build in this chapter is very simple. It serves as a way to introduce the navigation bar that’s used throughout the rest of the movie. Because the main goal of this movie is to give you an overall approach to building an interactive application, we didn’t want you to spend a large amount of time creating a complex animation for the opening sequence. You will probably want to create a more complex and compelling opening animation sequence when you are creating your own interactive presentations.
3486-6 ch09.f.qc
7/24/00
5:46 PM
Page 363
Chapter 9 ✦ Creating an Interactive Presentation
If your movie has a story line, you could create an animated opener that sets the scene for the story line that runs through the movie. Many games take this approach, using a very sophisticated opening animation that leads you to the point in the story where the game begins. If you create a large opening animation that takes several minutes to view, make sure that you give the user the opportunity to jump to the main content at any time. You might think the animation you created is very compelling, but you can never predict how much patience the user has. You might end up frustrating your users if they are forced to sit through the opening animation every time they run your movie. You can always create a button that plays the opening animation from any point in the movie. Caution
Avoid using digital video for an opening animation, because a certain percentage of your users might not have the capability to play digital video. If you do want to use digital video, you should create an alternate version of the opener that can automatically play in place of the video if the user doesn’t have video capability.
In the following exercise, you begin building the opening animation sequence for the movie. Most of the steps are a review of some of the things that you learned about animating sprites in Chapter 3. The big difference is that you’re going to set guides in Director to make it easier to align two of the sprites on the Stage. On the CD-ROM
For this exercise, use the explore1.dir Director movie. You can find this movie on the CD-ROM in the EXERCISE:CH09 (EXERCISE\CH09) folder. Save this movie to a folder on your hard drive so that you can add to it in other exercises in this chapter.
Building the Opening Animation 1. Open the explore1.dir movie, and then open the Cast window. 2. Click the Select Cast button in the Cast window and choose the Interface Elements cast. Select the cast member named navbar and drag it into sprite channel 1 of the Score window so that it begins in frame 5. Drag the title cast member into the score so that it’s directly below the navbar sprite in channel 2, as shown in Figure 9-4. Tip
If you hold down the Option (Ctrl) key while you click the Select Cast button, the new Cast window opens over the existing one.
3. Open the Property Inspector, shown in Figure 9-5, and click the Guides and Grids tab to display the Guides and Grid window. Make sure that the Visible and Snap to Guides check boxes are enabled.
363
3486-6 ch09.f.qc
364
7/24/00
5:46 PM
Page 364
Part II ✦ Bringing It All Together
Figure 9-4: Drag the navbar and title cast members into the Score as shown.
Vertical guide
Tooltip displaying pixel location Horizontal guide Figure 9-5: Use guides to accurately place sprites on the Stage.
3486-6 ch09.f.qc
7/24/00
5:47 PM
Page 365
Chapter 9 ✦ Creating an Interactive Presentation
4. Place a horizontal guide onto the Stage by dragging from the Horizontal Guide onto the Stage. Note that the pixel location of the guide dynamically updates in the Property Inspector window. When the Guide is 20 pixels from the top of the Stage, let go of it. Place a second horizontal guide so that is 44 pixels from the top of the Stage. 5. Repeat Step 4 to place a vertical guide so that it is 50 pixels from the left edge of the Stage by dragging from the Vertical Guide onto the Stage. Place another vertical guide 80 pixels from the left edge of the Stage. 6. On the Stage, position the Title sprite so that the upper left corner of the sprite snaps to the outermost horizontal and vertical guides. Then position the navbar sprite so that the upper-left corner of the sprite aligns with the innermost horizontal and vertical guides. 7. Drag the tail of the navbar sprite so that the sprite ends in frame 30. Repeat this step with the title sprite. 8. Open the Cast window and make sure that the Internal cast is visible. Drag the mountains cast member into channel 25 of the Score so that it begins in frame 2. Then drag the tail of the mountain sprite so that it extends to frame 79. Note
You need to have the mountain sprite visible on the Stage until the playback head reaches this frame (79) in order to add another element to the opening animation in a later exercise.
9. On the Stage, drag the mountain sprite so that the bottom of the sprite is even with the bottom of the Stage. At this point, your scene looks similar to the one shown in Figure 9-6. Press Command+L (Ctrl+L) to lock the sprite. Note
The mountains cast member contains an alpha channel that enables it to fade into the background.
10. In the Score window, Shift-click the navbar and title sprites, and then hold down the Option (Alt) key and drag a copy of the sprites until they are located just to the right of the original navbar and title sprites. The new sprites should extend from frame 30 through frame 56. Note
In the next step, you animate the navbar and title sprites. You created a copy of the sprites so that you have a backup of them in their final position, just in case something goes wrong with the animation you are going to create.
11. Click the tail of the navbar sprite in frame 30, and choose Insert ➪ Keyframe, or press Command+Option+K (Ctrl+Alt+K), to insert a keyframe. Then repeat this step for the title sprite channel 2. 12. Click the First frame (frame 5) of the navbar sprite, and then on the Stage, drag the sprite so that it disappears behind the mountains. You should see an animation path that shows the motion of the sprite.
365
3486-6 ch09.f.qc
366
7/24/00
5:47 PM
Page 366
Part II ✦ Bringing It All Together
Figure 9-6: The scene should now look similar to the one shown here.
13. In the Score window, click in the first frame of the title sprite, and then enter –90 in the Sprite Rotation field of the Score window. This value rotates the sprite 90 degrees counterclockwise, as shown in Figure 9-7. 14. Make sure that only the first keyframe for the title sprite is selected, and drag the sprite completely off the left side and down toward the bottom half of the Stage. Tip
You might want to zoom out the Stage so that you can see where you positioned the title sprite off the Stage.
15. To have the mountains transition from black, make sure that the Score window is open, and then double-click frame 2 of the Transition channel. Select a transition from the list. 16. Save the movie as explore2.dir. Rewind the movie and play it back. If the animation plays too slowly, increase the tempo by double-clicking in the Tempo channel and adjusting the tempo speed. You also might want to adjust the Sprite Tweening to make the animation move more smoothly. Click the sprite to select it, open the Sprite Tweening dialog box either by choosing Modify ➪ Sprite ➪ Tweening or by pressing Command+Shift+B (Ctrl+Shift+B), set the parameters that you want in the dialog box, and then click OK to return to Director’s main window. When you are satisfied with the animation, save the movie again as explore2.dir.
3486-6 ch09.f.qc
7/24/00
5:47 PM
Page 367
Chapter 9 ✦ Creating an Interactive Presentation
Sprite rotation angle
Figure 9-7: Set the rotation angle of a sprite by entering a number in the Sprite Rotation field. Caution
If you adjusted the tempo for the animation, you’ll probably want to set the tempo back to a more normal speed (15 to 30 fps) in frame 31. This setting ensures that any other animations that occur later on in the movie play as you expect them to. You can always set a new tempo speed at other points in the movie, if necessary.
Tweaking sprites Evenly spacing a series of sprites on the Stage by hand can be a time-consuming chore, even if you are using grids. You can use the Sprite Inspector and do the math to calculate the offset, but why do that when you don’t have to? Director’s Tweak window enables you to quickly create an even offset for a series of sprites. Now that you’ve introduced the navigation bar, you need to add the navigation buttons. You use the Tweak tool to quickly create an even offset for each of the buttons. Then you adjust the starting points of the sprites to have them appear on the Stage one at time.
367
3486-6 ch09.f.qc
368
7/24/00
5:47 PM
Page 368
Part II ✦ Bringing It All Together
Using the Tweak Window to Offset Sprites 1. Open the explore2.dir movie in Director and make sure that the Score window is active. 2. Click the tail of the navbar sprite in frame 56, and drag it to frame 79 to extend the sprite. Repeat this step for the title sprite in channel 2. Note
If you didn’t make copies of the sprites earlier, you could Option+drag (Alt+drag) the last keyframe of the original sprites to frame 79. This would extend the sprite the same way as the previous method.
3. Open the Cast window and select the interface elements cast. Locate the navbutton up cast member and drag it into frame 31 of sprite channel 3 of the Score window. Drag the tail of the sprite to frame 79. 4. Make the Stage active, and press Command+Option+S (Ctrl+Alt+S) to open the Property Inspector. Make sure that the navbutton up sprite is selected, and enter 115 into the X position and 78 into the Y position, as shown in Figure 9-8.
X location Y location Figure 9-8: Use the Sprite Inspector to set the location of a sprite.
5. Select the navbutton up sprite in the Score window and Option+drag (Alt+drag) a copy of the sprite to channel 5. Be sure to leave an empty channel between the two sprites. Later you’ll insert the text label for the button in the empty channel.
3486-6 ch09.f.qc
7/24/00
5:47 PM
Page 369
Chapter 9 ✦ Creating an Interactive Presentation
6. Move the Score window down so that the navbutton sprite is visible on the Stage (it’s on top of the sprite in channel 3), and then open the Tweak window by choosing Modify ➪ Tweak or by pressing Command+Shift+K (Ctrl+Shift+K). Enter 125 in the Horizontal change field and click the Tweak button (see Figure 9-9). Note
There is a major difference between the Sprite Inspector and the Tweak window. The Sprite Inspector fields show actual sprite position on the Stage. Use the Tweak window to enter the change in position that you want to make by typing a number in one of the offset fields, that is, from where it is now and where it will be after the change is made.
7. Option+drag (Alt+drag) a copy of the sprite in channel 5 to channel 7, and click the Tweak button. Option+drag (Alt+drag) a copy of the sprite in channel 7 to channel 9, and click the Tweak button again. Your scene and Score windows look like the ones shown in Figure 9-10. The four button sprites are now on the Stage and are evenly spaced.
Horizontal change field Vertical change field Figure 9-9: Use the Tweak window to offset a sprite.
Figure 9-10: The four button sprites are offset evenly.
369
3486-6 ch09.f.qc
370
7/24/00
5:47 PM
Page 370
Part II ✦ Bringing It All Together
8. To have the buttons appear on the screen one at a time, click the first frame of the sprite in channel 5 and drag it 10 frames to the right. Repeat this step with the sprites in channels 7 and 9, but move these sprites to the right 20 and 30 frames, respectively. 9. Save the movie as explore3.dir, and then rewind and play it. Note that the buttons appear on the Stage one at a time. After you have used the techniques explained in the preceding exercise a few times, you’ll be able to offset a series of sprites in far less time that it takes to read through the exercise.
Animating with a behavior When you looked at the completed version the explore movie, you might have noticed that the text labels for the main navigation buttons appeared to be typed one character at a time onto the screen. You create this effect by using a Library Palette behavior appropriately called the Typewriter Effect. Director’s Library Palette contains many behaviors that are used to animate sprites. These behaviors enable you to create animated effects that would have taken far longer to create in earlier versions of Director. It’s well worth your time to become familiar with all of the animation behaviors found in the Library Palette. Knowing how the behaviors work will enable you to create better movies in less time. Tip
Appendix B contains a description of all the behaviors found in the Library Palette.
All that’s left to do to complete the opening animation is to add the text labels for the navigation buttons and have them appear to type onto the screen. In the preceding exercise, you left an open sprite channel between each of the navigation buttons — this is where you insert the label cast members for each button. Because all the navigation buttons use a single cast member, it is easy to apply the wrong Go To marker parameter when you apply the button navigation behaviors later. To make life easier, we name the text cast members used for the button labels after the section of the movie to which the button jumps. This reduces the chances of making a mistake when you apply the button behaviors, because you can look at the sprite directly below the button to know to which section the button should jump.
Animating the Text Labels 1. Open the explore3.dir movie that you saved in the preceding exercise in Director. Make sure that the Score and Cast windows are visible. 2. Select the interface elements cast and locate the cast member called Tour nav text (it should be in cast slot 41). Drag the cast member into the Score so that it begins in frame 31 of sprite channel 4.
3486-6 ch09.f.qc
7/24/00
5:47 PM
Page 371
Chapter 9 ✦ Creating an Interactive Presentation
3. Repeat Step 2, placing the cast members named factfinder nav text, Lander pilot nav text, and Quit nav text into the open sprite channel located after each navigation button sprite. 4. Adjust the length of the sprites so that they all end in frame 79. The Score now looks like the one shown in Figure 9-11.
Figure 9-11: The text sprites are located below the button sprite that they label; the lengths of the sprites have been adjusted.
5. In the Score window, Command+click (Ctrl+click) the four text sprites. Then apply the Background transparent ink to them from the Ink pop-up menu in the Score window. 6. Make sure that the sprites are still selected, and open the Sprite Inspector. Enter 125 for the X coordinate and 70 for the Y coordinate. All four text sprites are now next to the first navigation button. 7. In the Score, select the factfinder nav text sprite, and then open the Tweak window. Enter 125 into the horizontal offset field. 8. Repeat Step 7 with the other two text sprites, entering 250 and 375 into the horizontal offset field, respectively. 9. Select the four nav text sprites in the Score window, and apply the Typewriter Effect behavior, using the behavior pop-up menu. The Parameters dialog box appears (see Figure 9-12). This behavior enables you to control how the behavior is activated, how long it pauses before typing the next character, and what sound, if any, and the channel that sound plays in. For this use of the behavior, the only parameter you want to adjust is the time to wait parameter. Set it to 0 so that the text types on as fast as possible.
371
3486-6 ch09.f.qc
372
7/24/00
5:47 PM
Page 372
Part II ✦ Bringing It All Together
Figure 9-12: Set parameters for the Typewriter Effect behavior to control the way the text types on the screen. The Typewriter Effect behavior was originally located on the Library Palette in the Text category. We brought it into the Cast window for you to save time.
Note
10. Save the movie as explore4.dir, rewind the movie, and play it back. The text now types onto the screen. Caution
The Typewriter Effect behavior reads the text of the cast member to which it has been applied into memory. It then adds the text one character at a time, until the text string is completely typed. If you stop the movie before that text has completely typed on the screen, the text cast member will contain only the characters that have been typed in when the movie was stopped. This problem only occurs while you are creating the movie in Director, not when it’s played back as a projector or Shockwave movie. It’s a good idea to make a backup cast member of the text member to which you apply the behavior. If you stopped the movie before the text finished typing onto the screen, replace the cast members by using backup cast members of the four text labels located in the interface elements Cast window. You can find the backup cast members beginning in slot 101.
Building the Navigation Elements Carefully structuring the Score and Cast windows in combination with a good naming convention for the cast members saves hours of creation time. Defining sections of the Score that contain the various elements, such as buttons, headers, and content, speeds up the development and makes it much easier to update your movies months later. It doesn’t matter how you structure your movies. For instance, you might prefer to have the navigation elements begin in Sprite channel 50; the important thing is to use techniques that work for you and stick with them. Developing a consistent approach to the way you structure your movies is the main goal.
3486-6 ch09.f.qc
7/24/00
5:47 PM
Page 373
Chapter 9 ✦ Creating an Interactive Presentation
Laying out the primary navigation elements Now that you have the opening animation sequence finished, it’s time to add the navigation elements to the rest of the movie. At this point, you want to start thinking about the structure of rest of the movie and the navigation behaviors you’re going to be applying to the buttons. The first step is to add markers to the movie that define where each section of content begins. Although it’s possible to add additional markers to the movie at any time, you are much better off if, early in the project, you add as many of the necessary markers as you can. This enables you to use the markers to jump easily to each section of the movie and add content. The other advantage is that most of the navigation behaviors that ship with Director generate a list of the markers in the movie as a parameter. When you apply the behavior, you can choose which marker you want the movie to jump to from a pop-menu contained within the behavior. Before beginning, review the Navigation flow chart shown in Figure 9-13. This helps you, first, to determine how many content screens to insert into each main section of the movie. Then you add markers that define the beginning of each section.
Explore Mars Navigation Flowchart Opening Animation
Vitural Tour
QTVR 1
QTVR 2
Mars Lander Game (external movie)
FactFinder
QTVR 3
Mars Facts Screen 1
Web Links
Mars Facts Screen 2 Mars Facts Screen 3 Figure 9-13: The flow chart helps you easily determine where to put the markers in your movie.
373
3486-6 ch09.f.qc
374
7/24/00
5:47 PM
Page 374
Part II ✦ Bringing It All Together
Adding the navigation markers With the exception of the Mars Pilot Game (which will be a separate Director movie), each box in the flow chart represents a point in the movie that you want to loop on a frame. Each of these frames in the movie enables users to view content or to make a decision about the next section of the movie that they want to view. Adding a marker that has the same name of each box in the flow chart makes it easy to define each section of the movie. Because you already know how to add sprites to the Stage, we saved you some time by placing the sprites on the Stage that are used for the second-level navigation of the movie. We also added a text cast member that appears at the end of the animation sequence that gives a brief explanation of the movie. On the CD-ROM
For the next exercise, you use the explore5.dir Director movie, which is on the CD-ROM in the EXERCISE:CH09 (EXERCISE\CH09) folder.
Adding the Markers 1. Open the explore5.dir movie in Director, and then make sure that the Score window is active. Note that a marker named intro text has been added to frame 82. This is where the movie pauses to let users select what section of the movie that they want to explore. 2. Click in the marker channel in frame 90, at the insertion point type tour. 3. Add the following markers to the indicated frames: frame 95 = olympus, frame 100 = viking, frame 105 = terraforming, frame 120 = fact, frame 125 = ppt1, frame 130 = ppt2, frame 135 = ppt3, frame 140 = HTML, frame 150 = quit. When you’ve finished this step, your Score looks like the one shown in Figure 9-14. Tip
When you add a new marker that’s close to an existing one, it’s often difficult to type in a name for the new marker. To avoid this problem, add a marker in a section of the Marker channel that has no other ones near it, type in the name for the marker, and then drag it to the frame of the movie where you want the marker to be located.
4. Save the movie as explore6.dir. Drag the Score window down so that the markers and the top of the Stage are both visible. 5. Press Command+left arrow (Ctrl+left arrow), and the playback head jumps to the next marker. If you press Command+right arrow (Ctrl+right arrow), the playback head jumps to the preceding marker. Note
You can also use the Markers window to navigate between markers, add new markers, and edit existing ones. Choose Window ➪ Markers, or press Command+Shift+M (Ctrl+Shift+M), to select the Markers window.
3486-6 ch09.f.qc
7/24/00
5:47 PM
Page 375
Chapter 9 ✦ Creating an Interactive Presentation
Figure 9-14: The Score window with the markers added
The movie eventually will loop on each frame that has a marker. You could have put all of the markers next to each other in the Score, but this makes it difficult to see the names of the markers. Because the navigation jumps to each marker and then loops on the frame, it doesn’t matter where they are placed in the movie. So, you might as well spread them out so that’s it easier to read the labels. After you add the markers, you need to extend the button, label, and navigation bar sprites so that they appear in every frame on which the movie loops. When you perform this operation, you want to take into consideration the behaviors and other scripts that are going to be applied to the sprites. Sprites that have the same behavior applied to them throughout the movie, such as the navigation buttons, should be extended the entire length of the movie. This approach enables you to apply the behavior to the sprite once, and it also saves a lot of debugging if you have to modify the behavior, because it is applied to a single sprite instead of to several copies of the sprite.
Extending the Navigation Sprites and Color Coding the Score Window 1. In Director, open the explore6.dir movie that you saved in the preceding exercise. Make sure that the Score window is active. Scroll the Score window so that frames 30 to 80 are visible. 2. Command+click (Ctrl+click) the sprites that begin in frame 31 and are located in channels 1, 2, 3, 5, 7, and 9 to select them. With the sprites selected, enter 140 in the End Frame field located at the top of the Score window (see Figure 9-15). This extends the selected sprites to frame 140, which is the last frame in the movie that needs to have these sprites visible on the Stage.
375
3486-6 ch09.f.qc
376
7/24/00
5:47 PM
Page 376
Part II ✦ Bringing It All Together
Figure 9-15: Select sprites and type a frame number in the End Frame field to extend them.
3. Because the text label sprites have the Typewriter Effect behavior applied to them, you don’t want to extend them the entire length of the movie or else the effect keeps repeating itself. Select the text label sprite in channel 4, and then Option+drag (Alt+drag) a copy of the selected sprite next to the original one. Repeat this step for the text label sprites in channels 6, 8, and 10. 4. Command+click (Ctrl+click) duplicate versions of the text label sprites in channels 4, 6, 8, and 10, and then click the Behaviors pop-up menu (see Figure 9-16) in the Score window and choose the clear all behaviors option.
Figure 9-16: Add or delete behaviors to sprites from the Behaviors pop-up menu in the Score window.
3486-6 ch09.f.qc
7/24/00
5:47 PM
Page 377
Chapter 9 ✦ Creating an Interactive Presentation
5. With the text label sprites still selected, extend them to frame 140, as you did in Step 2 with the other navigation sprites. 6. Apply a color to the sprites in channels 1 through 10 to make it easier to identify the navigation elements. Click in the sprite channel 1 label on the left side of the Score window. Then hold the Shift key down and click in the sprite channel 10 label, as shown in Figure 9-17. This selects all of the sprites in channels 1 through 10. Select a color from the swatches located in the lower left corner of the Score window.
Sprite channel labels Sprite channel color swatches Figure 9-17: Click in the sprite channel label to select all of the sprites in the channel.
7. Save the movie as explore7.dir. Color coding the sprite channels is just one more technique that you can use to organize your movies, enabling you to spend less time building and debugging the movie, giving you more time to focus on the creative aspects of your movies.
377
3486-6 ch09.f.qc
378
7/24/00
5:47 PM
Page 378
Part II ✦ Bringing It All Together
Adding the Navigation Behaviors Carefully structuring the way sprites are arranged in the Score makes the process of adding the behaviors and other scripts that add interactivity to your movie much easier. Another simple technique you can use to streamline building your movies is to drag all the behaviors found in the Library Palette into a Cast window before you begin applying them. When you drag a behavior from the Library Palette onto a sprite, Director places a copy of the behavior in the first available cast member slot of the current Cast window. Having behaviors spread throughout different Cast windows won’t affect the way the movie plays back; however, it does make it more difficult to find them again if you want to drag a behavior onto another sprite. Storing the behaviors in a separate Cast window makes it easier to locate them when you want to modify or apply the behaviors to other sprites that are added to the movie. The behaviors contained in the Library Palette that you’re going to use in the movie have already been added to the behavior Cast window. On the CD-ROM
For the following exercises, you can use the explore7.dir movie you saved in the preceding exercise, or you can use the explore7.dir movie on the CD-ROM in the EXERCISE:CH09 (EXERCISE\CH09) folder.
Adding the Loop on Frame Behavior 1. Open the explore7.dir movie in Director, making sure that the Score Window is open. 2. Click in frame 82 of the script channel under the marker named intro text. Choose the Hold on Current Frame behavior from the Behavior pop-up menu in the Score window. Note
You can find the Hold on Current Frame behavior in the Navigation category of the Library Palette.
3. Add this behavior to the other frames in the movie that contain markers (except the marker named start). Alternatively, you can copy the first behavior that you applied and paste in into the other frames. 4. Save the movie as explore8.dir. Next you’re going to add a behavior to the navbutton sprites on the main navigation bar that enables the buttons to become highlighted when the mouse rolls over them, display a down state and play a sound when clicked, and then jump to a specific section of the movie. The behavior you use is the MultiPurpose button behavior that you used in Chapter 7 to create multistate buttons. This behavior was custom built into Lingo to combine the features of several different behaviors found in Director’s Library Palette into a single behavior.
3486-6 ch09.f.qc
7/24/00
5:47 PM
Page 379
Chapter 9 ✦ Creating an Interactive Presentation
Adding the Main Navigation Behaviors 1. Open the explore8.dir movie in Director, making sure that the Score window is visible. Open the Cast window and choose the behaviors cast. 2. Scroll the Score window so that the navbutton up sprite that begins in frame 31 of sprite channel 3 is visible. Tip
Remember that earlier in the movie, you added the sprite that serves as the label for the button in the sprite channel below the button.
3. Drag the MultiPurpose Button behavior from the behavior Cast window onto the navbutton up sprite that begins in frame 31 of channel 3. The Parameters dialog box for the behavior appears, as shown in Figure 9-18. 4. As long you haven’t moved any of the nav button cast members in the Cast Window the default cast members listed for the different states should be the correct ones. Make sure that the cast members used for the button states match the ones shown in Figure 9-18; if not, select the correct cast members from the pop-up menus for each parameter.
Figure 9-18: Make sure that cast members used for the button state parameters are the ones shown in this figure.
5. Select the “tour” marker from the Action pop-up menu. There is only one sound in the movie, so the button7 sound parameter is correct. If you want to use a cursor other than the finger for the rollover state, select a different cursor from the Use which cursor? pop-up menu.
379
3486-6 ch09.f.qc
380
7/24/00
5:47 PM
Page 380
Part II ✦ Bringing It All Together
6. Repeat Steps 3, 4, and 5 for the navbutton sprites in channels 5, 7, and 9. Select these parameters from the Action pop-up menu: channel 5 = “Fact”; channel 7 = nothing; channel 9 = nothing. 7. Save the movie as explore9.dir, and then rewind the movie and play it. Click the each of the buttons to make sure that they display the correct cast members for each state, that the sound plays, and that the first two buttons go to the correct markers. For the time being, the Lander Pilot and Quit buttons perform no action. Both of these buttons require a different type of behavior that you add in exercises later in this chapter.
Using the Jump to Marker behavior for the Quit button There are many situations that will arise in your movies in which you want the user to jump to another section of the movie and then return to the point in the movie from which the user came. In the movie that you’re building in this chapter, the Quit button on the main navigation bar needs to have this kind of functionality. When the user presses the Quit button, the user should have the option either to terminate the application or to change his or her mind and continue viewing the movie. If the user chooses to continue viewing the movie, it’s a good practice to return to the screen that the user was viewing previously. Director has several built-in behaviors that can be applied to a button that keep track of the frame where the movie was when the user pressed the button. The Jump to behaviors function like the Back and Next buttons in a Web browser, enabling a user to backtrack through the screens that they have viewed previously. These behaviors are very useful for a complex movie that has a large amount of interactive content. You can create a set of buttons that will automatically step the user through the sequence of screens that they chose to view in the movie or movies. You can also use these behaviors to create hyperlinks that branch to a deeper level of content contained in any movie, and then jump back to the original movie at the frame that the user was viewing previously. The behaviors that perform these operations are in the Navigation category of the Library Palette. They are called the Jump Forward, Jump Back, Jump to Marker, and Jump to Movie behaviors. In the next exercise, you add functionality to the Quit button on the main navigation bar of the explore9.dir movie. When the user clicks the Quit button, a screen asks whether to terminate the application or continue viewing the movie. Director’s built-in Jump to Marker behavior enables a user to jump to the Quit screen. If the user decides to continue viewing the movie instead of terminating it, the user can click a button that returns the user to the frame in the movie where the user clicked the Quit button. This behavior stores the frame number that the user was viewing when the user clicked the Quit button. If the user presses the Cancel button, the user returns to the frame in the movie that the user was viewing previously.
3486-6 ch09.f.qc
7/24/00
5:47 PM
Page 381
Chapter 9 ✦ Creating an Interactive Presentation
A discussion about quitting Unless you are building a multimedia application that you’re sure will be viewed only by experienced computer users, you may want to consider not having the Quit button actually terminate the application. If the user accidentally clicks the Quit button, but hasn’t actually finished viewing the movie, the user will have to relaunch the application. In most cases, you want give the user a second chance to decide to actually terminate the application or continue viewing the movie. Although this technique requires the user to make an extra mouse click to quit the movie, it’s generally a good approach, especially if your application is being designed for less-experienced computer users. One method to prompt the user when the Quit button is clicked is to build an alert dialog box, which gives the option to terminate the movie or continue playing it. Creating these kinds of dialog boxes requires some pretty complex Lingo scripting in combination with Director’s MUI (Macromedia User Interface) Xtra. The MUI Xtra enables you to create dialog boxes that have the same look, feel, and functionality as the operating system’s dialog boxes. You can learn more about creating custom dialog boxes with the MUI Xtra in Chapter 23. If you’re not very comfortable with Lingo — or you don’t want to have a dialog box appear that looks like it’s part of the computer’s operating system — you can build an interim screen in the movie that asks the user if he or she wants to terminate the application or continue viewing the movie. The advantage to this approach is that it enables you to use the same look and feel as the rest of the movie. This interim screen is also a good place to include the credits for your movie.
Adding the Jump to Marker Behavior 1. In Director, open the explore9.dir movie that you saved in the preceding exercise, making sure the Score window is open. Then select the behaviors Cast window. 2. Locate the Jump to Marker behavior and drag it onto the navbutton up sprite in channel 9. Note
The Jump to Marker behavior is located on the Library Palette in the Navigation category.
3. In the Parameters dialog box, choose the Quit marker from the On mouseUp, jump to marker menu, set the Jump Mode to Play and Return, and make sure that the Remember Current Marker for Back button? box is checked, as shown in Figure 9-19. Figure 9-19: The parameters are correctly set for the behavior.
381
3486-6 ch09.f.qc
382
7/24/00
5:47 PM
Page 382
Part II ✦ Bringing It All Together
4. With the Score window active, press the Tab key. This action advances the movie to the last frame that has a sprite in it (the Quit screen in this case). Drag the Score window so that the two buttons labeled Cancel and OK are visible on the Stage. 5. Select the button labeled Cancel, locate the MultiPurpose Button behavior in the behaviors Cast window and drag it onto the sprite. Select the following cast members for the button state parameters: Up state = GlassButton up; Down state = GlassButton down; Roll state = GlassButton roll; Inert state = GlassButton up. The sound parameter should be correct, because there is only one sound in the movie. You want to make sure that the nothing is chosen for the action parameter. Use the default Finger cursor if that is the one that you’re using for the other buttons. 6. Drag the Jump Back button behavior from the behavior Cast window onto the sprite. This behavior intercepts a message sent from the Jump to Marker behavior applied to the Quit button that keeps track of the frame number the movie was in when a button that contains a Jump to behavior is clicked. Tip
Director’s built-in behaviors contain detailed descriptions of the functions that the behavior will perform. To see this information, double-click the behavior in the Cast window; this activates the Behavior Inspector. The information about the behavior is in the Description pane of the Behavior window. If you click the Script button in the Behavior Inspector, you will find that the Lingo script usually contains commented information that goes into greater detail about the behavior’s functionality.
7. Save the movie as explore10.dir. Rewind the movie and play it. Click the Quit button on the main navigation bar. When the Quit screen appears, click the Cancel button. Try this from several different frames of the movie and note that you are brought back to the exact frame in the movie that you were in when you clicked the Quit button. The Jump to Marker and Jump Back button behaviors are designed to work together. If you apply the Jump to Marker behavior to a button, you have to apply the Jump Back button behavior to the button that is used to jump back to the previous frame of the movie that was being viewed. Note
You can have this same functionality if you want to jump between several movies by using the Jump to Movie behavior in combination with the Jump Back button behavior. You learn how to use this technique later in this chapter.
Terminating the application Director has two Lingo commands that you can use to terminate the application: Quit and Halt. The Quit command stops the movie and terminates the Director application. This can be very frustrating while you are building the movie, because you have to relaunch Director each time you click the button that has the Quit command applied to it.
3486-6 ch09.f.qc
7/24/00
5:47 PM
Page 383
Chapter 9 ✦ Creating an Interactive Presentation
Instead of the Quit command, use Lingo’s Halt command. The Halt command functions similarly to the Quit command by terminating the application when the movie is played as a projector, but it does not terminate the Director application while you’re building the movie. Now you need to add a behavior to the OK button located on the Quit screen that terminates the application. To accomplish this, you apply the MultiPurpose button behavior to the OK button, and then you build a custom mouseUp event that uses Lingo’s Halt command to terminate the application.
Adding the Halt Command to the OK Button 1. Open the explore10.dir movie that you saved in the preceding exercise, and make sure that the Score window is active. 2. Press the Tab key to advance to the last frame in the movie, and drag the Score window so that the button labeled OK is visible on the Stage. Click the Behavior icon on the Toolbar to activate the Behavior Inspector. 3. Click the Behavior pop-up button and choose the MultiPurpose button behavior from the list. In the Parameters window, choose the same cast members for the buttons states that you applied to the Cancel button in the preceding exercise, and then click OK to return to the Behavior Inspector. Figure 9-20 shows the correct parameter settings that should be applied to the behavior.
Figure 9-20: Choose the same parameters as shown in this figure.
4. Make sure that the behaviors Cast window is open, and then click the Behavior Inspector to make it active. If the window is blank, reselect the OK button sprite. 5. Click the Behavior pop-up button, and choose the New Behavior option. A dialog box appears, prompting you to name the behavior; name it QuitMovie.
383
3486-6 ch09.f.qc
384
7/24/00
5:47 PM
Page 384
Part II ✦ Bringing It All Together
6. Make sure that the Events and Actions pane is open in the Behavior Inspector. Click the Event button, and choose the mouseUp event. Then click the Action button and choose Navigation ➪ Exit. Figure 9-21 shows how the behavior should appear in the Behavior Inspector window.
Figure 9-21: The Event and Action have been added to the QuitMovie behavior. Note
The Exit option uses the Lingo Halt command. Don’t confuse this with the Lingo command called exit that is used to exit a handler. If you open the script for this behavior, you will see that Director is using the Halt command.
7. Save the movie. Rewind the movie and play it. Click the Quit button and then click the OK button. The movie should stop playing and return you to Director’s main window. When you build a new behavior with the Behavior Inspector, the cast member that’s created is stored in the first available slot of the active Cast window. Having the behaviors Cast window active when you built the behavior ensured that the cast member would be stored in the same Cast window as the other behaviors used in the movie.
Building the QuickTime VR Tour You use Apple’s QuickTime VR (QTVR) technology to create photorealistic virtual environments that are platform independent. This exciting new technology is beginning to see widespread use both on the Web and in stand-alone applications such as games. There’s even a QTVR that was taken on the planet Mars (definitely one of our favorite QTVR movies).
3486-6 ch09.f.qc
7/24/00
5:47 PM
Page 385
Chapter 9 ✦ Creating an Interactive Presentation
There are three types of QuickTime VR media: Panoramas, Objects, and Scenes. Each media type and their uses are as follows: ✦ A QTVR panorama enables you to view a scene — usually a landscape or a room in a house or building — from a variety of angles. Most panoramas are created using a full 360-degree view, giving the illusion that you’re standing in the center of the scene. View a panorama by dragging the mouse in the direction that you want to view. When you move the mouse to a different quadrant of the window, the cursor changes to indicate the direction that you are moving in the scene. ✦ A QTVR object enables you to view a three-dimensional object, such as a car or a computer monitor, from a variety of angles. Rotate an object by clicking the mouse button on the object and dragging it in the direction that you want to view it. ✦ A QTVR scene is usually a collection of panoramas, objects, and other media, such as Web links, and static images, such as maps, that are combined into one movie. Each of these individual components is called a node. A QTVR scene contains hot spots — areas that link the nodes together. When the mouse passes over one of these hot spots, it changes to a finger, indicating that you can perform some action in the panorama. For example, you could have a panorama of a living room, and when the mouse passes over the door to the kitchen you can have a hot spot that enables the user to click on the door and view another panorama of the kitchen. Director fully supports the three QuickTime media formats. There are several Lingo commands that you can use to control various functions of the QTVR movies, such as the playback quality, size, and zoom settings. CrossReference
You learn more about Director’s QTVR Lingo commands in Chapter 19, where you’ll use Lingo to add functionality to a multinode QTVR scene.
Although you have a quite a bit of control over the way QuickTime VR files are used in your movies, Director does not have the capability to create the actual QTVR panoramas, objects, and scenes. You need to create them in another application, such as Apple’s QuickTime VR Authoring Tool, and then import them into Director. For users to view QTVR movies, they need to have QuickTime installed on their systems. If you’re distributing your movies on CD-ROM, you should look into licensing QuickTime from Apple so that you can include a QuickTime installer with the your interactive applications. Another approach is to create a Lingo script that detects whether QuickTime is installed on the user’s system. If it’s missing, you can have an alert box appear, asking users if they want to download it from the Web. Director then can launch the user’s browser to download the QuickTime extensions. This technique works for projectors as well as for Shockwave movies, as long as the user has a Web browser and a connection to the Internet.
385
3486-6 ch09.f.qc
386
7/24/00
5:47 PM
Page 386
Part II ✦ Bringing It All Together
Remember that large QTVR movies (especially complex scenes) can be very resource intensive. If your Director movies will be viewed on slower computers, you may want to avoid using complex QTVR scenes in your applications. You can learn more about Apple’s QuickTime VR technology, and see several QTVR examples at their Web site at http://www.apple.com/quicktime
Tip
Importing QuickTime VR movies into Director There’s no big mystery to importing QuickTime VR movies into Director. QTVR movies appear to Director as a QuickTime movie, and you import them the same way as any other digital video file. Remember that QTVR movies are linked files, so the QTVR movies should be in the same folder as the Director movie. You also want to make sure that you include the original QTVR files if you are distributing your Director movies as projectors. In the next exercise, you import and place three QTVR files — olympus.mov, viking. mov, and mohole.mov — into the explore11.dir movie, which is on the CD-ROM. This movie has all the elements in it that you added in the previous exercises, except that we added the navigation behaviors to the second-level navigation elements. On the CD-ROM
You need to have QuickTime 3.0 or greater installed on your system for the next exercise. The QuickTime installer for both the Macintosh and Windows is on the CD-ROM in the GOODIES:QUICKTIME (GOODIES\QUICKTIME) folder. The explore11.dir and three QTVR files olympus.mov, viking.mov, and mohole.mov are on the CD-ROM in the EXERCISE:CH09 (EXERCISE\CH09) folder. You may want to copy these files to a folder on your hard drive before beginning the following exercise.
Adding the QTVR Movies 1. Open the explore11.dir movie in Director. Press Command+3 (Ctrl+3) to display the internal Cast window. 2. Choose File ➪ Import or press Command+R (Ctrl+R). When the Import dialog box appears, select the olympus.mov, viking.mov, and mohole.mov files, and then click OK to import the files and return to Director’s main window. 3. In the Score window, click the Markers pop-up menu and choose the Olympus marker. Click Sprite channel 24, and drag the Olympus cast member into the core window or onto the Stage. 4. Open the Property Inspector and click the Sprite tab, make sure that the QTVR sprite is still selected, and position the sprite by entering 375 into the X field and 300 into the Y field of the Property Inspector window (see Figure 9-22).
3486-6 ch09.f.qc
7/24/00
5:47 PM
Page 387
Chapter 9 ✦ Creating an Interactive Presentation
Tip
Pressing the Tab key advances you to the next field in the Sprite Inspector. This technique works for most of Director’s dialog boxes and tool windows that have multiple text fields.
Figure 9-22: Use the Property Inspector to position a sprite on the Stage.
5. Repeat Steps 3 and 4 for the viking and mohole QTVR cast members. Place the viking QTVR in the frame labeled viking and the mohole QTVR in the frame labeled terraforming. 6. Save the movie as explore12.dir, and then select the tour marker from the marker window and play the movie. Press the Olympus Mons button, and then drag the mouse on the VR. Note
Press the Shift key to zoom in on the VR. Press the Control (Alt) key to zoom out.
Displaying the controller in QTVR movies You can set the properties of a QTVR movie to display a controller in the same way that you can with other digital video movies in Director by choosing the display controller option in the QuickTime Cast Member tab of the Property Inspector. You might want to display the controller if you want the user to be able to zoom in and out or view the hot spots. Although it’s possible to use a key command to zoom, it might be easier for the user to use the zoom tools found on the controller.
387
3486-6 ch09.f.qc
388
7/24/00
5:47 PM
Page 388
Part II ✦ Bringing It All Together
Note
You have to choose the Direct to Stage property to display a controller in a QTVR or digital video movie.
Another good reason to display the controller is to give users a short description of parts of the scene, or to inform them where a hot spot will take them if they click on it. It’s possible to create QTVR movies that can display a text description of a hot spot in the controller bar. When you viewed the QTVR panoramas in the preceding exercise, you may have noticed that the cursor frequently changed to a finger. These are hot spots that we built into the panoramas that contain text descriptions of different elements in the scene. In the next exercise, you set the properties of the QTVR movies to display the controller, enabling users to view the text descriptions. You also set several properties that enable Director to preload the panorama into memory and play the QTVR movie at maximum speed.
Setting the QTVR Properties 1. Make sure that the explore12.dir movie that you saved in the preceding exercise is open in Director. 2. Open the Cast window, and select one of the QTVR cast members. With the cast member selected, click the Properties button in the Cast window. When the Property Inspector appears, click the QuickTime tab. 3. Click the Show Controller checkbox, set the Video property to Play Every Frame (No Sound), set the Rate property to maximum, and click the Enable Preload option. These settings optimize the playback of the QTVR panorama. Note
When the Enable Preload option is selected, Director loads the entire QTVR movie (or as much as of the movie as will fit into the available memory) when the movie starts playing so that there won’t be a delay when the QTVR movie is displayed.
4. Repeat Step 3 for the other two QTVR movies. 5. Save the movie as explore13.dir, rewind the movie, and play it. Click the Virtual Tour button, and then select one of the QTVR panoramas. When you drag the mouse over a hot spot, note that a brief description of the hot spot appears in the controller. Tip
Click the Arrow button in the controller to view the hot spots that are contained in a QTVR movie.
QuickTime VR can literally add another dimension to your Director movies. Use Lingo to add other features to your QTVR movies, such as custom control buttons, to have the panoramas automatically zoom in or out, and to control the playback quality. It would even be possible to have the text that was displayed in the controller of the panoramas be displayed in a Director text cast member.
3486-6 ch09.f.qc
7/24/00
5:47 PM
Page 389
Chapter 9 ✦ Creating an Interactive Presentation
Adding Content from Other Sources If you’re an experienced Director user, you’ve probably had to recreate from scratch a PowerPoint presentation to use in a movie, because it wasn’t possible to import PowerPoint files. Have you ever tired to create hyperlinks for a movie? In earlier versions of Director, it required a good working knowledge of Lingo to create them. Director has solved most of these problems by enabling you to import PowerPoint presentations and HTML text into your movies. You may want to keep this a secret, though, because the world is full of poorly designed HTML pages and PowerPoint presentations that your client will want to use in a Director movie. All kidding aside, these features can really save a lot of movie-building time. The key to effectively using these types of media in Director is to try to control the initial design so that they fit seamlessly into your movies. Tip
If you are planning to use PowerPoint or HTML text content in a Director movie, design a template that fits the look and feel of the movie and have whoever is creating the content use these templates. This will save you from a lot of headaches later.
Importing PowerPoint presentations Importing a PowerPoint presentation into Director is a somewhat convoluted process. When you import a PowerPoint file using the Import PowerPoint File Xtra, Director takes all the individual elements (text, graphics, transitions, and so on) of the original PowerPoint file and converts them to individual cast members. Director then rebuilds the presentation in the Score window, using the converted cast members, and automatically applies a Wait For Mouse or Key Click Tempo setting for each slide. You define the way that Director will assemble the elements in the Score by means of the PowerPoint Import Options dialog box that appears after you have chosen a file to open (see Figure 9-23). The PowerPoint Import Options dialog box enables you to the set these options: ✦ Slide Spacing determines the number of empty frames in the Score between slides. ✦ Minimum Slide Duration determines the number of frames in the Score that a slide will use if it has no build or animation effects applied to it. ✦ If the presentation contains static build effects (such as text builds), Director will create a new slide for each effect. Item Spacing determines the number of empty frames between build slides.
389
3486-6 ch09.f.qc
390
7/24/00
5:47 PM
Page 390
Part II ✦ Bringing It All Together
✦ Fly Transition Item Spacing determines the number of frames in the Score that will be used to recreate any animated transition effects in a slide. Unfortunately, this setting is applied globally to all of the transitions in the file; however, you can adjust them individually in the Score window after the file has been converted.
Figure 9-23: Use the PowerPoint Import Options to set frame duration for the slides and effects that Director will use to create the presentation in the Score window.
When Director imports a PowerPoint file, it creates a copy of the presentation file, which means that you can enhance the Director movie without affecting the original PowerPoint document. Use Lingo to add more interactivity to the presentation, such as enabling users to select which slides they want to view from a pop-up menu. You can also use any of the features in Director to add sophisticated interactivity, such as synchronized audio and animation. In most cases, Director does a very good job of retaining the original look and feel of a PowerPoint presentation. Nevertheless, there are several caveats of which you need to be aware before importing a PowerPoint file: ✦ Director can import only version 4.0 PowerPoint files. If you are using a newer version of PowerPoint, you need to save the presentation as a PowerPoint 4.0 file. ✦ You can import a PowerPoint presentation into a new Director movie only. If you want to add a PowerPoint file to an existing movie, you need to create a new movie, import the file, and then copy and paste the Score data from the movie into the movie to which you are adding the presentation. ✦ When Director encounters a feature in a PowerPoint presentation that it doesn’t support, such as certain transitions or fonts, it substitutes the closest matching feature. Both the user manual and Director’s built-in help engine contain a detailed description of PowerPoint’s features and how they are converted in Director. To view this information in Director’s built-in help engine, type PowerPoint in the Find section, and then choose the Comparison of PowerPoint and Director Features category. ✦ You may run out of memory if you’re importing a large PowerPoint file that contains several OLE objects, such as charts and graphs, or if the file contains many large bitmap images. If this is the case, you may want to divide the PowerPoint file into several smaller ones and import them individually.
3486-6 ch09.f.qc
7/24/00
5:47 PM
Page 391
Chapter 9 ✦ Creating an Interactive Presentation
The movie that you’ve been building in this chapter uses a simple PowerPoint presentation in the FactFinder section. In the next exercise, you import a PowerPoint presentation that we built for you into a new Director movie. Because you cannot import PowerPoint files directly into an existing movie, you will copy and paste the Score data into the explore13.dir movie that you saved in the preceding exercise. On the CD-ROM
You use a PowerPoint file named facts.ppt for this exercise, which is on the CD-ROM in the EXERCISE:CH09 (EXERCISE\CH09) folder.
Importing a PowerPoint File 1. Open Director and create a new movie. 2. Choose Xtras ➪ Import PowerPoint File. A dialog box appears, prompting you to locate a PowerPoint file. Select the facts.ppt file and click Open. 3. The PowerPoint Import Options dialog box appears, as shown in Figure 9-23. The only option you need to adjust is the Slide Spacing. Enter 1 in the Slide Spacing field. Because you are using the default Item Spacing of 4 — forcing each slide to span 4 frames of the movie — you are left with one empty frame between slides, so each slide begins 5 frames from the previous one. This makes it easier to paste the slides into the explore.dir movie, because the markers that you placed in the movie that will contain the slides are spaced 5 frames apart. Click Import, and the file is imported into Director and the elements appear on the Stage and in the Score window, as shown in Figure 9-24.
Figure 9-24: The converted PowerPoint file as it appears in Director.
391
3486-6 ch09.f.qc
392
7/24/00
5:47 PM
Page 392
Part II ✦ Bringing It All Together
Note
After the file is imported, you will be alerted to reset the Stage size of your movie to match the size of the PowerPoint presentation. Because you will be copying the content into a new movie that is a different size, you can ignore this alert.
4. Save the movie as facts.dir. Rewind the movie and play it. Note that you can click the mouse or press any key to advance to the next slide. Take a few moments to explore how the movie is constructed by examining the Score and Cast windows. Now that you have the PowerPoint file converted to a Director movie, you need to copy the contents of the facts.dir movie into the explore13.dir movie that you saved to your hard drive at the end of the QTVR exercise earlier in this chapter. The easiest way to accomplish this is to copy the Score data from the facts.dir movie, and then paste the data into the explore13.dir movie. When you paste the Score data from one movie into the destination movie, Director places all of the cast members that the sprites in the Score window are referencing into the active Cast window. You may have noticed earlier that Director created 50 cast members when it converted the facts.ppt PowerPoint file. If you have the Internal or one of the other Cast windows active when you paste the Score data into the explore13.dir movie, the active Cast window will become quite a mess. To avoid this problem, you create a new Cast window, called PowerPoint, that will be active when you paste the score data from the facts.dir movie. This will make it much easier to identify the cast members that are used for the PowerPoint slides, because they will be contained in their own Cast window.
Inserting the PowerPoint Slides into an Existing Movie 1. With the facts.dir movie open in Director, make the Score window active so that all of the sprites that make up the three slides are visible. 2. Select all of the sprites, except the one called Shape item 11 in sprite channel 1, by clicking on the first sprite in channel 2, and then holding the Shift key down and clicking in frame 18 of sprite channel 23 (see Figure 9-25). Note
The sprite in channel 1 is a black rectangle that’s used as a background for the slides. Because the movie into which you’re going to paste these sprites already has a black background, this sprite is redundant and isn’t needed.
3. Press Command+ C (Ctrl+C) to copy the sprites to the Clipboard. 4. Open the explore13.dir movie that you saved earlier in the chapter. Make the Cast window active. Click the Choose Cast button, and select the New Cast option. When the New Cast dialog box appears, name the Cast PowerPoint and make sure that the Internal Radio button is selected. 5. Close any other open Cast windows to make sure that the PowerPoint Cast window is active.
3486-6 ch09.f.qc
7/24/00
5:47 PM
Page 393
Chapter 9 ✦ Creating an Interactive Presentation
Figure 9-25: All of the sprites that you want to paste into the destination movie are selected.
6. In the Score window, click sprite channel 24 in the frame that contains the ppt1 marker. Choose Edit ➪ Paste Sprites. Director pastes the sprites from the Clipboard into the Score beginning from the selected point in the Score window. The cast members are pasted into the PowerPoint Cast window, as shown in Figure 9-26. Tip
You might want to assign a color to these sprites to make it easier to identify them later. Make sure that the sprites are still selected in the Score window, and click on one of the color swatches located at the bottom-left corner of the Score window.
7. Save the movie as explore14.dir. Now you need to reposition all of the sprites so that they are located in the proper position on the Stage. 8. Make sure that all of the sprites that you pasted into the movie are still selected. In the Score window, put the playback head in the frame that’s labeled with the ppt3 marker, and then drag the Score window so that the Stage is visible. Caution
If you try to move the sprites on the Stage by dragging them, chances are that you’ll only choose one sprite instead of all of them. The safest way to move the sprites so that they all stay selected is to use the Tweak window.
393
3486-6 ch09.f.qc
394
7/24/00
5:47 PM
Page 394
Part II ✦ Bringing It All Together
Figure 9-26: The sprites are pasted into the destination movie, beginning at the selected frame.
9. Open the Tweak window by pressing Command+Shift+K (Ctrl+Shift+K). Enter 125 into the Horizontal Offset field and 100 into the Vertical offset field to position the sprites close to the final position that you want. Fine-tune the position of the sprites by entering new numbers into the Horizontal and Vertical Offset fields until you are satisfied with the final position. The Stage should look similar to the one shown in Figure 9-27. Caution
Tip
If you want to tweak a sprite in one direction only, make sure that you enter 0 in the other Offset field.
After you are satisfied with the position of the sprites, press Command+L (Ctrl+L) to lock them. This will prevent you from accidentally selecting and moving one of the sprites.
10. Save the movie, and then rewind it and play it. Click the Factfinder button, and then click the Mars Facts button. Click the Next and Prev button to view all three screens to make sure they are positioned correctly.
3486-6 ch09.f.qc
7/24/00
5:47 PM
Page 395
Chapter 9 ✦ Creating an Interactive Presentation
Figure 9-27: Use the Tweak window to adjust the position of the sprites so that they look similar to the figure.
Adding a PowerPoint file to an existing Director movie is a bit cumbersome. Carefully structuring the way that Director creates the sprites in the Score and creating a separate Cast window that will contain the cast members that are pasted into the destination movie will save you considerable time and headaches. Locking the sprites after they have been placed in your movies prevents you from accidentally bumping a sprite out of position.
Using HTML text in a movie In today’s world, almost every multimedia application has some type of Internet component to it. These components cover a wide range of possibilities, ranging from a simple link to a Web site to a multiuser CD-ROM game that connects to a server and enables you to compete online against other people from all over the world. It’s possible to create applications with Director that cover both ends of this spectrum. In this section, you learn the basics of Director’s Internet capabilities by importing an HTML document that contains hypertext links to several different Web sites. Then you apply a built-in behavior to the HTML text that will launch a Web browser and display the chosen Web site when a user clicks a hyperlink. When an HTML document is imported into a movie, it becomes a text cast member, giving you the same formatting control and options that you have with any other text cast member. Director recognizes most of the standard HTML tags and parameters, and approximates this formatting in the text cast member.
395
3486-6 ch09.f.qc
396
7/24/00
5:47 PM
Page 396
Part II ✦ Bringing It All Together
Caution
Director does not recognize the <APPLET>, , , , or HTML tags and ignores them when the file is imported. Director only imports the text that’s contained in the HTML document. Because the listed tags are used for elements other than text, they are not supported.
If the HTML text cast member contains hyperlinks that you want to have available in your movie, you can set a property called Use Hypertext Styles. This property causes the hyperlinks in the cast member to be colored blue and underlined; visited links are colored red. If you want to use colors other than blue and red for your links, you need to use Lingo to set the colors. In the next exercise, you import an HTML document called links.html, which contains several hyperlinks to the explore14.dir file to be used in the Links section of the movie. After importing the document, you apply Director’s Hypertext-General behavior, which enables the hyperlinks in the document to function as they do in the original HTML file. On the CD-ROM
The links.html file that you need for this exercise is located on the CD-ROM in the EXERCISE:CH09 (EXERCISE\CH09) folder.
Note
To test the functionality of the Hypertext links that you are adding to your movie, you need to have a Web browser with a connection to the Internet installed on your computer.
Importing HTML Text 1. Make sure the explore14.dir movie that you saved in the preceding exercise is open in Director. Open the internal Cast window. 2. Choose File ➪ Import or press Command+R (Ctrl+R). Locate the links.html document, double-click on it or click the Add button, and then click the Import button. A dialog box appears, prompting you to choose a format for the text document. Select the text option and click the OK button to import the file. 3. Locate the links cast member and double-click on it to open the cast member in the Text window. The text is colored green on a black background and the hyperlinks are blue and underlined. The text cast member is using the same formatting that was applied to the original HTML document. 4. Change the font to the embedded font used for the other text in the movie by selecting all of the text and choosing the font called *Optical C-Normal from the font menu, as shown in Figure 9-28. Note
The asterisk in front of the font name signifies that the font is embedded in the Director movie.
3486-6 ch09.f.qc
7/24/00
5:47 PM
Page 397
Chapter 9 ✦ Creating an Interactive Presentation
Figure 9-28: An embedded font has been applied to the text cast member.
5. Click the Properties button in the Text window. When the Property Inspector appears, set the Anti-Alias property to All Text. 6. Open the Score window and make sure that frame 24 in the sprite channel labeled with the HTML marker is visible. Hold down the Option (Alt) key and drag the links cast member into frame 24. This places the sprite in a single frame of the Score. 7. Close the Score window, make sure that the links sprite is selected on the Stage, and open the Sprite tab on the Property Inspector. Change the size of the sprite to 450 pixels wide by 325 pixels high by entering 450 and 325 into the Width and Height fields, respectively. Then drag the text sprite so that it’s centered in the lower right quadrant of the Stage. When you are finished, the Stage should look similar to Figure 9-29. 8. With the sprite still selected, open the Property Inspector and click the Behaviors tab. Choose the Hypertext-General behavior from the Add Behavior pop-up menu. Click OK when the Parameters dialog box appears, asking if you want to use Hyperlink styles. Note
The Hypertext-General behavior is on the Library Palette in the Text category.
397
3486-6 ch09.f.qc
398
7/24/00
5:47 PM
Page 398
Part II ✦ Bringing It All Together
Figure 9-29: Position the links sprite similarly to the one shown in this figure.
9. Save the movie as explore15.dir, and then play it. Click on one of the hyperlinks. Your Web browser opens and displays the Web page that you chose. You can also use the Hypertext-General behavior to send an e-mail message, go to an ftp site to download from the Internet, or execute a Lingo script. Any Hyperlink that contains the following URL schemes — http://, https://, ftp://, and mailto: — will work with this behavior. If you want to trigger a Lingo script with the behavior, the hyperlink must start with Lingo. Tip
You can add Hypertext links to any text cast member by selecting the text that you want to contain the hyperlink, and then type in the URL for the link in the Hyperlink Data field of the Text Inspector.
Using Multiple Director Movies If you are building large Director applications, you may want to consider breaking the project down into several different movies that are linked together. This modular approach is especially useful if several authors will be working on the project, reducing the development time needed to create complex Director applications.
3486-6 ch09.f.qc
7/24/00
5:47 PM
Page 399
Chapter 9 ✦ Creating an Interactive Presentation
This technique can also be used to create multimedia applications that are made up of separate modules that can be recombined to create customized versions of the application. For example, you can create a corporate sales presentation that will be used by several sales representatives. Each sales rep specializes in a separate product the company creates; therefore, each sales rep needs a customized version of the presentation. The main Director movie could contain content that every sales rep will need, such as a corporate overview and financial information. You then create separate movies for each product line, which are then linked to the main Director movie. This type of modular approach not only enables you to quickly customize a presentation, but it’s also a very efficient method for maintaining and updating content.
Launching an external Director movie By now you are aware of the amount of control you have over the way a user can navigate through your movies. You can create navigation by using behaviors to jump to any frame or marker in the movie, and then keep track of the frames that user has visited to enable them to go back to any point in the movie. This same functionality can be used to jump to and from separate Director movies. The Explore Mars Director movie that you’ve been building in this chapter only has one more piece of content to be added to complete the movie: the Lander Pilot game. This game is actually a separate Director movie called lander.dir. When the user clicks the Lander Pilot button on the main navigation bar in the Explore Mars Director movie, it launches the lander.dir movie. The lander.dir movie contains a button called Done that returns the user to the frame in the Explore Mars movie where the user clicked the Lander Pilot button. In the next exercise, you apply the Jump to Movie behavior found on the Library Palette to the Lander Pilot button to launch the lander.dir movie, a small game in which the user gets to fly a rocket around the planet Mars. After finishing the game, the user can click the Done button and return to the frame in the Explore Mars movie where the user clicked the Lander Pilot button. On the CD-ROM
For the next exercise, you can use explore15.dir movie that you saved in the preceding exercise, or you can use the explore15.dir movie on the CD-ROM. You also need the lander.dir movie. Both of these movies are on the CD-ROM in the folder EXERCISE:CH09 (EXERCISE\CH09). If you want to use the explore15.dir movie that you saved in the preceding exercise, you should copy the lander.dir movie into the folder on your hard drive that contains your explore15.dir movie.
399
3486-6 ch09.f.qc
400
7/24/00
5:47 PM
Page 400
Part II ✦ Bringing It All Together
Launching a Separate Movie 1. Open the explore15.dir movie in Director. In the Score window, make sure that the navbutton up sprite that begins in frame 51 of sprite channel 7 is visible. 2. Open the behaviors Cast window, locate the Jump to Movie button, and drag it onto the sprite. In the Open file dialog box, select the lander.dir movie and click the Open button. After you have chosen the lander.dir movie, you need to click the Cancel button to terminate this operation. Note
The Jump to Movie behavior is on the Library Palette in the Controls category.
3. The Parameters dialog box for the behavior appears, enabling you to set the following parameters for the behavior (shown in Figure 9-30): • The On mouseUp, go to movie parameter displays the path and destination movie. • You can enter a marker in the destination movie to which you want to jump. • Determine the Jump Mode. Go To does not retain the marker information of the current movie, whereas Play and Return stores the current marker information so that you can return to the same marker in the original movie. • The Remember current marker for Back button? option remembers the original movie for the Back button in the destination movie to use. Choose the Play and Return option from the Jump Mode pop-up menu and make sure that the Remember current marker for Back button? check box is enabled. Click OK to return to Director’s main window.
Figure 9-30: Set the parameters to control the way that the destination movie will be launched.
4. Save the movie as explore16.dir. Play the movie and click the Lander Pilot button. Have a little fun and play the game. When you’ve finished playing the game, click the Done button and note that you are returned to the same frame in the explore16.dir movie where you clicked the Lander Pilot button.
3486-6 ch09.f.qc
7/24/00
5:47 PM
Page 401
Chapter 9 ✦ Creating an Interactive Presentation
The Done button uses the same MultiPurpose button behavior that the buttons in the explore16.dir movie. We also applied the same Jump Back behavior to the Done button that you used for the Continue button in the explore movie. As you know, the Jump Back behavior stores the marker information, enabling the user to return to the previous marker. CrossReference
The lander.dir movie is a slightly modified version of the Director movie that you’ll create in Chapter 15, which teaches you how to use Lingo to control sprites.
Summary This chapter discussed the following techniques: ✦ A flow chart that breaks down the individual components of a Director movie makes it much easier to identify the elements that you use for the movie, as well as aids you in structuring the navigation. ✦ Careful organization of the Score and Cast windows speeds up the production of your movies. ✦ Use Director’s built-in behaviors to create complex navigation without having to program scripts in Lingo. ✦ Director supports a variety of external media, including QuickTime VR, PowerPoint files, and HTML text documents. ✦ You can link individual Director movies. Chapter 10 discusses the tools and techniques used to create a better production process for your movies.
✦
✦
✦
401
3486-6 ch09.f.qc
7/24/00
5:47 PM
Page 402
3486-6 ch10.f.qc
7/24/00
5:47 PM
Page 403
10 C H A P T E R
Designing a Production Process
C
reating successful multimedia applications with Director involves more than just a strong understanding of the program. A successful multimedia application contains timely, well-researched content, combined with a navigation scheme that’s easy to use. All too often, we see multimedia applications with all kinds of cool graphics and animation, but which fail to meet the application’s original objectives. The best way to avoid having this happen to your multimedia applications is to spend time up front to determine the scope of the project. Then you can develop a well-defined production process to create the application. This chapter explores several tools and techniques to help you do the following: clearly define the goals and objectives of your projects; add more creativity to your projects; and streamline the production process.
Determining the Scope of the Project You must consider many factors before building a multimedia application in Director. Some factors are more obvious than others, such as the computer platform and delivery medium on which the application is to play. Other factors are more obscure, such as determining whether there will be a secondary audience for the application — for example, building a game for students that has a tracking component for teachers to use. Developing a consistent approach to collecting this information not only makes for a better multimedia application, but also provides you with a basis for determining the cost and production time.
✦
✦
✦
✦
In This Chapter Determining the scope of a project The creative process Production techniques Copyright issues
✦
✦
✦
✦
3486-6 ch10.f.qc
404
7/24/00
5:47 PM
Page 404
Part II ✦ Bringing It All Together
Using a project analysis form The first step in determining the scope of a multimedia project is to ask the client the right questions. As the developer, you need to get the client to focus on the project’s objectives, the intended audience, how often the project will need to be updated, and the delivery media. It can be very difficult to ask all the right questions in a room full of people whose attention is divided between looking at your latest cool project and showing you their latest PowerPoint presentation. A useful tool to help you and your client answer these questions is a project analysis form that contains detailed questions about the objectives, audience, and any production considerations that need to be addressed in the project. If possible, ask the client to complete this form early in the project — ideally before your initial meeting. The information you gather on this form not only makes you appear more professional, but also enables you to walk into the room with solutions to problems. It also helps provide you with background information to answer the dreaded question: “How much do you think this is going to cost?” Another useful aspect of a project analysis form is that you can get an early indication of just how organized a client is, as well as how much thought the client has given to the project. If most of your questions are answered with “Don’t know,” you’ll know that you’re going to have to spend a considerable amount of time before beginning the project to help the client answer the questions, and then adjust your production timeline and budget factors accordingly. As mentioned earlier, your project analysis form should cover at least three main areas: objectives, audience, and production considerations. Let’s dissect each of these topics and give you a series of basic questions for each topic area.
Objectives Design questions about objectives so that they determine what the application needs to accomplish. The questions also give you a good starting point for researching the content for the application. Here are some sample questions: 1. Why do you want to produce a multimedia application? 2. What is the primary goal of the application? (Please select one.) • Inform • Motivate • Teach/Train • Sell • Other 3. What specific objectives do you want to accomplish with this multimedia application?
3486-6 ch10.f.qc
7/24/00
5:47 PM
Page 405
Chapter 10 ✦ Designing a Production Process
4. Are there any problems, misunderstandings, or misperceptions about the subject that need to be corrected? 5. Will the audience have access to other materials that deal with the same subject? If so, what are they? 6. In one sentence, recap the most important idea anyone using the multimedia application should get. Note that question two allows the client to pick only one topic. This is a subtle way of educating the client that a multimedia application that focuses on one specific goal is much more effective than an application that tries to serve as a catchall for several different objectives. Question six reinforces this concept by asking a client to define the major goal in a single sentence.
Audience Questions about the audience should make the client consider the target market and audience demographics for the multimedia application. The following questions help you determine the reading level of the content and the subject matter that should be emphasized or avoided in the project: 1. Who comprises the primary audience receiving this information? Describe by age, sex, educational level, and so on. 2. Who comprises the secondary audience? 3. What is the audience’s major interest in the multimedia application? Why would they want to use it? 4. What does the audience already know about the subject? 5. What possible negative attitudes toward the subject does the audience have? Why? 6. Are there any taboos or political factors that must be taken into consideration?
Production considerations Questions about production considerations help you determine the factors that affect the actual production of the project, such as the amount of time to complete the project, the delivery medium, and the budget. You should also include questions to help you create the look and feel of the project, and to help you choose the level of technology that you can employ. 1. What will be the primary delivery medium for the multimedia application? (Pick one.) • CD-ROM
• Hard disk
• Live on the Internet
• Other
• On the Internet via download
405
3486-6 ch10.f.qc
406
7/24/00
5:47 PM
Page 406
Part II ✦ Bringing It All Together
2. Will there be an alternate delivery medium for the application? If yes, what? 3. What will be the minimum system configuration on which the application will play? 4. If the project will be designed to play live over the Internet, what will be the minimum Web browser the application will have to support? 5. What style do you envision for the multimedia application (business-like, entertaining, documentary, cutting-edge, and so on)? 6. What existing resource materials (such as other multimedia applications, graphics, Web sites, brochures, and so on) could benefit this multimedia application? 7. How often do you anticipate updating this multimedia application? 8. Do you plan to expand this project in the future? 9. When is the target completion date for the project? 10. What is the budget for this project? 11. Is there anything else we should know in order to produce a successful multimedia application for your company? In most cases, the client will choose not to fill in the budget amount for a project. For some reason, clients seem to take the same approach to buying multimedia content that they do toward purchasing a car, forcing you to walk a fine line between scaring them off with too high a price or undercharging just to get the work. Life will be much easier if you know how much the client is willing to spend on a project, and often this will not be an issue after you have developed a relationship with the client and they trust you. In the meantime, filling in as many blanks as possible on your project analysis form helps you create realistic budgets and timelines for your multimedia applications.
The Creative Process After you’ve determined the scope of the multimedia application you’re going to create, it’s time to move on to the design phase of the project to begin capturing the concept’s ideas that will be used in the project. Coming up with creative concepts can often be one of the most difficult parts of creating a multimedia application. You can start by creating an outline, but this approach can force you to think inside a very limited box of concepts. A better approach is to use a technique called brainstorming, which enables you think freely — “outside the box,” so to speak. A very good tool to use for brainstorming is a program created by Inspiration Software called Inspiration (shown in Figure 10-1), which enables you to quickly capture ideas electronically. A good old-fashioned white board and sticky notes also work well for this process.
3486-6 ch10.f.qc
7/24/00
5:47 PM
Page 407
Chapter 10 ✦ Designing a Production Process
Figure 10-1: Inspiration is a very valuable brainstorming tool.
Gather in a room all the people who will be working on the project, and assign a person in the group to be the facilitator, the person who is responsible for capturing the ideas as the group throws them out. At this stage of the process, you want to capture as many ideas as possible, no matter how improbable or ridiculous they may seem. One way to avoid the “We can’t do that” syndrome is to arm everyone with a soft toy that they can use as a weapon to bombard anyone who criticizes an idea. This technique is lots of fun, and you’ll be amazed at the number of really powerful concepts that you can generate in a very short amount of time. After you’ve captured enough ideas, have the facilitator take a vote on each concept to narrow the ideas to those that are the most practical for the project. This gives everyone involved influence over the concepts. Another advantage to using Inspiration is that the program automatically builds an outline of ideas in the diagram. Inspiration is also a very good tool to use for creating flow charts. Tip
Make sure to keep the ideas that the group has discarded; they could prove to be very valuable for some other project.
407
3486-6 ch10.f.qc
408
7/24/00
5:47 PM
Page 408
Part II ✦ Bringing It All Together
Avoiding creative block One of the most difficult aspects of multimedia production is coming up with creative concepts to make your projects stand out from others. Here are several tips to spark your creativity and help you avoid the Blank Page Syndrome when it comes time to design your project. Keep a scrapbook that includes clippings from cool magazine ads and illustrations that you run across. Flipping through the scrapbook is a great way to spark a creative idea. Of course, you don’t want to steal another artist’s concept, but a powerful image or layout can often inspire your own unique concept. Use this same approach for Web sites by keeping a set of bookmarks of Web sites that might inspire you. Buy one of those magnetic poetry kits that contains individual words and use it to make random combinations of three to six words each. These word combinations can provoke a wonderful concept or idea. Give yourself a Whack on the Head. A very creative fellow named Roger Von Oech created a book and a deck of cards called the Creative Whack Pack. These cards give you all kinds of suggestions and techniques that force you to think nonlinearly. You can find his book and cards in most bookstores, and a software version is available.
Creating a flow chart One of the best ways to visualize the layout and navigation structure of your Director project is to create a flow chart. In Chapter 9, you used a simple flow chart to visualize the navigation components of your movie. Another good use for a flow chart is to model the logic in your movies. Suppose that you will create a game composed of a series of questions that progress through several levels of difficulty. The user will have three chances to answer the question in each level correctly. If the user fails to answer the question correctly on the third try, the user is taken to a screen that gives him or her several hints. The user then is invited to try to answer again. The illustration in Figure 10-2 shows how modeling this process can make it much easier to visualize what screens you’ll need to build in Director. The illustration is also a valuable tool for creating the Lingo scripting needed for the game. This example shows that you need to create two screens for each question. One screen contains the question, and another screen contains the hint. The triangles (commonly referred to as decision points) help you identify what actions the Lingo script must perform. In this case, the script needs to detect whether the question is correct, how many times the question has been answered, and the proper screen to which the movie should advance. Because you need a script that has this functionality for each level, it might make sense to create a behavior that enables you to adjust the parameters for each question.
3486-6 ch10.f.qc
7/24/00
5:47 PM
Page 409
Chapter 10 ✦ Designing a Production Process
Level one hint screen
No
Yes
Level one question screen
Is this the third try?
No
Is the answer correct?
Yes
Level two question screen Figure 10-2: Use a flow chart to model the logic in your movies. On the CD-ROM
A shareware flow-charting program, SmartDraw for Windows, comes on the CD-ROM that accompanies this book. It is in the GOODIES:SMARTDRAW (GOODIES\ SMARTDRAW) folder.
The value of storyboarding In Chapter 2, we discussed the benefits of storyboarding your animation sequences. For a large Director project, you should consider creating a detailed storyboard of the entire Director movie to serve as a roadmap, clearly defining the entire scope of the project. This storyboard ensures that everyone involved — from the client who is paying for it, to the audio engineer who will be creating the voiceovers — understands their role in the project. When you create a storyboard, make sure you clearly define all the visuals, text, animation, and audio components that will be included in each scene. This helps you identify the elements that need to be produced for the project, and it gives you a basis on which to estimate the cost of the project. A carefully detailed storyboard, like the one shown in Figure 10-3, is also the best way to make sure that both you and the client are in agreement about the content of the project. It’s a good idea to have the client sign off on the storyboards, which — ideally — helps you avoid having to absorb the cost of additional changes to the
409
3486-6 ch10.f.qc
410
7/24/00
5:47 PM
Page 410
Part II ✦ Bringing It All Together
scope of the project later on. If the project is going to be a complex one, you might want to create a rough prototype in Director to have the client sign off on also. On the CD-ROM
There are several blank storyboards on the CD-ROM that you can use for your own projects. They are in PDF format and can be opened and printed on both the Macintosh and Windows platforms, using Adobe’s Acrobat Reader software, which is also included on the CD-ROM. You can find the storyboards in the folder STORYBOARDS. You can find the Acrobat Reader in the GOODIES:ACROBAT READER (GOODIES\ACROBAT READER) folder.
Make sure that your storyboards include references to any factors that affect the cost and timely delivery of the project, such as: ✦ Digital video content that needs to be shot and edited before being included in the movie ✦ Complex animation sequences ✦ Special programming issues, such as connections to an online database, that might require outside assistance ✦ Any content requiring special permission or additional cost to acquire, such as stock photography, recordings of famous speeches, or a popular song The level of detail to include in the storyboard should reflect the amount of trust between you and your client. If you’re creating storyboards for a new client, you should include as much detail as possible to avoid confusion and to ensure that both you and the client have a clear understanding of the content that you’re going to deliver. Generally, you should spend about one-third of the allocated production time on the creative process. Any less time might cause you to miss something that could greatly affect the cost or time needed to complete the project. If you spend any more time than this, our experience is that no additional benefit is gained from your efforts. Caution
One of the authors of this book had an unfortunate experience with a dishonest client. He invested more than a week of time creating a detailed concept and storyboards for a television commercial to be produced by his client. After he submitted the proposal, the client informed him that he had chosen another company to produce the commercial. What the client actually did was use the author’s storyboards to have other production companies bid on the project until he found one that would produce the commercial for a lower cost. The commercial that aired was shot scene-for-scene from the author’s storyboards. If you are in a competitive bid situation in which you are asked to supply detailed storyboards for a project before a vendor is chosen, make sure that you either receive payment for the work up front, or have the client agree to compensate you for the time invested in creating the storyboards if they choose not to use you for the project. At the very least, include a copyright notice on each page. This may give you some kind of legal recourse if a client pulls a stunt similar to the one just described.
3486-6 ch10.f.qc
7/24/00
5:47 PM
Page 411
Chapter 10 ✦ Designing a Production Process
Figure 10-3: A detailed storyboard used for a client review
411
3486-6 ch10.f.qc
412
7/24/00
5:47 PM
Page 412
Part II ✦ Bringing It All Together
Work Flow Considerations Whatever the size of the project, deadlines for completion are usually very tight. When it comes time to begin the actual production, you need a system in place that enables the work to progress continually. Many aspects of a multimedia project affect the deadline of your project, such as getting the client to approve the written content, or legal or copyright issues that need to be resolved. If you are creating a presentation for an event such as a trade show or sales meeting, where the deadline is written in stone, you’ll be the one who has to make up all of the time lost at the beginning of the project. Try to anticipate problems that could affect the deadline up front, such as delays in receiving content from the client (usually the biggest showstopper), and come up with an alternate plan, such as having your own writer standing by, just in case. Make sure that the client is aware of this alternative and has approved it up front so that you won’t have to absorb the additional cost. Another way to have more control over the production process is to structure the review cycles carefully. Try to discourage review by committee — the best approach is to ask your client to assign a small team that has the authority to sign off on the project, especially for reviews late in the process. A good rule of thumb is to have two review cycles: the first near the beginning of the project, when the storyboards and project plan are presented, and a second near the end of the project. Reviews after the initial presentation of the storyboards and project plan are not the place to introduce sweeping changes, because they could affect the deadline. The best way to avoid this is to create detailed project plan storyboards and make sure that the client fully understands the work you intend to produce.
Managing the process Keeping track of all of the elements that need to be produced for a project can be an overwhelming task. Even a small project can contain hundreds of different elements, such as artwork for buttons and animation sequences, audio, digital video, behaviors, and text content. Working on a large project that involves several people compounds the complexity, because you not only need to identify all of the elements and make sure they are produced in a timely manner, but you also need to ensure that the content coming from these various sources is consistent. Here are some tips to help you better manage the production process and ensure consistency: ✦ Develop a standard naming convention for the elements, and make sure everyone sticks to it. A good technique is to develop a naming convention that identifies what the component is used for (for example, the main headers for
3486-6 ch10.f.qc
7/24/00
5:47 PM
Page 413
Chapter 10 ✦ Designing a Production Process
each section could use the prefix hdr followed by the name of the actual section name, such as hdrfacts.pct). This naming convention forces all the header elements to be grouped together in the folder, making it much easier to locate them. This convention applies to movie and Cast window names as well. ✦ Create a spreadsheet that contains a list of all of the elements that need to be created for each screen in the movie. This is a good point to determine the naming conventions. Then check off each element as it’s created. This gives you a clear picture of the progress and helps you identify content that is taking more time to create than you had anticipated. ✦ Build templates in Director that contain elements, such as navigation buttons, that are used for the entire project. These templates should have all of the properties set, such as movie size, color space, and background color. Set the 16 favorite colors in the color palette to be the 16 common colors used in the project. ✦ Carefully design a set of rules that governs the placement of sprites in the Score; for example, the company logo is always in sprite channel 10, navigation buttons are always in sprite channels 3 through 8, and so on. This technique is especially important if several authors will be working on the project. Use guides to govern the position of key elements, such as titles and navigation components. ✦ Store common elements, such as behaviors, logos, and buttons that you use throughout the project, in the Library palette. Put these elements in an unlinked Cast window, and then drag the Cast window into the LIBS folder, which is in Director’s application folder. ✦ Use the List View mode in the Property Inspector to track information about who created a particular cast member, as well as to find out the creation and modification dates. ✦ Create behaviors (Lingo scripts) that include parameters that give you as much flexibility as possible. For example, build a single behavior for the navigation buttons that contains every action that the various buttons in the movie will need to perform. Developing a consistent approach to the way you build movies saves many hours of wasted time and identifies far in advance issues that can affect the deadline.
Using project management software For large projects that involve a team, you should consider using project management software, such as Mac Flow or Microsoft Project. These programs enable you to track all the production aspects affecting the completion of the project. Project management software works by your plugging in each task, the number of people and percentage of their time devoted to the task, and the total amount of time needed to complete the task. This enables you to build a virtual model of the time
413
3486-6 ch10.f.qc
414
7/24/00
5:47 PM
Page 414
Part II ✦ Bringing It All Together
(called a timeline) involved in completing the project. With this model, you can easily identify tasks of the project that may affect the deadline, and then make any necessary adjustments, such as redefining the scope of the task or reassigning production resources. Remember that a project timeline is only as accurate as the data plugged into it. It’s also fairly time-consuming to maintain the timeline. If you’re working with a small team, building and maintaining a project timeline is probably more of a hindrance than a help.
Working in a networked environment There’s nothing more frustrating than searching for an important file on someone’s hard drive. The frustration is compounded if there are no standard naming conventions for the files. The best way to avoid this problem is to store the source files for a project in a carefully structured network environment. Although it’s not a good idea to work directly on the files stored on the network — this can bring most networks to their knees and can even cause the server to crash — it’s wise to have everyone update the files daily on the network that they are responsible for creating. The structure of the network should mirror your production process. Structuring your network will vary greatly, depending on the needs of the project, but following are some general guidelines for most types of multimedia projects: ✦ Dedicate an area of the network for the “raw” content, which then serves as a repository for the source material being collected and created for the project, such as word processing documents, digitized video footage, Photoshop files, and scanned artwork. ✦ After this raw material is processed — the elements have been prepared so that they can be imported into Director — they should be stored in a separate area of the network that is accessible to the multimedia authors. This arrangement helps to avoid confusion on the author’s part about which elements are ready to be imported into the movies and which are not. This could also be a good area for storing the working versions of the Director movies until they are finalized. ✦ As the movies begin to be finalized, you should store them in an area of the network dedicated to testing and debugging. After this stage is complete, move the finished movies to an area on the network where they are converted to projectors or are uploaded to a Web server as Shockwave and Java applets. Tip
Create a directory structure that matches the one used to deliver the content. This approach ensures that any linked media in your movies function correctly.
A media cataloging tool, such as Extensis Portfolio, is another valuable tool for managing the various media assets used for large productions. These types of software enable you to create keywords for the elements and create a catalog that
3486-6 ch10.f.qc
7/24/00
5:47 PM
Page 415
Chapter 10 ✦ Designing a Production Process
knows the location of the element, making it very easy to find it in the future. This is especially useful if you will be revising and enhancing the projects and will need to use those assets many times.
Understanding Copyright Issues Copyright is a form of protection that is provided by the United States (and most foreign governments) to the author of an original work. For example, an author can be an architect, artist, composer, photographer, publisher, singer, or writer. The copyright holder (that is, the author of a work) holds the exclusive right, according to the copyright law, to do the following: ✦ Reproduce the work ✦ Create derivative works based on the original ✦ Display the work in public ✦ Perform the work in public ✦ Distribute and sell copies of the original work These rights must be specifically assigned, in writing, to you before you can duplicate a copyrighted image, sound, or text passage in any interactive media production. A copyright notice is not required to assert the author’s legal rights to original material. It is prudent, however, to always include a notice of copyright, for example: Copyright © 2000 by Robert Martin, John R. Nyquist, and IDG Books, Inc. All rights reserved. Ownership or possession of a work (book, fine-art painting, limited-edition print, magazine, manuscript, photograph, sound recording, or video recording) does not give you permission to copy an item. If you purchase a limited-edition print, for example, you do not have the right to scan the image and place it in an interactive media project. If you purchase a book from a bookstore, you do not have the right to use images and text in a multimedia project. In both cases, you must seek permission from the copyright holder.
What can be protected by copyright? Works that can be copyrighted include: ✦ Architectural drawings (blueprints, schematics) ✦ Audiovisual works (films, videotapes, DVDs) ✦ Dramatic works (pantomimes, musicals, plays, screenplays) ✦ Graphic images (cartoons, drawings, maps, paintings, photographs)
415
3486-6 ch10.f.qc
416
7/24/00
5:47 PM
Page 416
Part II ✦ Bringing It All Together
✦ Literature (articles, novels, poems, reports, short stories) ✦ Multimedia works (computer games, choreographic works, other products based on mixed-media types) ✦ Music and lyrics ✦ Publications (books, journals, magazines) ✦ Sound recordings (cassette tapes, compact discs, phonograph records) As a general rule publications written by United States government agencies cannot be copyrighted and therefore are considered to be in the public domain; you can use these works without seeking copyright permission. This group does not include works belonging to the U.S. Postal Service, however. The Postal Service is an incorporated business, and as such it is entitled to copyright protection for the designs of its postage stamps. Caution
Be extremely careful that you have not consciously or inadvertently included any information in your interactive media project that is the property of some other copyright holder. Obtain the required permissions if you want to use excerpts from textbooks, newspaper or magazine articles, material from other multimedia works, photographs, graphics, or other forms of media. The same restrictions and obligations that govern the use of print materials also apply in multimedia.
Copyright protection under U.S. copyright law is for a limited period, based on when the work was created. One of the following two formulas apply when determining the life of a copyright: ✦ If the work was created on or after January 1, 1978, it is protected from the moment of its creation until 50 years after the author’s death. ✦ If the work was created prior to January 1, 1978, the life of the copyright is 28 years, and the author has the option to renew the copyright for an additional 47 years. Therefore, the maximum life span of the copyright is 75 years. Note
These are general guidelines to creating copyrighted material. Before publishing any copyrighted material, you should consult a qualified copyright attorney.
Fair use for educational purposes Many colleges and universities have departments that produce multimedia classroom materials for instructional purposes. In this regard, the following information describes guidelines for fair use of copyrighted materials in such productions. The fair use provision of the Copyrights Act is found in Section 107. It states that the use of copyrighted materials for “criticism, comment, news reporting, teaching (including multiple copies for classroom use), scholarship, or research, is not an infringement of copyright.” This provision was established at a time when the newest medium for copyrighted materials was the phonograph record. Further, the
3486-6 ch10.f.qc
7/24/00
5:47 PM
Page 417
Chapter 10 ✦ Designing a Production Process
law predates the introduction of personal computer applications, including multimedia. Still, legal precedence suggests that the fair use doctrine (as a means whereby copyrighted works may be used for noncommercial, not-for-profit educational purposes) also applies to multimedia applications. As we stated previously, these are general guidelines. If you have any concerns about the content that you intend to use, consult a qualified copyright attorney. Caution
If you intend to sell your work, read no further. Fair use guidelines do not apply to your application!
Although few written standards exist to cover the fair use of copyrighted nonprint media, most legal experts and students of copyright suggest that when you use materials to prepare multimedia courseware for instruction or classroom presentations, you should apply the same criteria as prescribed for the fair use of copyrighted print materials. The criteria include these characteristics: ✦ Spontaneity: The decision to use copyrighted material must be a spontaneous decision. For example, an instructor cannot use the same copyrighted material spontaneously for several semesters. The decision to use the material must be the instructor’s, and the decision must not be dictated by management or administration (as a cost-saving measure, for instance). ✦ Brevity: When discussing print media, guidelines are very specific, even to the point of specifying the maximum length of an excerpt from poetry or prose. The clear intent is to limit the use of copyrighted material to a small portion of the original work. ✦ Cumulative Effect: The fair use doctrine limits the copying or use of the copyrighted work in order to preserve the commercial or monetary value of the work to the author. Guidelines for copying print media limit the amount of information that can be used, based on the fair use doctrine. For instance, the law restricts the educator from copying more than one short poem, article, story, or essay from the same author, or two excerpts from the same author in the same collective work or periodical. The limitation applies to using the material during any one class term. There are different considerations for integrated media; in principle, however, the cumulative effect of any copying should not diminish the financial viability or rewards to the author. As a developer, you can only claim fair use if the use of copyrighted material meets all three tests (spontaneity, brevity, and cumulative effect). In all other cases, you must obtain a copyright release for the materials that you use. The strongest argument for fair use involves use of the material in these activities: ✦ The noncommercial use of copyrighted material for instructional purposes ✦ “Scholarly pursuits” (research and literary criticism) ✦ Copying modest portions of the copyrighted work for educational use
417
3486-6 ch10.f.qc
418
7/24/00
5:47 PM
Page 418
Part II ✦ Bringing It All Together
Copyright concerns for the developer First, when working with material that you have not personally created, maintain a record of each item used in your project. Include the following information: ✦ The source of the asset (name of the book, magazine, publication, video, and so on) ✦ The author’s name (artist, writer, cartoonist, illustrator, photographer, and so forth) ✦ The copyright holder and any pertinent copyright information (address, phone number, year of copyright notice, and so on) Caution
Be aware that the author of a work may not be the copyright holder. Many authors create “works for hire” that belong to the publisher or to the creator’s employer. Furthermore, the copyright may be held jointly by two or more individuals, in which case permission must be sought from all owners.
Second, as soon as you know you plan to use a copyrighted work, seek permission from the copyright owner. Finally, don’t forget to protect your own creative works. Although not required, it is still wise to include a copyright notice in a prominent location on your work. Tip
Under the Berne Convention, any work you create is automatically protected, even without the addition of the copyright notice. If your work is reproduced inappropriately, however, your legal case is strengthened if the notice appears on your work.
Summary Defining the scope of a project, developing a standard production process, and developing a standard naming convention will go a long way toward ensuring that your Director projects are more creative and will be delivered on time and on budget. Keep the following points in mind before beginning your next Director project: ✦ Use a project analysis form to determine the scope of the project. ✦ Develop detailed storyboards to ensure that everyone involved in the project understands what will be delivered. ✦ Use flow charts to model logic problems and programming issues that can arise in your projects. ✦ Use solid naming conventions and consistent production procedures. ✦ Be aware of copyright issues when using content from other sources. Chapter 11 discusses the fundamentals of programming in Lingo.
✦
✦
✦
3486-6 ch11.f.qc
7/24/00
5:48 PM
Page 421
11 C H A P T E R
Programming Fundamentals
✦
✦
✦
✦
In This Chapter
M
any artists start working with Director and soon learn that the real power lies in Lingo. They might complete the Lingo tutorials provided with the program, but it still doesn’t click for them because they haven’t had any programming experience. The problem lies in understanding the very fundamentals of programming. This chapter teaches you some programming basics. If you’ve never programmed before, this is the chapter for you. If you’ve done some programming in other languages, you might want to skim through this chapter, because it will give you a good idea of how Lingo works compared to languages with which you may be familiar. You might be surprised at some of the things that Lingo can do!
Using the Message Window The Message window is very useful for testing small bits of code, debugging, and, in this case, teaching (see Figure 11-1). You’ll want it open for the rest of this chapter, so choose Window ➪ Message or press Command+M (Ctrl+M for Windows). Figure 11-1: The Message window
In the Message window, you can type a line of code and press the Return key (the carriage return, not the Enter key on the keypad), and the code executes. You can do this while a
Learning programming fundamentals with Lingo Director’s four script types Explanations of events, messages, and handlers
✦
✦
✦
✦
3486-6 ch11.f.qc
422
7/24/00
5:48 PM
Page 422
Part III ✦ Learning to Program with Lingo
movie is running or stopped. Also, you can output information to the Message window with the put command. The put command places strings or numbers into the Message window. When you have a great deal of information being output to the Message window, it can affect the performance of the movie. Although the Message window is available during the movie-creation process in Director, it does not appear in Shockwave or a projector. If you leave put commands in your code when you make a projector or Shockwave movie, it does not affect your movie’s performance or cause errors.
Variables A variable is a means of storing data. It is like a box that can hold one item at a time. A variable is the name of the storage location (the box). Whenever you use that name, you get the value of the data at that location (whatever is in the box). The data referenced by a variable is changeable throughout the life of the variable. As soon as you assign another value to the variable, the prior value is gone. Type the following in the Message window and press Return at the end of the line: set myNumber to 10
Then type this command: put myNumber
Once again, press Return at the end of the line. -- 10
As soon as you press Return, -- 10 appears. Pressing the Return key in the Message window makes Director execute that line of Lingo, even when the movie is not playing. Typing put myNumber executes that line of code. The put command displays the value of the variable myNumber in the Message window. At that point in time, myNumber was holding the number 10. Now type the following: set myNumber to “Hello” put myNumber
Don’t forget to press the Return key after each line! After you type the second line and press Return, you get the following: -- “Hello”
You’ve changed the contents of the variable from the number 10 to the word “Hello.” Of course, now the variable name doesn’t make too much sense, but you learn about appropriate variable names a little later in this chapter.
3486-6 ch11.f.qc
7/24/00
5:48 PM
Page 423
Chapter 11 ✦ Programming Fundamentals
Commenting your code You might be wondering why two hyphens appear before the value of the variable after you put it to the Message window. In Lingo, a double-hyphen indicates a comment. A comment is code that is not executed. In other words, it does not do anything. For example, type the following: -- put myNumber After you press Return, no value appears in the Message window as it did in the preceding exercise. Director knows that a line beginning with two hyphens is a comment and ignores it. Comments are a useful way to make your code more understandable to yourself and others. You can also put comments on the same line as executable code. The code before the comment executes, unaffected by the comment that follows it: put myNumber -- nothing after two hyphens gets executed
If you’ve been working along while reading this section, your Message window should look like Figure 11-2. Figure 11-2: How your Message window should look
Creating variables In some programming languages, you need to declare a variable before you can initialize it (initialize means to give it a value). In Lingo, a variable is created as soon as you use it. So, when you type a line of code like the following: set myName to “John”
You’ve created the variable myName. You could have written it this way as well: set myName = “John”
Or even like this: myName = “John”
423
3486-6 ch11.f.qc
424
7/24/00
5:48 PM
Page 424
Part III ✦ Learning to Program with Lingo
In the preceding two code samples, the equal sign ( = ) is not an equal sign but an assignment operator. The preceding example uses syntax first introduced in Director 7. It is more concise, but perhaps less readable, for the beginner than the older syntax, which uses the set keyword. In this book, we address both old and new syntax.
Naming variables A variable name can include up to 256 characters. A good variable name, however, shouldn’t be so long as to be cumbersome. It has to start with a letter (from a–z) or an underscore ( _ ), and can be upper- or lowercase. After that, you can have numbers in the name. Variable names are only one word, so you can’t have spaces in the name.
Legal variable names Here are some variable names that do not cause a syntax error: MyVariable some_stuff _stillValidName aaa
Illegal variable names These variable names cause errors: 2bad No Good stillbad?
-- can’t start with a number -- spaces aren’t allowed -- can’t use the ? character
It is good to give variables meaningful names, because the name of the variable should give you an idea of the value it holds. You might be tempted to give it a meaningless name if you are in a rush or not feeling very creative. Don’t do it! Although aaa is a legal name, it won’t make sense to you a week from now. It’ll be even worse for someone else trying to figure out your code.
Variable case In some programming languages, the case of a variable is important. This is not true in Lingo. The variable name MYNAME is considered the same variable as myName. In the Message window, type the following: set myVariable to “This is my variable, I’d know it anywhere.” put MYVARIABLE -- “This is my variable, I’d know it anywhere.”
3486-6 ch11.f.qc
7/24/00
5:48 PM
Page 425
Chapter 11 ✦ Programming Fundamentals
Types of variables A variable in Lingo can hold data of different types: basic data, symbols, lists, and objects.
Basic types In programming languages, different kinds of data are said to be of different types. Text is different from numbers, so they are considered different types of data. Numbers can be either integers or floats (decimal point numbers). Text is called a string. If you visualize a piece of text as a bunch of individual letters strung together, the term string should make more sense to you. Table 11-1 shows some common data types, as well as examples of each.
Table 11-1 Common Data Types in Lingo Data Type
Examples
Integer
1, –34, 10000022334
Float
–0.124, 1.5, 30000.1
String
“Hello”, “a”, “Now is the time”
Symbols
#hello, #x1, #abc_def
Lists
[1, 2, 3], [“abc”, 1.2, 34], [#name: “John”, #age: 33]
Objects
Any variable in Lingo can hold any of the types available in Lingo, regardless of the type it currently holds. If one moment a variable is holding a string and a little later you decide to stick an integer in there, Lingo doesn’t complain.
Symbols Integers, floats, and strings are obvious data types, but what is a symbol? Computers deal with numbers much more quickly than strings. Sometimes you want the speed of a number and the descriptiveness of a string. Symbols are Lingo’s way of satisfying this need. Symbol names have the same rules as variables, but they must begin with a pound sign (#). They are not case sensitive. In the Message window, type the following: mySymbolVar = #name put mySymbolVar -- #name
425
3486-6 ch11.f.qc
426
7/24/00
5:48 PM
Page 426
Part III ✦ Learning to Program with Lingo
Lists Most data types consist of one element. Sometimes, however, you might want to have a variable hold more than one item. Because variables hold only one thing at a time, you need a data type that can hold more than one item. For circumstances like these, you can use lists. We cover lists in more detail in Chapter 12, but for now you just need to know that they are a collection of elements contained within brackets, and that they come in two varieties: linear and property. The elements can be the same type or different types. Type the following in the Message window: set myLinearList to [“abc”, 1.2, 34] set myPropertyList to [#name: “Rob”, #age: 40]
Objects Objects can combine data and functionality. Objects hold their data in variables called properties. The functionality comes from handlers defined for each class of object. We cover objects in detail in Chapter 13.
Expressions Expressions are chunks of code that result in a value. They exist within statements. An expression might be a single variable or it might be a formula. Following are examples of expressions: 1 + 1 power(3, 2) + power(4, 2) - 2 * 3 * 4 * cos(1) myVar
They are valid expressions, but they are not valid statements. If you type any of these in the Message window, you get a syntax error as soon as you press Return.
Statements A statement is one executable line of Lingo code. A line of code is terminated by a carriage return (the Return key). To make the preceding example expressions into statements, you can adjust the code, as shown here: set mySum to 1 + 1 myAng = power(3, 2) + power(4, 2) - 2 * 3 * 4 * cos(1) myVar = 101
3486-6 ch11.f.qc
7/24/00
5:48 PM
Page 427
Chapter 11 ✦ Programming Fundamentals
You get no syntax errors when you type these in the Message window! These are statements because they are an executable line of Lingo (in fact, we are executing it in the Message window). 1 + 1 is an expression in the set mySum to 1 + 1 statement.
Operators An operator is a symbol or word that acts, or “operates,” on one or more elements. Operators are part of the Lingo programming language and are used for calculations, assignment, and comparison.
Assignment operator The equal sign (=) functions as a comparison operator and as an assignment operator. When you want to assign a value to a variable, you can do it four different ways: set myNumber to 10 set myNumber = 10 put 10 into myNumber myNumber = 10
If you’ve used versions of Director before 7.0, the first three should be familiar to you (unless you were avoiding Lingo). The last line, myNumber = 10, means the same thing. The value on the right side of the assignment operator is placed into the variable on the left side. In other words, it is assigned to that variable. For example, type in the following: myNumber = 2 + 2
Now myNumber holds 4. 2 + 2 is evaluated to 4, and then that value is assigned to the variable. All operations to the right of the assignment operator are carried out first.
Arithmetic operators For doing simple arithmetic calculations in Lingo, you use the +, -, *, and / operators for addition, subtraction, multiplication, and division, respectively. If all the operands are integers, the result is an integer, including division! All arithmetic operations in Lingo that contain a float result in a float. Note
An operand is the object of an operation. If you are adding 1 + 2, the operands are 1 and 2, with the addition operator in between.
427
3486-6 ch11.f.qc
428
7/24/00
5:48 PM
Page 428
Part III ✦ Learning to Program with Lingo
Addition Addition uses the + operator. It requires an operand on each side of the operator. The put command executes on the result of the addition, putting it to the Message window. put 5 + 3 -- 8 put 5.0 + 3 -- 8.0000
Lingo even enables you to use numbers that are strings in your calculation, as follows: put “5” + 3 -- 8.0000 put “5” + “3” -- 8.0000
Note that when you add two strings, the result is a float, not a string.
Subtraction Subtraction uses the – operator. It requires an operand on each side of the operator. Again, the put command executes on the result of the subtraction, putting it to the Message window. put 5 - 3 -- 2 put 5.0 - 3 -- 2.0000 put “5” - 3 -- 2.0000
Multiplication Multiplication uses the * operator and works like the other operators: put 5 * 3 -- 15 put 5.0 * 3 -- 15.0000 put “5” * 3 -- 15.0000
3486-6 ch11.f.qc
7/24/00
5:48 PM
Page 429
Chapter 11 ✦ Programming Fundamentals
Division Division uses the / operator. But there is more to division in Lingo than meets the eye. Look at the following example, 5/3: The result, --1, is not the one that first comes to mind. put 5/3 -- 1
Anytime all of the operands are integers, the result is an integer. In the preceding example, 3 goes into 5 only one time, so the answer is 1. Now look at this example: put 5.0/3 -- 1.6667
After changing at least one of the numbers to a float, you get the result you were probably expecting: 1.6667. You can also use strings. The result is a float even when both operands are strings: put “5”/3 -- 1.6667 put “5”/”3” -- 1.6667
If your expression has a variable in it, the variable is evaluated first and then the calculation is performed: x = 5
-- you could also write set x to 5, set x = 5, -- or put 5 into x put x - 2 -- 3 y = 2 put x - y -- 3
You can have multiple operators in any arithmetic expression: put 1 + 2 + 3 -- 6 put 1 + 2 - 3 -- 0
429
3486-6 ch11.f.qc
430
7/24/00
5:48 PM
Page 430
Part III ✦ Learning to Program with Lingo
Modulo The mod operator (short for “modulo”) divides the dividend by the divisor and returns the remainder of that operation: put 10 mod 3 -- 1 put 19 mod 5 -- 4
It’s like doing integer division, but the result is the remainder. For example, 3 goes into 10 three times with 1 left over. put 10/3 -- integer division -- 3 put 10 mod 3 -- 1
Modulo works only with integer expressions. If an expression evaluates to a float, it is treated as an integer for the mod operator, as follows: put 5.3 mod 3 -- 2 put 5.9 mod 3 -- 0
Lingo rounds the 5.9 automatically to 6. The remainder of 6 divided by 3 is 0. This operator does not work with strings: put “5” mod 3 -- 0
Mod is handy when you want to determine whether a number is even or odd. Even numbers divided by 2 have no remainder, so you know when a number is odd: put 6 mod 2 -- 0 put 7 mod 2 -- 1 put 8 mod 2 -- 0
Negation Most operators we’ve covered so far are binary operators. Binary operators have two operands. Unary operators have only one operand. The negation operator, -,
3486-6 ch11.f.qc
7/24/00
5:48 PM
Page 431
Chapter 11 ✦ Programming Fundamentals
is unary. Putting the negation operator in front of an expression makes a positive expression negative and a negative expression positive: - 2 + 3 -- the result is 1 - 3 + 2 -- the result is -1
Again, you can use parentheses to make it clearer: (-3) + 2 ((-3) * 8)/2
-- the result is -1 -- the result is -12
Parentheses and precedence Arithmetic operators have an order of precedence similar to algebra. Multiplication has a higher precedence than addition: put 7 + 3 * 2 -- 13
In the preceding example, 3 * 2 is evaluated first, and then 7 is added to produce the result of 13. You can use parentheses to make your code clearer, even when you do not functionally need them: 7 + 3 * 2 7 + (3 * 2) -- this is more easily read as 13
If you want the addition to be evaluated first, you can put parentheses around it, as you would do in math. Expressions in parentheses are evaluated first: put (3 + 2) * 7 -- 35
In cases where the precedence of the operators is equal, the expression is then evaluated from right to left: put 2.0 * 5 / 4 -- 2.5
Comparison operators Comparison operators are also called predicates. Predicates are operators that return true or false. In Lingo, a value of 1 is considered true, and a value of 0 is considered false. These operators work the same way in algebra; the only one that might look unfamiliar is the Lingo version of “not equal to.” Table 11-2 lists the comparison operators.
431
3486-6 ch11.f.qc
432
7/24/00
5:48 PM
Page 432
Part III ✦ Learning to Program with Lingo
Table 11-2 Comparison Operators Operator
Name
=
Equals
>
Greater than
=
Greater than or equal to
4 >= 5 4 = 5.0
The result of the comparison operators is a Boolean value. A Boolean value is either true or false (1 or 0). These comparison operators work nicely with strings. You can use the less-than and greater-than signs to find out what is less, in terms of alphabetical order: put “John” = “JOHN” -- 1 put “John N” > “John” -- 1 put “a” > “b” -- 0 put “a” < “b” -- 1
3486-6 ch11.f.qc
7/24/00
5:48 PM
Page 433
Chapter 11 ✦ Programming Fundamentals
put “A” = “a” -- 1 “A” = “a” because Lingo is NOT case sensitive.
Logical operators Logical operators are operators whose operands are Boolean values, and the result is a Boolean value. A Boolean value is a value that is true or false. In Lingo, any positive or negative integer is true, and zero is false. A Boolean result is either 1 for true or 0 for false.
AND and OR AND produces a true result only if both operands are true: put 1 AND 1 -- 1 put (5 > 4) AND (5 = 5) -- 1 AND produces a false result if one or both of the operands is false: put 1 AND 0 -- 0 put 0 AND 0 -- 0 put (5 > 4) AND (5 = 4) -- 0 OR produces a true result if either of the operands is true: put 1 OR 0 -- 1 put (5 > 4) OR (5 = 4) -- 1 OR produces a false result if both operands are false: put 0 OR 0 -- 0
not If you have a single operand and you want the opposite true value, you can use the not function, as follows: put not 1 -- 0
433
3486-6 ch11.f.qc
434
7/24/00
5:48 PM
Page 434
Part III ✦ Learning to Program with Lingo
put not 0 -- 1
Lingo also has the constants TRUE and FALSE. These constants evaluate to the integer values 1 and 0, respectively. If you prefer, you can use them in your code instead of 1 or 0, to make it more readable: put TRUE -- 1 put not TRUE -- 0 put FALSE -- 0
Lingo is not case sensitive, so typing true and false in lowercase letters works as well. As stylistic convention, however, Lingo constants such as TRUE and FALSE are in all uppercase letters.
Concatenation operators Concatenation is putting together two strings. There are two concatenation operators in Lingo, && and &. The first, &&, adds a space when you put the strings together, as shown here: put “Laura” && “Lynn” -- “Laura Lynn” put “20” & “00” -- “2000”
You can put several strings together: put “May” && “28,” && “20” & “00” -- “May 28, 2000”
Numbers are automatically converted to strings: put “$19.” & 99 -- “$19.99” put 20 & “01” -- “2001”
Of course, it’s okay to use variables as well: set myName to “John” put myName && “Nyquist” -- “John Nyquist”
3486-6 ch11.f.qc
7/24/00
5:48 PM
Page 435
Chapter 11 ✦ Programming Fundamentals
Handlers A handler is a way of grouping together several Lingo statements to perform a single task. Lingo has many built-in handlers, such as on mouseUp, but you can also create your own custom handlers. Suppose that you want to make the sprites in the first three channels invisible. In the Message window, type the following commands: set the visible of sprite 1 to FALSE set the visible of sprite 2 to FALSE set the visible of sprite 3 to FALSE
Note: You can also use dot syntax. The following three statements achieve the same result as the preceding three statements: sprite(1).visible = FALSE sprite(2).visible = FALSE sprite(3).visible = FALSE
This is a long way to go about setting three sprites to be invisible. If you had to do this many times in a program, using handlers could save you time.
Creating a Handler 1. Open a new Script window by pressing Command+0 (zero) for Macintosh users or Ctrl+0 (zero) for Windows users. 2. Click the Cast Member Properties button to open the Script tab of the Property Inspector (see Figure 11-3). Figure 11-3: The Script Cast Member Properties tab
435
3486-6 ch11.f.qc
436
7/24/00
5:48 PM
Page 436
Part III ✦ Learning to Program with Lingo
3. Type MakeInvisible into the editable field. 4. Make sure that the Type pop-up menu is Movie. If it isn’t, select Movie. 5. Click OK. 6. In the Script window, type these lines: on MakeInvisible set the visible of sprite 1 to FALSE set the visible of sprite 2 to FALSE set the visible of sprite 3 to FALSE end
7. Click the Recompile All Scripts button. Tip
A handler definition always starts with the word on, followed by the name of the handler (and any parameters), and then the statements it executes. It ends with the word end.
The MakeInvisible term did not exist in Lingo until you created it. When you type MakeInvisible, Lingo executes each of the statements in the handler. It does so one line at a time, from top to bottom. Now, every time you call MakeInvisible, the sprites in the first three channels become invisible. Try it: Put three sprites on the Stage, and then in the Message window type: MakeInvisible
Parameters and arguments You can make this handler more useful by adding a parameter to it. Parameters are variables that can be used by the statements in the handler. First, rename the handler from MakeInvisible to MakeVisible. This is an easier to understand name, given the functionality that you’re going to add. Doesn’t it sound more sensible to say, “It is true you want to make those sprites visible” rather than “It is false that I want those sprites invisible”? Make the following changes: on MakeVisible bool set the visible of sprite 1 to bool set the visible of sprite 2 to bool set the visible of sprite 3 to bool end
3486-6 ch11.f.qc
7/24/00
5:48 PM
Page 437
Chapter 11 ✦ Programming Fundamentals
Now you’ve added a parameter to the handler -- bool. Click the Recompile All Scripts button. In the Message window, type the following: MakeVisible TRUE
Using the name of a handler in a line of code is referred to as calling the handler. When Lingo executes MakeInvisible, it looks up how the handler is defined. When you call the MakeInvisible handler, it takes the argument TRUE and puts that value into the bool parameter. Arguments are the values you pass on to parameters. Now, if you want to make the sprites visible again, you can type the following in the Message window: MakeVisible FALSE
Functions A special type of handler is called a function. A function is a handler that returns a value. Create a new movie script or add the following handler to the same Script window as MakeInvisible: on CalcVolume set x to 10 set y to 20 set z to 5 set volume to x * y * z put volume end
Click the Recompile All Scripts button. This handler is almost useful at this point. The problem is that it puts the result of the calculation into the Message window, where it cannot be used in further calculations. It needs to be made into a function. Change the put volume statement to return volume: on CalcVolume set x to 10 set y to 20 set z to 5 set volume to x * y * z return volume end
437
3486-6 ch11.f.qc
438
7/24/00
5:48 PM
Page 438
Part III ✦ Learning to Program with Lingo
The return command is an important one. It breaks out of the function and returns a value to the place from where the function was called. If there were any lines of code after return volume, those lines would never execute. In the Message window, type the following code: put CalcVolume() -- 1000
You need the put statement in the Message window because the CalcVolume() function is an expression — it evaluates to a single value. When you call a function, you need to put parentheses after it, which lets Lingo know it is getting a value back. If you forget the parentheses, the return value is : put CalcVolume – whoops, forgot the parentheses --
This handler can be made more useful by adding parameters to it. Change the CalcVolume handler to the following: on CalcVolume x, y, z set volume to x * y * z return volume end
In the Message window, type the following: put CalcVolume(10, 20, 5) -- 1000
You can even perform arithmetic operations on the results of two functions, as follows: put CalcVolume(10, 20, 5) + CalcVolume(5, 7, 10) -- 1350
Control Structures Control structures enable you to alter the flow of the program. Until now, the flow of the program has been from the top statement to the bottom statement without skipping any statements and doing each statement only once. Here you learn to add decision-making capability to your code with if and case structures. You also learn how to do the same thing repeatedly with repeat loops. There are many flavors of each, and the differences can be subtle when just reading, so make sure you work through the examples on a computer. As you become more familiar with them, the subtleties become obvious.
3486-6 ch11.f.qc
7/24/00
5:48 PM
Page 439
Chapter 11 ✦ Programming Fundamentals
if structures There is more to coding than just statements — there are decisions to be made! Statements execute one right after the other, but decision structures enable you to skip over statements, based on conditions you define.
if . . . then The if...then structure enables you to make logic that executes when a certain condition exists. Here’s the syntax for an if...then statement: if integerExpression then statement(s) end if
The words in italics mean you need to replace those words with your own code; integerExpression is any expression that evaluates to an integer. If that value is 0, then the statements between the if and end if do not execute. statement(s) is one or more valid Lingo statements. Note
If you try to use something that evaluates to another type, such as a float or string, you get a syntax error.
Lingo also enables you to write if structures with a single statement. Note that the end if is not needed (it is needed when the statement is on the line following the condition, as in the preceding example): if integerExpression then statement Tip
We tend to usually write it the first way (multiple lines), even for single statements. This visually separates the condition from the statements, making it easier to understand what is going on. It also makes it faster to add more statements. Also, there are times when the single-line format does not execute reliably. This bug has been documented in previous versions of Lingo. When you suspect this may be the case, try changing the if statement to multiple line format and see if the behavior changes.
Type the following in a movie Script window: on TestTrue bool if bool = TRUE then myAns = “It’s the truth” end if if bool = FALSE then myAns = “It’s a lie” end if return myAns end
439
3486-6 ch11.f.qc
440
7/24/00
5:48 PM
Page 440
Part III ✦ Learning to Program with Lingo
If you refer to the syntax for an if...then, you’ll notice that integerExpression in TestTrue() is the result of the equal sign acting as a comparison operator. We are testing whether the variable bool holds a 1 (remember, TRUE is the same as 1) or a 0 (FALSE is the same as 0). In real code, statement(s) is replaced by an actual statement, myAns = “It’s the truth”. Here is TestTrue() in the single-line if format: on TestTrue bool if bool = TRUE then myAns = “It’s the truth” if bool = FALSE then myAns = “It’s a lie” return myAns end
When you have multiple statements to execute based on a condition, write the if structure in the following format: on TestTrue bool if bool = TRUE then set the visible of sprite 1 to TRUE myAns = “It’s the truth” end if if bool = FALSE then myAns = “It’s a lie” end if return myAns end
Click the Recompile All Scripts button. In the Message window, try it out: put TestTrue(TRUE) -- “It’s the truth” put TestTrue(FALSE) -- “It’s a lie”
if . . . else if When you have either-or decisions, use the if...else if structure, as follows: if integerExpression then statement(s) else if statement(s) end if
As in the case with if...then structures, Lingo also enables you to write if...else if structures with a single statement. The end if is not needed (it is, however, needed when the statement is on the line following the condition, as in the preceding example): if integerExpression then statement else if statement
3486-6 ch11.f.qc
7/24/00
5:48 PM
Page 441
Chapter 11 ✦ Programming Fundamentals
You can have as many else if statements as you need: if integerExpression then statement(s) else if statements(s) else if statements(s) end if
You can optimize the TestTrue() function by using the if...else if structure: on TestTrue bool if bool = TRUE then myAns = “It’s the truth” else if bool = FALSE then myAns = “It’s a lie” end if return myAns end
The difference here is if bool turns out to be TRUE, then the test for FALSE is never executed.
if . . . else What if bool is neither true nor false? What if you passed in a string by mistake? Then you can add a catch-all statement at the end with one last else (not an else if), as in the following: if integerExpression then statement(s) else statements(s) end if
If integerExpression is not true, then the else statement(s) executes. You can also put one or more else if statements between the if and the else. You can have many else if statements, but only one else: if integerExpression then statement(s) else if integerExpression then statements(s) else statement(s) end if
441
3486-6 ch11.f.qc
442
7/24/00
5:48 PM
Page 442
Part III ✦ Learning to Program with Lingo
As in the case with if...then structures, Lingo also enables you to write if...else if structures with a single statement. The end if is not needed (it is needed, however, when the statement is on the line following the condition, as in the preceding example): if integerExpression then statement else statements if integerExpression then statement else if integerExpression then statement else statement
Here is TestTrue() with an else statement added: on TestTrue bool if bool = TRUE then myAns = “It’s the truth” else if bool = FALSE then myAns = “It’s a lie” else myAns = “I’m not really sure on this one” end if return myAns end
Click the Recompile All Scripts button and try it in the Message window: put TestTrue(“hi”) -- “I’m not really sure on this one”
Nesting ifs Sometimes you need a condition tested within a condition. In the following example, a logical or is used to make sure the bool parameter holds a TRUE or FALSE value, as opposed to some other type, such as a string, symbol, list, or object: on TestTrue bool if (bool = TRUE) or (bool = FALSE) then if bool = TRUE then myAns = “It’s the truth” else if bool = FALSE then myAns = “It’s a lie” end if else myAns = “I’m not really sure on this one” end if return myAns end
3486-6 ch11.f.qc
7/24/00
5:48 PM
Page 443
Chapter 11 ✦ Programming Fundamentals
case statements Another branching structure is the case statement. Like the if...then structures, you can write the case statement many different ways. Often your decision to use case or if is based on which structure you are more comfortable with. Here is the syntax you can use that is like an if...then structure: case (expression) of expression: statement(s) end case case (expression) of expression: statement end case
Like an if...else if structure: case (expression) of expression: statement expression: statement end case case (expression) of expression: statement(s) expression: statement(s) end case
Or like an if...else structure: case (expression) of expression: statement(s) otherwise statement(s) end case case (expression) of expression: statement(s) expression: statement(s) otherwise statement(s) end case
443
3486-6 ch11.f.qc
444
7/24/00
5:48 PM
Page 444
Part III ✦ Learning to Program with Lingo
case (expression) of expression: statement otherwise statement end case case (expression) of expression: statement expression: statement otherwise statement end case
It is optional to put a colon after otherwise. It works either way. Now change the TestTrue() function to use a case statement instead of an if else, as shown here: on TestTrue bool case (bool) of TRUE: myAns = “It’s the truth” FALSE: myAns = “It’s a lie” otherwise myAns = “I’m not really sure on this one” end case return myAns end
Iteration Iteration statements enable a program to do something repeatedly until some condition is met. Iteration is often referred to as looping. There are four different ways to create loops in Lingo: ✦ repeat while ✦ repeat with . . . to ✦ repeat with . . . down to ✦ repeat with . . . in
repeat while The repeat while structure has this format: repeat while integerExpression statement(s) end repeat
3486-6 ch11.f.qc
7/24/00
5:48 PM
Page 445
Chapter 11 ✦ Programming Fundamentals
integerExpression is any expression that evaluates to an integer. If that value is 0, then the statements following it do not execute. If you try to use something that evaluates to another type, like a float or string, you get a syntax error. In the code, statement(s) is one or more valid Lingo statements.
In a Movie script, type the following: on FunWithLoops counter = 0 repeat while mouseUp() put counter counter = counter + 1 end repeat put “Done looping.” end
Click the Recompile All Scripts button, and then type the following code in the Message window: FunWithLoops
This handler continues to execute while the mouse button is up. Click the mouse to have it stop. See the sidebar “mouseUp( ), the mouseUp, and on mouseUp” for more information on the mouseUp() function used in this handler. Change the handler to this: on FunWithLoops counter = 0 repeat while counter < 10 put counter counter = counter + 1 end repeat put “Done looping.” end
The expression counter < 10 uses a comparison operator. Comparison operators always have a result of 1 or 0 (true or false). The repeat loop continues executing the statements while the variable counter is less than 10; after it hits 10, the expression counter < 10 is no longer true and the loop ends, and the rest of the handler is executed.
repeat with . . . to Another way to repeat something a finite number of times is to use the repeat with...to structure, which is: repeat with variable = intExpression to largerIntExpression statement(s) end repeat
445
3486-6 ch11.f.qc
446
7/24/00
5:48 PM
Page 446
Part III ✦ Learning to Program with Lingo
mouseUp( ), the mouseUp, and on mouseUp Did you realize that mouseUp() in the first FunWithLoops handler is a function, because of the “( )” after it? It’s not a user-defined function, but a function that is part of the Lingo language. It detects whether the mouse button is currently up and returns 1 (true) or 0 (false). You can also use the syntax the mouseUp, which is the way it was done in earlier versions of Director. Back then, you could find it referred to as a system property or a function. In the past, a Lingo expression that started with a “the” was often referring to a property of some sort and would evaluate to that property’s value. Because it evaluated a value, you might think it would be called a function, but because it was evaluating to a property of a movie, sprite, and so on, it probably seemed more straightforward to refer to it as the property itself, as opposed to a function that returned that property. Whether it is the property or evaluates to the value of the property, you can use either form for the same result, as in the following: put mouseUp() -- 1 put the mouseUp -- 1 Don’t confuse either with the on mouseUp event handler, which captures the message (handles it) of the mouse button being released. When a user releases the mouse button after it has been held down, that is called an event, and then that message (“Hey everybody! There’s been a mouseUp!”) is sent through the movie. We discuss events a little later in the chapter, but you can peek ahead at Figure 11-8 if you want to see a diagram of a mouseUp event). The same can be said for mouseDown(), the mouseDown, and on mouseDown.
Change the FunWithLoops handler to: on FunWithLoops repeat with counter = 0 to 9 put counter end repeat put “Done looping.” end
We can make it a more flexible handler by adding some parameters, as shown here: on FunWithLoops start, finish -- if start is GREATER than finish, it’ll skip the repeat repeat with counter = start to finish put counter end repeat put “Done looping.” end
3486-6 ch11.f.qc
7/24/00
5:48 PM
Page 447
Chapter 11 ✦ Programming Fundamentals
repeat with . . . down to If you need to count backward, you can use the repeat with...down to structure: repeat with var = intExpression down to smallerIntExpression statement(s) end repeat on FunWithLoops start, finish -- if start is LESS than finish, it’ll skip the repeat repeat with counter = start down to finish put counter end repeat put “Done looping.” end
repeat with . . . in When you need to go through a list of items, you can use the repeat with...in structure, as follows: repeat with variable in aList statement(s) end repeat on FunWithLoops set aList to [1, 5, “hey”, 2.65, 6] repeat with anItem in aList put anItem end repeat put “Done looping.” end
The repeat with...in structure is only used with lists and objects. This structure repeats the loop as many times as there are elements in the list. It automatically puts the next element into the variable anItem. Of course, we can improve this handler, too, by adding a parameter: on FunWithLoops aList repeat with anItem in aList put anItem end repeat put “Done looping.” end
Now call the revised FunWithLoops from the Message window and pass in a list, as shown here: FunWithLoops [1,2,3] -- 1 -- 2
447
3486-6 ch11.f.qc
448
7/24/00
5:48 PM
Page 448
Part III ✦ Learning to Program with Lingo
-- 3 -- “Done looping.”
If you call this version of FunWithLoops and pass in something other than a list, you get a syntax error.
Exiting a loop Another way to write a repeat loop is to use the repeat...while structure with a literal so that it is always true. Of course, the loop would execute infinitely, unless you have a way to break out of it. That’s where the exit repeat command comes in. The exit repeat command does exactly what it says — it exits the repeat. The following is an example: on FunWithLoops -- This loop will count to 10 and then exit. counter = 0 repeat while TRUE put counter if counter > 9 then exit repeat else counter = counter + 1 end if end repeat put “Done looping.” end
Another way to modify the flow of a repeat loop is to use next repeat. Suppose that you only want to count even numbers: on FunWithLoops repeat with i = 1 to 10 if i mod 2 0 then next repeat end if put i && “is even” end repeat put “Done looping.” end
When you call this in the Message window, you’ll get: FunWithLoops -- “2 is even” -- “4 is even” -- “6 is even” -- “8 is even” -- “10 is even” -- “Done looping.”
3486-6 ch11.f.qc
7/24/00
5:48 PM
Page 449
Chapter 11 ✦ Programming Fundamentals
As soon as next repeat is encountered, the loop starts back at the top. None of the statements below it are executed.
Nested repeats You can place repeat loops within each other as well, as this example shows: on FunWithLoops set myList to [[11, 12, 13], [21, 22, 23], [31, 32, 33]] repeat with aList in myList repeat with anItem in aList put anItem end repeat end repeat end
The outer loop goes through the three lists within myList. Each iteration places one of the lists into aList. The inner loop goes through the elements of aList.
MakeVisible revisited The MakeVisible handler mentioned earlier in the chapter can be improved with the use of a repeat loop. This handler used three very similar statements; the only difference between each statement was the number of the sprite whose visibility was being changed. Because those sprites occurred in a sequential order, you can modify the handler as follows: on MakeVisible bool repeat with i = 1 to 3 set the visible of sprite i to bool end repeat end
You can improve this handler further by adding parameters for the first and last sprite. By adding these parameters, you increase the flexibility of the handler dramatically; the handler is no longer limited to just sprites 1 to 3: on MakeVisible bool, firstSpr, lastSpr repeat with i = firstSpr to lastSpr set the visible of sprite i to bool end repeat end
449
3486-6 ch11.f.qc
450
7/24/00
5:48 PM
Page 450
Part III ✦ Learning to Program with Lingo
Creating Different Types of Scripts Director has four types of scripts. In this chapter, you’ve been working with the Movie script. Each script has its own effective domain where it has control. Figure 11-4 shows five scripts because frame scripts and sprite scripts are both behaviors. Figure 11-4: The Cast window showing movie, frame, sprite, cast, and parent scripts.
Movie scripts When handlers were introduced earlier in the chapter, it was in reference to Movie scripts. Handlers in Movie scripts are global in scope, meaning that they can be called from handlers in any of the other types of scripts and the Message window. A way to remember this is to recall that a Director document is called a movie, and that handlers in Movie scripts can be called from anywhere in the movie. Movie scripts can include handlers that are automatically executed when the movie starts, stops, or idles. Movie scripts might also be used to define and initialize global variables for use within your movie, and to store user-defined handlers, such as MakeInvisible, CalcVolume, TestTrue, and FunWithLoops, which you created earlier in this chapter.
Behaviors (Score scripts) A behavior is a script that is attached to sprites or frames in the Score. A behavior is sometimes referred to as a Score script, which refers to where behaviors are applied. Behaviors attached to sprites are called sprite scripts, and behaviors attached to frames via the script channel (the behavior channel) are called frame scripts. A sprite might have more than one behavior (script) attached to it. A frame can have only one behavior attached to it.
3486-6 ch11.f.qc
7/24/00
5:48 PM
Page 451
Chapter 11 ✦ Programming Fundamentals
Whenever you attach a behavior to a sprite from the Library palette, that behavior is added to the cast. When you edit a behavior, that change takes effect in every frame and every sprite to which it is attached.
Behaviors on sprites (sprite scripts) A sprite can have one or more behaviors attached to it. Each behavior can have one or more handlers in it. The handlers can be event handlers that are part of Lingo or they can be user-defined handlers. These handlers are executed when a message is sent to the sprite to which the script is attached. Sending a message to a sprite simply means calling a handler in one of its behaviors. The most common use for a sprite behavior is to perform an action based on a mouse click. If the cast member (from which the sprite was created) also has a script, Director ignores the cast member script unless specific commands are in place in the sprite behavior to pass the event to the cast member script. It’s important to understand what happens when you attach a behavior to a sprite that also has a cast member script. If both scripts have an on mouseUp handler, the behavior intercepts the mouseUp event. The cast member script is not called unless the mouseUp in the behavior has the pass command in it. If there is more than one behavior attached to the sprite, and they all have a mouseUp, all of the mouseUp handlers in the behaviors execute. If you want the cast member script’s on mouseUp to execute as well, all of the mouseUp handlers in the behaviors must contain the pass command. As the next section (“Events and Script Priority”) shows, sprite scripts can receive many events. Every time the playback head moves, every sprite script in that frame of the Score gets an enterFrame, exitFrame, prepareFrame, and idle message. Of course, the sprite does not do anything if an on exitFrame handler was not defined in its behavior. To create a new sprite behavior: 1. Open the Score by choosing Window ➪ Score. 2. Select a sprite. 3. Click the Behavior pop-up menu on the Score window. 4. Choose New Behavior. A Behavior script window opens. You’ve just created a behavior and applied it to the sprite at the same time. Tip
If you close an empty, nameless script window, Director removes that member. If you want to create the member but not write anything at the moment, just give the script cast member a name or type a double-hyphen in the window. Because a double-hyphen is read as a comment, it won’t be executed.
451
3486-6 ch11.f.qc
452
7/24/00
5:48 PM
Page 452
Part III ✦ Learning to Program with Lingo
Another way to create a behavior on a sprite is to Ctrl+click the sprite (right-click for Windows users) and select Script. A third way is to: 1. Select the sprite. 2. Open the Behavior Inspector (choose Window ➪ Inspector ➪ Behavior). 3. Choose New Behavior from the Behavior pop-up menu on the Behavior Inspector. If you want to create a behavior without applying it to a sprite, just do the following: 1. Open a script window by choosing Window ➪ Script. If one is open already, click the New Script button. 2. If it doesn’t say Behavior Script in the title bar, click the Cast Member Properties button and select Behavior from the Type pop-up menu.
Behaviors on frames (frame scripts) A frame script is attached to a specific frame in your Director movie. This type of Score script (behavior) executes when the playback head reads the script channel cell in a specific frame. Although a frame script can receive and act upon most system messages (refer to the later section “Events and Script Priority”), the most common messages handled by a frame script are enterFrame and exitFrame. Frame scripts are created and edited in the Script channel of the Score window. By default, when you create a frame script (by double-clicking an empty frame channel cell), Director inserts the beginning and ending lines for an on exitFrame handler. A typical frame script reads as follows: on exitFrame go to the frame end
This is one of the most common and useful frame scripts. It causes the playback head to go to the current frame (loop) until some other action is invoked (such as clicking a mouse button or pressing a key). Though the go to the frame statement loops through the current frame, it does not redraw the Stage unless objects change between each loop. In other words, Director only refreshes those areas of the Stage that change. Using the go to the frame instruction does not cause a loss in performance as other types of loops do
3486-6 ch11.f.qc
7/24/00
5:48 PM
Page 453
Chapter 11 ✦ Programming Fundamentals
(repeat with and repeat while statements lock out any user interaction until they complete their work. There are several ways to create a frame script. You can: 1. Open the Score by choosing Window ➪ Score. 2. Double-click a cell in the Script channel of the frame on which you want this behavior. Or you can: 1. Open the Score by choosing Window ➪ Score. 2. Select a cell in the Script channel of the frame on which you want this behavior. 3. Click the Behavior pop-up menu in the Score window. 4. Choose New Behavior. A Behavior script window opens. You also can: 1. Open the Score by choosing Window ➪ Score. 2. Ctrl+click (right-click for Windows users) in the Script channel the cell that you want the behavior to be on. 3. Choose Frame Script.
Cast member scripts A cast member script is attached to (stored with) the cast member. A cast member can have only one cast member script attached to it. Cast member scripts are often used to hold on mouseUp and on mouseDown handlers, but they can have userdefined handlers as well. To create a cast member script, do the following: 1. Create a button cast member from the Tool palette (choose Window ➪ Tool Palette if it is not open). 2. Highlight the cast member (choose Window ➪ Cast if it is not open). 3. Click the Cast Member Script button in the Cast window. When you click the Cast Member Script button, the Script window opens (see Figure 11-5). Note that the title bar at the top of the Script window indicates the type of script. By default, when you create a cast member script, Director inserts the beginning and ending lines for an on mouseUp handler.
453
3486-6 ch11.f.qc
454
7/24/00
5:48 PM
Page 454
Part III ✦ Learning to Program with Lingo
Figure 11-5: The Script window, showing a new cast member script
If the Cast Member Properties dialog box is already open, you can access the Script window by selecting the Script button in that dialog box. You can see whether a cast member has a script attached to it by looking at the cast slot that holds the cast member. The presence of a script icon, as shown in Figure 11-6, indicates that a script is attached. The feature that displays the script icon can be toggled on and off. Just choose File ➪ Preferences ➪ Cast to display the Cast Window Preferences dialog box, and then place a check mark in the check box for Show Cast Member Script Icons, as shown in Figure 11-7. Figure 11-6: The Cast Window, showing a cast member script attached to member 1
Figure 11-7: The Cast Window Preferences dialog box
3486-6 ch11.f.qc
7/24/00
5:48 PM
Page 455
Chapter 11 ✦ Programming Fundamentals
Parent scripts Parent scripts are special scripts used by Lingo to create child objects. When a script has been specified as a parent script, its handlers have the scope of the Script window, like a behavior. A parent script differs from a behavior in that the script does not appear in the Behavior Pop-up menu of the behavior or in Sprite Inspectors. (Parent scripts are used in object-oriented programming and discussed at length in Chapter 13.) Note
Behaviors, movie scripts, and parent scripts appear in the Cast window as cast members, but cast member scripts do not; they appear as an attachment to a cast member. Scripts that appear as cast members are accessible from the Script pop-up list in the Score window or by double-clicking the script cast member in the Cast window.
Events and Script Priority You might have noticed that all four script types can receive and act on some of the same messages (such as the mouseDown and mouseUp messages), so you might be wondering what happens when a handler exists for the same event. What if a movie script has a handler that is meant to intercept a mouse click, as does the current frame script, cast member script, and sprite script? Which script gets control first? An event is some action that occurs in a program. An event can be the action generated by a user typing or clicking the mouse, or it can be generated within Director when the playback head moves, or it can even be generated by a handler. Table 11-3 lists the events defined in Lingo and the scripts that are sent messages when such an event occurs.
Table 11-3 Messages, Related Events, and Script Types Message
Event That Causes the Message
on activate Window
A window is selected or becomes active.
on alertHook
This event enables you to do error handling.
Movie
Frame
Sprite
Cast
Parent
X
X* Continued
455
3486-6 ch11.f.qc
456
7/24/00
5:48 PM
Page 456
Part III ✦ Learning to Program with Lingo
Table 11-3 (continued) Message
Event That Causes the Message
Movie
on beginSprite
The playback head enters a frame containing the first cell of a sprite. (A cell is the intersection of a channel and frame. A sprite might span more than one cell). An on beginSprite initializes a sprite’s properties. It occurs before it’s drawn and it occurs only once (if the playback head leaves and returns, it is called again).
on closeWindow
A window is closed.
X
on cuePassed
A cue point in a sprite or sound is passed.
X
on deactivate Window
A window is deselected or becomes inactive.
X
on endSprite
The playback head leaves the last frame of a sprite’s span. An on endSprite handler cleans up after the sprite restore properties, and to compact memory.
on enterFrame
The playback head enters the frame prior to the frame being drawn.
X
Frame
X
X
Sprite
Cast
X
X
X
X
X
X
X
X
Parent
3486-6 ch11.f.qc
7/24/00
5:48 PM
Page 457
Chapter 11 ✦ Programming Fundamentals
Message
Event That Causes the Message
Movie
Frame
Sprite
Cast
X
X
X
on exitFrame
The frame has been drawn, but the playback head hasn’t yet moved to the next frame. An on exitFrame handler frequently contains navigational information that tells where the playback head should go next.
X
on EvalScript
In a Shockwave movie, this message is received from a browser.
X
on getBehavior Description
This event is called when the Behavior Inspector is opened. It returns a string used as a description of the script.
X
X
on getProperty DescriptionsList
This event is called when you drag a behavior to the Score or you double-click the behavior in the Behavior Inspector. The result is used for the parameter’s dialog box.
X
X
on hyperlink Clicked
This event is called when a user clicks a hypertext link.
on keyDown
The user presses a keyboard key.**
on keyUp
The user releases a keyboard key.**
X
X
X
X
X
Parent
X
Continued
457
3486-6 ch11.f.qc
458
7/24/00
5:48 PM
Page 458
Part III ✦ Learning to Program with Lingo
Table 11-3 (continued) Message
Event That Causes the Message
Movie
Frame
Sprite
Cast
on idle
The movie has no other instructions.
X
X
X
X
on mouseDown
The primary (left) mouse button is pressed. This message can be intercepted by the sprite or cast member over which the mouse pointer rests, or it can be intercepted by the frame if you just want to capture a mouse click.
X
X
X
X
on mouseEnter
The mouse moves into the intercept region of the sprite (usually the sprite’s bounding box unless the sprite uses the Matte ink). This event only occurs once, when the mouse first enters the sprite’s intercept region and until a mouseLeave event occurs.
X
X
on mouseLeave
The mouse pointer exits the intercept region of a sprite, regardless of whether the mouse button is pressed.
X
X
on mouseUp
The mouse button is released. This event is sent each time the primary (left) mouse button is released.
X
X
X
X
Parent
3486-6 ch11.f.qc
7/24/00
5:48 PM
Page 459
Chapter 11 ✦ Programming Fundamentals
Message
Event That Causes the Message
Movie
Frame
Sprite
Cast
on mouseUp Outside
The mouse button is released outside a sprite’s bounding box, after the mouse button was originally pressed while over the sprite.
X
X
on mouseWithin
This event occurs repeatedly while the mouse pointer resides within the bounding box of a sprite. Use this event handler only when absolutely necessary, because the constant stream of mouseWithin messages intercepted by a handler can slow movie performance.
X
X
on moveWindow
This event is called when you drag a movie’s window.
X
on openWindow
A window opens.
X
on prepareFrame
This event is called when the playback head moves; it occurs before anything is drawn on the screen.
X
X
X
on prepareMovie
This is the first message sent to a movie. This is a good place to initialize global variables.
X
on resizeWindow
The user resizes a window.
X
X
Parent
Continued
459
3486-6 ch11.f.qc
460
7/24/00
5:48 PM
Page 460
Part III ✦ Learning to Program with Lingo
Table 11-3 (continued) Message
Event That Causes the Message
Movie
Frame
Sprite
Cast
on rightMouse Down
The user presses the right mouse button. For Mac users, this message is sent if the user is pressing the Control key while the mouse is clicked (if emulateMulti ButtonMouse is set to TRUE.
X
X
X
X
on rightMouseUp
The user releases the right mouse button. For Mac users, this message is sent if the user is pressing the Control key while the mouse is clicked (if emulateMulti ButtonMouse is set to TRUE).
X
X
X
X
on runProperty Dialog box
This event is called when the Parameters dialog box in the Behavior Inspector is opened. It enables you to override the defaults from the getProperty DescriptionList.
X
X
on startMovie
A movie starts. Useful for initializing sprites in the first frame.
X
on stepFrame
When the Stage gets updated, this message is sent to the actorList. Any child object in the actorList receives this message.
Parent
X
3486-6 ch11.f.qc
7/24/00
5:48 PM
Page 461
Chapter 11 ✦ Programming Fundamentals
Message
Event That Causes the Message
Movie
on stopMovie
A movie ends. Useful for cleaning up external resources, memory, and storing information about the session.
X
on streamStatus
This handler is called when tellStream Status is set to TRUE.
X
on timeOut
Nothing is happening. This event measures a period of inactivity and is used to trigger another event.
X
Frame
Sprite
Cast
*
An alertHook message is sent on a global (movie-wide) level, but the handler must be placed in a parent script.
**
If the keyUp or keyDown event occurs over an editable field, all types of scripts can intercept the message. If the event does not occur over an editable field, the message can be intercepted only by a frame or movie script.
Parent
Messages generated by events in a Director movie follow a specific hierarchical path. Don’t worry about duplicate handlers in overlapping scripts; after a message is intercepted by one handler, it won’t be passed to another handler unless specifically instructed to do so. The path of any event message is illustrated in Figure 11-8. In this example, the event is a mouse click, the message is mouseUp, and Director is seeking an on mouseUp handler to manage the event. Note
You can establish primary event handlers for four common events that generate messages in a Director movie (keyDown, mouseDown, mouseUp, or timeOut). If a primary event handler has been defined, the message is intercepted and the specific instructions in the primary event handler are executed first, before any of the handlers in the appropriate script in the message hierarchy. While all other event handlers automatically trap the event by default, the primary event handler passes it on by default, so you do not need to use the pass command.
Here’s what happens when a mouse click occurs (refer to Figure 11-8). This stepby-step explanation shows how messages are generated by events and passed to handlers. ✦ Primary event handler: When the mouse button is clicked on the Stage, Director first checks to see if a primary event handler exists. If so, Director executes the instructions in the handler. The message is then passed, unless there is a stopEvent command in the handler.
461
3486-6 ch11.f.qc
462
7/24/00
5:48 PM
Page 462
Part III ✦ Learning to Program with Lingo
User presses mouse button
mouseDown event
Is there a primary event handler?
Yes
If there is a primary event handler defined then that handler is executed and the message is passed. Example: set the mouseDownScript to "myHandler", myHandler is the first thing to execute.
No
Is there a sprite behavior?
Yes
If there is a sprite behavior with an on mouseDown handler then it executes.
Is there another sprite behavior?
No
Is there a cast member script?
No
Yes
If there is a cast member script with an on mouseDown handler then it executes.
No
Is there a frame script?
Yes
If there is a frame behavior with an on mouseDown handler then it executes.
No
Is there a movie script?
Yes
If there is a movie script with an on mouseDown handler then it executes.
No
Message (event) Ends
Figure 11-8: The path of a mouseDown event
Yes
If there is another sprite behavior with an on mouseDown handler then it executes. Message stops here unless there are more sprite behaviors.
3486-6 ch11.f.qc
7/24/00
5:48 PM
Page 463
Chapter 11 ✦ Programming Fundamentals
Note
If no sprite exists at the location of the mouse click, then Director immediately looks to the frame script channel to see if the frame includes a handler for the mouse click event. If no frame script exists, Director looks for a movie script that contains a handler for the event.
✦ Sprite behavior: Next, Director checks to see if there’s a sprite at the clicked location. If so, Director looks for a behavior attached to the sprite. If the sprite has multiple behaviors attached, all of them are sent the mouseDown message. Director takes no further action, unless each of the behaviors attached has a pass command in the handler. If no behavior script exists, or if it doesn’t have a handler for the event, Director checks for a cast member script. ✦ Cast member script: If a cast member script is found and it has a handler for the event, Director takes no further action, unless the handler has a pass command. If there is no cast member script, or if it doesn’t have a handler for the event, Director checks for a frame script. ✦ Frame script: If a frame script is found and it includes a handler for the event, control is passed to that handler. Director takes no further action, unless instructed to by the frame script. If no frame script exists with a handler for the message, Director checks for a movie script. ✦ Movie script: If a movie script is found and it includes a handler for the event, control is passed to that handler. Finally, if no script is found with a handler for the event throughout the hierarchy, it is simply ignored. Tip
Visualize the script types as a series of safety nets, with the sprite behavior being the first net, the cast member script being second, the frame script being third, and the movie script being the final net. If a script of a certain type exists, the net captures the event (a primary event handler has no net). If the script does not exist with a handler for the event, no net exists. The event jumps off a platform and keeps falling until it encounters a safety net. When a safety net is encountered, the event is grabbed by a handler that takes its message and executes a specific action.
Following are a few additional guidelines to help summarize the priority given to various scripts. ✦ If you click a sprite that has both a cast member script and a sprite behavior attached, the sprite behavior takes priority. ✦ If you click a sprite that has a cast member script, and the current frame also has a script attached, the cast member script takes priority.
463
3486-6 ch11.f.qc
464
7/24/00
5:48 PM
Page 464
Part III ✦ Learning to Program with Lingo
✦ If you click a sprite that has both a sprite behavior and a cast member script, and the current frame also has a script attached, the sprite behavior takes priority. ✦ If you click an area of the Stage that does not have a sprite, the frame script takes priority. ✦ If you click an area of the Stage that does not have a sprite and no frame script exists for the current frame, the movie script takes priority. In the preceding statements, we used a mouse click as the event. The event could just as easily have been leaving a frame (exitFrame), entering a frame (enterFrame), no action (idle), the elapsing of a specified period of time (timeOut), or any of the other events listed in Table 11-3.
Variable Scope Variables come in three varieties. A global variable can be used anywhere within a movie. A local variable is used only within a specific handler. After the handler completes execution, the local variable ceases to exist. Whether local or global, the first occurrence of a variable in your script creates it. The third variety is called a property variable. It is declared at the beginning of a behavior or parent script and is available within the handlers within that script window.
Global variables The following guidelines are helpful when using a global variable: ✦ You can declare a global variable in any handler or in any script in a movie. ✦ If you want to establish a global variable, use the global keyword followed by the name of the variable. You can declare more than one global variable on the same line. The following are examples of two global statements that declare, respectively, a single variable and multiple (three) variables: global gMyNewVariable global gCost, gRetail, gProfit
✦ To use a global variable in a specific script, you must repeat the global statement within that script. Once declared, the current value or string stored by a global variable is available for use and modification within the handler. ✦ Sometimes, to easily differentiate between local and global variables, Lingo programmers begin global variables with the lowercase letter g. ✦ To see a display of global variables and their current values, use the showGlobals command. The result appears in the Message window. ✦ You can reference all of the initialized global variables with the globals property. This the globals property returns a property list of all of the global variables in use.
3486-6 ch11.f.qc
7/24/00
5:48 PM
Page 465
Chapter 11 ✦ Programming Fundamentals
Local variables The following guidelines are helpful when using a local variable: ✦ If you do not declare a variable as global, it is a local variable. ✦ A local variable can be used only within the handler in which it is declared. When the handler finishes, the variable ceases to exist. Note
For the sake of comparison, a local variable is like a three-year-old child, and a global variable is like a teenager. The effective domain of a three-year-old (local variable) is limited to inside the house and a fenced backyard (the current handler). The effective domain of a teenager (global variable) is anywhere and everywhere he or she decides to go (the entire movie). Both global variables and teenagers perform assigned tasks only when called by name (sometimes loudly), whenever and wherever they are needed.
Properties You can use properties in both behaviors and parent scripts. The value of a property variable persists as long as the object that contains it exists. Properties declared at the top of a Script window, outside of any handler, can be accessed from any handler within that Script window. We discuss them in detail in Chapter 13.
The life cycle of a local variable Variables have a certain (albeit very limited) kind of life. Within a script, a variable is born, lives out its life, and dies. Birth: You write a set or put statement, with the variable being assigned a value. For example: set count=0 In this case, Director creates space for the variable and reserves the variable name for as long as the variable shall live. Life: The variable’s contents can be accessed or changed. Within a routine, the variable retains its contents until those contents are explicitly changed. For example: set count = count + 1 The contents of the variable count are updated every time the statement is evaluated (executed). Death: Director removes the variable name from its references, the contents of the variable are discarded, and the variable ceases to exist. Death usually occurs only when the routine where the variable is defined ends. When this happens, the variable is said to “go out of scope.”
465
3486-6 ch11.f.qc
466
7/24/00
5:48 PM
Page 466
Part III ✦ Learning to Program with Lingo
Summary Among the things you learned in Chapter 11 are the following: ✦ The Message window is your tool for testing code and checking properties. ✦ Variables can be declared (by their use) as local to a specific handler or global (available in all handlers within a movie). ✦ Like other programming languages, Lingo uses commands, expressions, functions, variables, and constants as code-building blocks. ✦ Handlers enable you to execute many lines of code with one word. ✦ Functions are handlers that return a value. ✦ Operators are symbols that tell you how two or more expressions should be combined. Lingo includes arithmetic, comparison, logical, and a few miscellaneous operators. ✦ There are four types of scripts in Director: movie, behavior (score/frame/sprite scripts), parent, and cast member. ✦ There are three types of variable scope: global, property, and local. In the next chapter, you learn about lists and their usefulness.
✦
✦
✦
3486-6 ch12.f.qc
7/24/00
5:48 PM
Page 467
12 C H A P T E R
Lists and Other Structures
✦
✦
✦
✦
In This Chapter
S
ometimes the data you manage in a movie doesn’t fit into a neat, single value or string, but instead must be stored and manipulated as a collection of items. Lingo responds to this need with lists. From collections of numbers to collections of windows and objects, the list is a tool for working with aggregate information. Being familiar with lists is very important to becoming a good Lingo programmer. This chapter teaches you to build and work with linear and property lists — as well as other Lingo structures, such as rects, points, colors, and dates — and how they are useful in your movies.
Using Lists Lists are complex data structures that can store more than one piece of data per variable and treat the entire collection as a single item. You store and retrieve data in a list based on the data’s position within the container. Lingo supports two types of lists: ✦ Linear lists: Values in a linear list are accessed by their position in the list. ✦ Property lists: Values in a property list are accessed by a property associated with the value. Each of these types of lists can be either sorted or unsorted. After you use the sort command on a list, the list remains sorted even when you make changes to it. Note
Director 8 has improved the access times of nonsorted lists to about equal that of sorted lists for most cases. In fact, overall list access times have improved.
Working with linear lists Working with property lists Working with points and rects Working with colors and dates
✦
✦
✦
✦
3486-6 ch12.f.qc
468
7/24/00
5:48 PM
Page 468
Part III ✦ Learning to Program with Lingo
Lists are valuable when you need to create an undetermined number of variables while the movie runs. Unlike variables that can hold only a single value or string at one time, lists are, by definition, variables that can store multiple values or strings at the same time. You can add an item to a list, retrieve an item from a given position in the list, delete an item from a list, and even step through the list one item at a time. The list is actually one of the more useful structures in programming. It provides a way to put items in order, to transport a lot of items at once, and to treat all the items within the list in a similar fashion without establishing a separate variable for each item individually. A list can hold any data type that a simple variable can — an integer, a string, a reference to a cast member, even another list. Lingo offers several commands to manage and manipulate data within lists. They enable you to: ✦ Add data at the beginning of or at a specific location in a list ✦ Append data at the end of a list ✦ Remove data from a list ✦ Access data from a specific location in a list ✦ Edit data stored in a list ✦ Sort data in a list ✦ Count the number of data items in a list Remember these rules about list commands: ✦ In all cases, the myList argument refers to the list you are modifying. ✦ If the data you add is a string, be sure to enclose it within double quotation marks. If the data is numeric, quotation marks are not used. Table 12-1 identifies the most important list-related Lingo. It’s been separated into categories: Lingo that works on property and linear lists, and Lingo exclusive to linear or property lists.
3486-6 ch12.f.qc
7/24/00
5:48 PM
Page 469
Chapter 12 ✦ Lists and Other Structures
Table 12-1 List-Related Lingo All Terms
Type of List Used In
Add
Linear
AddAt
Linear
AddProp
Property
Append
Linear
Count
Both
DeleteAt
Both
DeleteOne
Both
DeleteProp
Property
Duplicate()
Both
FindPos()
Both
FindPosNear()
Both
GetAProp()
Property
GetAt()
Both
GetLast()
Both
GetOne()
Both
GetPos()
Both
GetProp()
Property
GetPropAt()
Property
Ilk()
Both
List()
Linear
ListP()
Both
SetAProp
Property
SetAt
Both
SetProp
Property
Sort
Both
Max
Both
Min
Both
[ ] (brackets)
Both
. (dot)
Both
469
3486-6 ch12.f.qc
470
7/24/00
5:48 PM
Page 470
Part III ✦ Learning to Program with Lingo
Working with linear lists Like other variables, a list must have a name and must be initialized either with or without data. You declare, or initialize, a list when you use it. You can use two forms to declare a linear list. The more common syntax is to use the set command: set myList to [item1, item2, item3...]
myList is replaced with the list’s name; and item1, item2, and so on, are replaced with the data that you want stored in the list. The square brackets signal Director that the enclosed data is a list. The other method of declaring a linear list, which is seldom used, is: set myList to list(item1, item2, item3...)
This second method uses the list function, to which the data in the parentheses are returned as a list. In the following example, you initialize (create) a linear list with three entries: set products to [“motherboard”, “chip set”, “keyboard”]
Just like the different ways you learned to initialize a variable in Chapter 11, you can initialize a list by using the variety of syntactical methods Lingo supports: set products = [“motherboard”, “chip set”, “keyboard”] put [“motherboard”, “chip set”, “keyboard”] into products products = [“motherboard”, “chip set”, “keyboard”]
The same is true for the list() function: set products to list(“motherboard”, “chip set”, “keyboard”) set products = list(“motherboard”, “chip set”, “keyboard”) put list(“motherboard”, “chip set”, “keyboard”) into products products = list(“motherboard”, “chip set”, “keyboard”)
Using brackets is the most common form of list creation, so from this point on, that is what we’ll use in our examples. In addition to strings, lists can include values, as in set playerScores to [50, 27, 33, 66]
Lists do not have to be homogeneous — a single list can hold many different data types. set person to [“John Smith”, 34, #sales]
3486-6 ch12.f.qc
7/24/00
5:48 PM
Page 471
Chapter 12 ✦ Lists and Other Structures
Most of the time, you find yourself using linear lists to hold elements of the same data type. Property lists lend themselves to holding different types. To initialize a linear list that is empty, you can do any of the following: set products to [] put [] into products products = []
Additionally, you can use the list() function, which returns an empty list when passed with no arguments: products = list()
Getting values There are many ways to get information from a linear list. Some of them require functions, others require just the list operators [ ]. Note
All of the list functions in Lingo work on the assumption that the first element in the list is item number 1, the second is item number 2, and so forth. If you’ve learned programming in the C language arena, this can throw you, because C-like languages (including C++ and Java) usually start counting with zero instead of 1.
getAt( ) and [ ] Both getAt() and the list operators enable you to get a value of a list, based on the items index in the list.
Syntax: getAt(myList, index) myList.getAt(index) myList[index] myList is the name of your list or a variable holding a list. index is an integer or a variable holding an integer. The list operators, [], go at the end of the list when you
want to retrieve an element from the list. The index indicates which element in the list is retrieved. Here’s an example you can try in the Message window: daysOfWeek = [“Sun”, “Mon”, “Tue”, “Wed”, “Thu”, “Fri”, “Sat”] put getAt(daysOfWeek, 3) -- “Tue”
Or, using the dot operator: put daysOfWeek.getAt(4) -- “Wed”
471
3486-6 ch12.f.qc
472
7/24/00
5:48 PM
Page 472
Part III ✦ Learning to Program with Lingo
Or, with the brackets: put daysOfWeek[5] -- “Thu”
This next instruction sets the variable thirdDay equal to the third item in the daysOfWeek list: thirdDay = getAt(daysOfWeek,3)
If you type put thirdDay in the Message window, the result is as shown here: put thirdDay -- “Tue”
Alternatively, you can write: secondDay = daysOfWeek[2] put secondDay -- “Mon”
As you might expect, when using the getAt() function, you have to be careful about specifying the position within the list from which you want to get data. If you request a position that’s greater than the number of items the list holds, as in the following example, Director displays the Alert message shown in Figure 12-1: eighthDay = daysOfWeek[8]
Figure 12-1: Director complains if the requested position exceeds the number of items in the list.
The brackets make life much easier when you are dealing with lists within lists. Suppose that you had the following list: myTable = [[11, 12, 13], [21, 22, 23], [31, 32, 33]]
You want to get the third item of the second list. If you think of it as a table, then you want to retrieve the item in row 2, column 3. You need to write the following: put getAt(getAt(myTable, 2), 3) -- 23
3486-6 ch12.f.qc
7/24/00
5:48 PM
Page 473
Chapter 12 ✦ Lists and Other Structures
Yipes! Gets confusing to look at, doesn’t it? The inner function is executed first, and it returns the second list. It’s like writing: put getat(myTable, 2) -- [21, 22, 23]
Then the outer function executes on the return value, which is the second list, [21, 22, 23]. It’s like writing: put getAt([21, 22, 23],3) -- 23
You could make life simpler by doing it in steps, using a temporary variable: put getAt(myTable, 2) into temp put getAt(temp, 3) --23
That’s much easier to read. With brackets, it is even easier and involves less typing, as follows: put myTable[2][3] -- 23
The first index holds the row index, and the second holds the column index.
getLast( ) This handy function gets the last item from a list.
Syntax: getLast(myList) myList.getLast()
Now try it on the daysOfWeek list: put getLast(daysOfWeek) -- “Sat” put daysOfWeek.getLast() -- “Sat”
getOne( ) This function returns the position of an item in a list, and it works with both linear and property lists.
Syntax: getOne(myList, aValue) myList.getOne(aValue)
473
3486-6 ch12.f.qc
474
7/24/00
5:48 PM
Page 474
Part III ✦ Learning to Program with Lingo
myList is the name of your list or the variable holding a list. aValue is a value you expect to be in the list. Perhaps, however, you are testing the list to see if that value is in it. If the list does not contain the value, it returns 0. put getOne(daysOfWeek, “Tue”) -- 3 put getOne(daysOfWeek, “Tuesday”) -- 0 put daysOfWeek.getOne(“Sat”) -- 7
getPos( ) This function works in the same way as the getOne() function.
Syntax: getPos(myList, aValue) myList.getPos(aValue)
You get the same results as getOne(): put getPos(daysOfWeek, “Tue”) -- 3 put getPos(daysOfWeek, “Tuesday”) -- 0 put daysOfWeek.getPos(“Sat”) -- 7
Setting values You set values in a list almost as often as you get values from one. Setting a value just means changing a value at a particular location to a new value. If you want to change an entry in a list, the simplest way is to use the setAt command, which mirrors the getAt command.
Syntax: setAt myList, index, aValue myList.setAt(index, aValue) myList[index] = aValue
The setAt command passes the name of the list, the position that you want to change, and the value you want to change as arguments. As an example, from a collection of pets, you can create a list with the following animals: pets = [“dog”, “cat”, “fish”]
3486-6 ch12.f.qc
7/24/00
5:48 PM
Page 475
Chapter 12 ✦ Lists and Other Structures
Here’s how to change the third entry (“fish”) to a bird and then a hamster, using the setAt command: setAt pets, 3, “bird” put pets -- [“dog”, “cat”, “bird”] pets.setAt(3, “hamster”) put pets -- [“dog”, “cat”, “hamster”] Note that you did not have to put parentheses around the setAt arguments. This is because setAt is a command, not a function. It does not return a value, so the parentheses are optional. We like to add them to improve the readability of the code. When using the dot notation, pets.setAt(3, “newt”), the parentheses are required. If you can’t remember whether the arguments need to be in parentheses, then use them (it won’t hurt and it might make your code easier to understand).
Note
setAt(pets, 3, “newt”) -- parentheses not required, but nice put pets -- [“dog”, “cat”, “newt”] pets.setAt(3, “newt”) -- parentheses ARE required here Caution
Be careful about passing the setAt command a number outside of its range. The results may surprise you: setAt(pets, 7, “snake”) put pets -- [“dog”, “cat”, “newt”, 0, 0, 0, “snake”] When the index to the setAt command falls outside the range of the list, Lingo pads the list, inserting zeroes for items that have not been defined. It does this with the list operators as well. Although this approach may be useful in some (unusual) circumstances, in general you should avoid it, because it can introduce spurious data into your lists.
As with the getAt() function, you can also use the list operators, [ ], instead of the setAt command, as follows: pets = [“dog”, “cat”, “hamster”] pets[1] = “iguana” put pets -- [“iguana”, “cat”, “newt”]
475
3486-6 ch12.f.qc
476
7/24/00
5:48 PM
Page 476
Part III ✦ Learning to Program with Lingo
Adding to a list Sometimes you don’t want to change a value in a list, but you want to add additional values. You can add to a specific location in a list or just tack it onto the end.
addAt The addAt handler works similarly to setAt. Whereas setAt replaces the value at a given position, addAt inserts the value at that position, shifting all subsequent items back one position. The addAt handler works only with linear lists.
Syntax: addAt myList, index, aValue myList.addAt(index, aValue)
Continuing with the pets example: pets = [“fish”, “dog”, “cat”, “hamster”] addAt pets, 3, “bird” put mylist -- [“fish”, “dog”, “bird”, “cat”, “hamster”] Note
Note how “bird” was put into position 3, and the other elements after it are still there. This is the difference between adding an element to a specific position in a list and setting an element in a specific position in the list to a new value.
Using the dot operator, you can add a newt to the first position and bump all the lesser pets back: pets.addAt(1, “newt”) put pets -- [“newt”, “fish”, “dog”, “bird”, “cat”, “hamster”]
As with setAt, if you specify an index position outside of the range of the list with addAt, Lingo pads the list with zeroes to fill the undefined locations in the list. pets = [“fish”, “dog”] addAt pets, 5, “newt” put pets -- [“fish”, “dog”, 0, 0, “newt”]
If a list has been sorted, using addAt breaks the sorting. pets = [“dog”, “cat”] sort pets put pets -- [“cat”, “dog”] addAt pets, 2, “bird” put pets -- [“cat”, “bird”, “dog”]
3486-6 ch12.f.qc
7/24/00
5:48 PM
Page 477
Chapter 12 ✦ Lists and Other Structures
add You can add an item to a list by way of the add command. The add command places the item at the end of the list, unless the list is sorted. You can use it only with linear lists.
Syntax: add myList, aValue myList.add(aValue)
In the Message window, type the following code: pets = [] add pets, “dog” add pets, “cat” put pets -- [“dog”, “cat”]
Using add is straightforward. If you want a quick list of the names of all the members in a castLib, for example, you can write a function like the one shown in Figure 12-2. GetMemName() also includes some commented code in it that shows how the statement inside the repeat loop could be written using the dot notation syntax.
Figure 12-2: A function using add to build a list of member names
It becomes a little less straightforward after you’ve used the sort command on it. If the list is sorted, then additions to the list are added and put in their sorted position automatically, as follows: sort pets put pets -- [“cat”, “dog”] add pets, “bird” put pets -- [“bird”, “cat”, “dog”]
Because “bird” was added to a list that had been sorted, it was not put at the end of the list but in the right alphabetical position.
477
3486-6 ch12.f.qc
478
7/24/00
5:48 PM
Page 478
Part III ✦ Learning to Program with Lingo
append The append command always puts the value at the end of the list, even if it is sorted.
Syntax: append myList, aValue myList.append(aValue)
Continuing with pets from the preceding example: append pets, “alligator” put pets -- [“bird”, “cat”, “dog”, “alligator”] pets.append(“iguana”) put pets -- [“bird”, “cat”, “dog”, “alligator”, “iguana”]
In the pets example, the items are no longer in sorted order when the append command is used. Caution
If a list has been sorted, using the append command breaks the sorting.
Deleting items from linear lists You can also remove values from lists. Linear lists have two commands for deleting items, deleteAt and deleteOne.
deleteAt To remove a specific item from a linear list, use the deleteAt command. This command eliminates the item at a specified position and then collapses the list by one.
Syntax: deleteAt myList, index
To delete the second item in this list, write the following code: pets = [“cat”,”dog”,”fish”,”hamster”] deleteAt pets, 2 put pets -- [“cat”, “fish”, “hamster”]
deleteOne If you want to remove something from a list based on its value, you can use deleteOne.
3486-6 ch12.f.qc
7/24/00
5:48 PM
Page 479
Chapter 12 ✦ Lists and Other Structures
Syntax: deleteOne myList, aValue
For example: pets = [“cat”, “dog”, “fish”, “hamster”] deleteOne pets, “cat” put pets -- [“dog”, “fish”, “hamster”]
If there are two items in the list with the same value, the first item is deleted. pets = [“cats”, “dogs”, “cats”] deleteOne pets, “cats” put pets -- [“dogs”, “cats”] deleteOne pets, “cats” put pets -- [“dogs”]
Lingo doesn’t have a command that enables you to remove all instances of a value, so this would be a good time to create one by writing our own handler in Lingo (see Figure 12-3).
Figure 12-3: A handler that removes all instances of a value in a list RemoveAll takes advantage of getOne() and deleteOne. First, getOne() checks whether anItem is in the list, and if it is, deleteOne removes it. The handler keeps going through this loop until getOne() returns 0, at which point the loop exits.
This handler is not a function; it does not return a value. pets = [“cats”, “dogs”, “cats”] RemoveAll pets, “cats” put pets -- [“dogs”]
So how does the modified list get back to where you called RemoveAll from? See the sidebar “Transferring and Duplicating Lists.”
479
3486-6 ch12.f.qc
480
7/24/00
5:48 PM
Page 480
Part III ✦ Learning to Program with Lingo
Transferring and duplicating lists When you assign a variable holding a basic data type, such as an integer, float, symbol, or string, to another variable, that value is copied to the other variable. That value exists in a different chunk of memory. The following statements and their results should come as no surprise to you: intA = 12 intB = intA put intB -- 12 intB = 7 -- we’ll change intB put intB -- 7 put intA -- intA is unaffected -- 12 A list is kept internally as a pointer to a structure in memory; if you assign one variable (which contains a list) to another variable, then the only thing transferred is the pointer, not the list itself. In other words, if you set listB to equal listA and change the contents of listB (or listA), the changes are reflected in both lists. That’s because both variables point to the same list. This can best be demonstrated in the following example: listA = [1, 2, 3, 4, 5] listB = listA add listB, 6 -- we’ll change listB put listB -- [1, 2, 3, 4, 5, 6] put listA -- [1, 2, 3, 4, 5, 6] -- They’re the SAME! This may not be the behavior that you desire if you want to create a new list containing all the components of the old list and be able to change the new list without affecting the original. With the duplicate function, you have the capability to create a copy of a list and modify it separately from the list upon which it was based. The duplicate function copies the entire list into a new block of memory and then assigns a new pointer to that block: listA = [1,2,3,4,5] listB = duplicate(listA) add listB, 6 put listB -- [1, 2, 3, 4, 5, 6] put listA -- [1, 2, 3, 4, 5] To use duplicate() with dot notation, write: listB = listA.duplicate()
3486-6 ch12.f.qc
7/24/00
5:48 PM
Page 481
Chapter 12 ✦ Lists and Other Structures
When you copy a pointer, it happens in an instant. On the other hand, copying the entire contents of a large list (and lists can become very large) may take a noticeable amount of time, perhaps even seconds (an eternity!). For this reason, as you design your project, try to minimize the amount of actual list duplication. It can have a profound impact on performance. When you call a handler with parameters, the values you pass in as arguments are copied into the parameters. So, when a list is passed to a function, as in Figure 12-3, the pointer to the list is what is copied to the parameter. That means the operations are manipulating the same list, not a duplicate. Thus, you do not need a return statement though it wouldn’t hurt to have one, and it may make your code clearer to others; see the figure below).
The RemoveAll handler changed to the function RemoveAll(). Here’s how you use the altered RemoveAll(): pets = [“cats”, “dogs”, “cats”] pets = RemoveAll(pets, “cats”) put pets -- [“dogs”] This snippet of code seems clearer than the RemoveAll handler version. Here, it is obvious that the variable pets is being changed by the RemoveAll() function.
Working with Property Lists Properties — of sprites, of cast members, of the system itself — form the core of Director Lingo programming. Through Lingo, you can also create your own property lists, thus opening the door for database processing, advanced pro-gramming in behaviors, and object-oriented programming. A property list includes two related components for each entry in the list. The first component, called a property, is linked to a second component, called a data element. A property list is like a two-field database. Using this analogy, the first field is the key field (the property) and the second field contains linked data. When you sort a property list, it is ordered by the property.
481
3486-6 ch12.f.qc
482
7/24/00
5:48 PM
Page 482
Part III ✦ Learning to Program with Lingo
The syntax for a property list is demonstrated in the following example of test scores. In this example, the names (strings such as “Pat”, “Joan”, and “Mary Ellen”) are properties, and the scores (such as 1200, 1545, and 950) are data. Each name and its associated score is an item in the list. scores = [“Pat”: 1200, “Joan”: 1545, “Mary Ellen”: 950]
Strings are not the best choice for property labels. They are slower to process, but more important, using a string as a property label is the only time that you encounter a case-sensitivity issue with Lingo. Suppose that you tried to get one of the properties and used the wrong case, such as: put getProp(scores, “pat”)
The result is a syntax error. Most of the time, it is preferable to use symbols, which are not case sensitive. scores = [#Pat: 1200, #Joan: 1545, #MaryEllen: 950] put getProp(scores, #pat) -- 1200
You can initialize or create an empty property list named Scores by using this syntax: scores = [:]
Consider the following situation: You are developing an application in Director that displays a catalog of merchandise. Each “page” of the catalog contains the name of a product, a picture showing the merchandise, a category that describes the type of merchandise, a description of the merchandise, a unique ID, and a price. To make things more complicated, the catalog is updated every week and distributed via the Internet to thousands of customers who don’t take kindly to long downloads. In other words, you don’t have the luxury of creating a frame-based solution that provides for each page of the catalog having a separate frame, or have a new catalog downloaded each week to all the customers. Does this sound like an impossible challenge? Actually, it’s a scenario typical of many product-related environments, thanks to Internet-fostered changes that make hybrid CD-Web products feasible. Back to the point at hand: This example illustrates the principle of properties in a big way. If you think of a product in the catalog as an object in the same vein as a cast member or a sprite, then the page has several distinct properties. These properties are the nouns that quantify the page, describing the makeup of the page. We might come up with several properties, just from the description of the application, as shown in Table 12-2.
3486-6 ch12.f.qc
7/24/00
5:48 PM
Page 483
Chapter 12 ✦ Lists and Other Structures
Table 12-2 Properties of the Catalog Product Object Property
What It Describes
The Name of Product
The name of the merchandise
The Picture of Product
A picture (or at least the filename of a picture)
The ID of Product
A unique identifying number for the product to help expedite processing
The Category of Product
A string specifying a given product category (for example, a book might be in the fiction category)
The Description of Product
A text description of the product
The Price of Product
The price of the product (we’ll assume this is a floating point number)
Why are these characteristics described as properties of a list, rather than just generic variables? In a catalog, there may be hundreds of different products with various prices, descriptions, names, and so forth — but the important thing is that each item has its own description, name, price, and even maybe an ID. If you could create a generic product and then customize it to describe uniquely this widget or that gadget, you could make routines that worked with these properties without having to know any specifics about what the properties contain. Again, the principle of separating the functionality of your code from the content of the data comes into play. And, of course, there is a way — in Lingo — to specify such a generic product: That’s what the specialized property list is for. Although this list shares some of the same characteristics as a linear list, it also has some considerably expanded functionality. In the following example, the property list is made up of a collection of entries, each referenced by the property name given as a symbol. For example, the following code segment represents a property list for a paperback book in a catalog application: product = [ #name: “The Novaenglian Chronicles”, ¬ #picture: “NovChron1.jpg”, ¬ #ID: “BKSTR123NC12”, ¬ #category: “Science Fiction”, ¬ #price: 5.95, ¬ #description: “The rise of civilization in post-¬ apocalyptic England.” ¬ ]
483
3486-6 ch12.f.qc
484
7/24/00
5:49 PM
Page 484
Part III ✦ Learning to Program with Lingo
Note
The preceding lines of code constitute one executable statement. The continuation character (¬) enables you to break a long line of code into shorter lines, which can still be considered part of the same statement. When Director evaluates this instruction, it assembles the smaller parts together before interpreting the entire line. To enter the continuation character, press Option+Return (Alt+Return). The continuation character does not work in the Message window.
If you are following along, experimenting in the Message window, then enter product, as follows: product = [#name: “The Novaenglian Chronicles”, #picture: “NovChron1.jpg”, #ID: “BKSTR123NC12”, #category: “Science Fiction”, #price: 5.95, #description: “The rise of civilization in post-apocalyptic England.”]
Each list entry is given a label, using a symbol, which describes the property. Like a linear list, this property list is marked by square brackets. In contrast to a linear list, however, each entry uses a symbol followed by a colon (:). After you define a property list as just shown, you can refer to the properties of the list as if the list were an object. For example, you can write the following code so that, after the preceding code fragment is encountered, you get the result shown: put “The price of “&(the name of product)&” is $”&(the price of product)&”.” -- “The price of The Novaenglian Chronicles is $5.95.” Note
If the price of product property on your system displays as 5.9500, it’s because the floatPrecision property is set to 4, the default value. This property, which establishes the number of digits that a floating point number displays after the decimal point, can use a value between 0 and 15. Only the display of the float is affected by this property, not the calculation of values. Set the floatPrecision to 2 if you want it to display as in the example.
For all intents and purposes, Lingo now treats product as an object, in much the same vein as a cast member or sprite. This works in assignments as well. You can alter the price (the book is remaindered) by using the following instruction: set the price of product to 3.95 put “The price of “ & (the name of product) & “ is $” & (the price of product) & “.” -- “The price of The Novaenglian Chronicles is $3.95.”
You can also use dot syntax: product.price = 3.95 put “The price of “ & (product.name) & “ is $” & (product.price) & “.”
3486-6 ch12.f.qc
7/24/00
5:49 PM
Page 485
Chapter 12 ✦ Lists and Other Structures
You can even the list operators: product[#price] = 3.95 put “The price of “ & (product[#name]) & “ is $” & (product[#price]) & “.”
Note the differing syntax. When you use the property and dot syntax, the # is left off the name of the symbol. Were you to leave it on, you’d get a syntax error. If you left the pound sign (#) off when using the list operators [ ], Director would think you are using a variable. The use of symbols as labels in a property list is not required — you can use numbers, strings, and even lists. If you don’t use symbols, however, you cannot use the property syntax (the price of product) or the dot syntax, and several other operations with property lists become less efficient. If you use strings as labels, you have to deal with case-sensitivity. Unless you have a compelling reason to do otherwise, stick with symbols as property labels. Although property lists can be viewed similarly to objects, they also have many of the same characteristics as linear lists — to the extent that a property list is like a “superset” of linear lists. Property lists give you more ways to get and set data than linear lists do. Both linear and property lists share a common set of commands and functions. In general, when a linear list function is used on a property list, it acts on the property list’s values (data elements), not on the property labels. Using the preceding example, the command getAt(product1, 4) retrieves the data associated with the fourth entry in the product list (the value: “Science Fiction”) — as opposed to the property name of the fourth entry (#category). The primary benefit of using a property list is that you don’t need to know a given property’s position in the list. You need to know only that the property list contains the property. Don’t waste the primary benefit of a property list — avoid relying on positional references for accessing entries unless you are retrieving all of the properties from the list. The sort command sorts the properties alphabetically, instead of sorting the data elements. set myList to [#b:3, #a:2, #c:1] put myList -- [#b: 3, #a: 2, #c: 1] sort myList put myList -- [#a: 2, #b: 3, #c: 1]
This command is the only exception to the rule that functions common to linear and property lists work exclusively on the entries of the list (the data elements), not on the properties. This idiosyncrasy can be a source of errors, because it may seem more logical to sort by the values of the properties.
485
3486-6 ch12.f.qc
486
7/24/00
5:49 PM
Page 486
Part III ✦ Learning to Program with Lingo
Many list functions/commands work for both property lists and linear lists. Where a function/command works identically for property lists as it does for linear lists, we’ll refer you back to the section on linear lists.
Getting values from property lists You can get a property from a list by using the propName of myList syntax, as shown earlier.
getProp( ) This function returns the value of the property. If the property does not exist, it returns a syntax error.
Syntax: getProp(myList, propName) myList.getProp(propName)
To use getProp() just pass in the name of a property that is in the list: membList = [#happy: (member 1 of castLib 1), #sad: (member 2 of castLib 1)] put getProp(membList, #happy) -- (member 1 of castLib 1) put membList.getProp(#sad) -- (member 2 of castLib 1)
dot As in the case of setProp and the dot operator’s similar functionality, getProp and the dot operator work in similar ways. The property must be there for it to work. It is more limited in use because, to use the dot operator, the property labels must be of the symbol data type. It does not work if the property labels are strings or integers.
Syntax: myList.propName
Because we used symbols in the getProp() example, we can rewrite it using dot notation. membList = [#happy: (member 1 of castLib 1), #sad: (member 2 of castLib 1)] put membList.happy -- (member 1 of castLib 1)
3486-6 ch12.f.qc
7/24/00
5:49 PM
Page 487
Chapter 12 ✦ Lists and Other Structures
getAProp( ) This function returns the value of the property. If the property does not exist, it returns . This can be useful if you deal with a void return value in your code.
Syntax: getAProp(myList, propName) myList.getAProp(propName)
Use getAProp() the same way as you would getProp(), or take advantage of the return value. on GoSomewhere aDest choices = [#Japan: 5, #China: 10, #HongKong: 15] myDestination = getAProp(choices, aDest) if myDestination = VOID then go to the frame else go to frame myDestination end if end
list operators — [ ] Just as setAProp and [] function similarly, so do getAProp() and []. The brackets return a property that is in the list or void if it does not exist.
Syntax: myList[propName]
The GoSomewhere handler in the getAProp() example can be rewritten using brackets to achieve the same functionality. on GoSomewhere aDest choices = [#Japan: 5, #China: 10, #HongKong: 15] myDestination = choices[aDest] if myDestination = VOID then go to the frame else go to frame myDestination end if end
487
3486-6 ch12.f.qc
488
7/24/00
5:49 PM
Page 488
Part III ✦ Learning to Program with Lingo
The case with symbols As stated in Chapter 11, the symbol data type in Lingo is not case-sensitive. If you try the following: put #SYMBOL = #symbol the result returns true. Nevertheless, sometimes the case does not appear the way you want it to. For example: set mySym to #Name put mySym -- #name set sym2 to #ASDF put sym2 -- #ASDF Yipes! What ‘s going on? Whenever you create a new symbol, your movie forever remembers it the way you first used it. Almost romantic, in a way, but it’ll drive the anal-retentives out of their minds. This issue can be serious if you are using the name of your properties in your formatting of output (by using getPropAt()). What can you do about it? Well, if the word you are using already exists in Lingo, such as name, then you are out of luck. If you create a word that is not in the Lingo lexicon, then it appears the way you first used it. In the preceding example, #ASDF always appears in all uppercase. put #asdf -- #ASDF It goes beyond Lingo words and symbols. Suppose that you have a handler called DumpList, and you have compiled the scripts, and then you type the following in the
Message window: put #dumplist -- #DumpList The case is the same as the handler’s. In fact, any variable name, local or global, sets the case. After you create a variable or handler, for example, you have set the case for the word. The only time this becomes obvious is in the case of symbols, because you can output them. Is there anything you can do — say, if you accidentally typed the following: put #jOhn -- #jOhn put #John -- #jOhn
3486-6 ch12.f.qc
7/24/00
5:49 PM
Page 489
Chapter 12 ✦ Lists and Other Structures
We admit it: We’re retentive types who had to figure out a way around this issue. If it is driving you nuts, too, you’ll be happy to know that there is a way to reset these values (except for the words that are part of the Lingo language). Here’s what we discovered that works:
1. Comment out all your scripts. 2. Save and compact. 3. Quit. 4. Relaunch. 5. Uncomment all your scripts. 6. Recompile all scripts.
Getting property information As mentioned earlier, it’s not generally recommended that you use positional information to retrieve entries in a property list. Nevertheless, sometimes you need a list of the properties in a property list. Because the repeat with...in syntax pulls out only values, not properties, you actually have to request the property at a specific position in the list in order to retrieve the property name. The getPropAt command takes two parameters: the property list name and the position within the list. It returns the property and associated data element located at that position. If you want to output all of the properties and their associated values to the Message window (frequently a useful technique for debugging problems in property lists), here is the dumpList handler to use for that task. You can use this command to get a “dump” of the contents of the product list in the Message window: product = [#name: “The Novaenglian Chronicles”, #picture: “NovChron1.jpg”, #ID: “BKSTR123NC12”, #category: “Science Fiction”, #price: 5.95, #description: “The rise of civilization in post-apocalyptic England.”] DumpList product -- “name: The Novaenglian Chronicles” -- “picture: NovChron1.jpg” -- “ID: BKSTR123NC12” -- “category: Science Fiction” -- “Price: 5.9500” -- “Description: The rise of civilization in post-apocalyptic England.”
489
3486-6 ch12.f.qc
490
7/24/00
5:49 PM
Page 490
Part III ✦ Learning to Program with Lingo
If you typed the property #name in a different case — for example, #NAME — and you are wondering why it appears as #name, see the earlier sidebar “The Case with Symbols.” You might wonder why the DumpList handler doesn’t just reference the data from its position, rather than from the property. Surprisingly, the answer is because it’s faster to do it from the property. The entries are internally referenced by property, and if we used the position, Lingo would have had to find the property corresponding to that position, and then retrieve the entry from the property. By using the property to get the data directly, we cut down on a step that Director would have done otherwise.
Setting values, revisited You can set a property by using the set the propertyName of myList to aValue. There are many other ways to set property values.
setAt This command works identically with both linear and property lists. See the discussion of setAt under “Setting Values” in the “Working with Linear Lists” section of this chapter.
setProp This command takes the name of the property to which you are giving a new value and sets it to that value. It causes an error if the property does not exist in the list.
Syntax: setProp myList, propName, aValue myList.setProp(propName, aValue)
The setProp command sets a property’s value to a new value: product = [#name: “Director”, #Version: 7.0] setProp product, #Version, 8.0 product.setProp(#Version, 8.0)
dots Using the dot operator works like the setProp command: The property must be there for it to work. It is more limited in use because, in order to use the dot operator, the property labels must be of the symbol data type. It doesn’t work if the property labels are strings or integers.
Syntax: myList.propName = aValue
3486-6 ch12.f.qc
7/24/00
5:49 PM
Page 491
Chapter 12 ✦ Lists and Other Structures
Rewriting the setProp example, using the dot example, can save some keystrokes. When you use this format, don’t put the # sign in front the of the symbol name. product = [#name: “Director”, #Version: 7.0] product.Version = 8.0 put product.Version -- 8.0
setAProp This command takes the name of the property to which you are giving a new value and sets it to that value. It adds the property to the list if it does not exist.
Syntax: setAProp myList, propName, aValue myList.setAProp(propName, aValue)
You can use this command to set existing properties, or you can use it to add ones that do not exist: product = [#name:”Freehand”] setAProp product, #name, “Director” setAProp product, #Version, 8.0 put product -- [#name: “Director”, #Version: 8.0] Note
Because an addProp command does exist, we don’t recommend using setAProp to create new properties. Someone who comes along later to modify your code might not understand that you are intentionally using it this way. It is clearer to use addProp when you want to add a property and setAProp (or setProp) when you want to set existing properties.
Caution
If you accidentally misspell the name of a property when using setProp, Director alerts you that something is wrong. If you use setAProp instead, then the misspelled property name is blithely added to the list and you are none the wiser until the misspelling generates a syntax error down the line or a value is not properly updated. Unless you have a strong reason for using the setAProp routine to create a property, you should use setProp instead.
[ ] — List Operators You can use the list operators [] with property lists as well as with linear lists. Where you would use an index with a linear list, you use a property name or an index. If the property does not exist in the list, it acts like the setAProp command, creating the property.
Syntax: myList[#propNameOrIndex] = aValue
491
3486-6 ch12.f.qc
492
7/24/00
5:49 PM
Page 492
Part III ✦ Learning to Program with Lingo
We can rewrite the setAProp example to use brackets. Like the dot operator, list operators save us some keystrokes: product = [#name:”Freehand”] product[#name] = “Director” product[#Version] = 8.0 put product -- [#name: “Director”, #Version: 8.0]
Adding an item to a property list In order to add an item to a list, use the addProp handler, passing to it the list, the property name (preferably as a symbol), and the entry.
Syntax: addProp myPropList, propName, aValue myPropList[propName] = aValue myPropList = [:] addProp myList, #Version, 8.0 addProp myList, #name, “Director” put myList -- [#Version: 8.0, #name: “Director”]
You can also do it this way: myList = [:] myList[#Version] = 8.0 myList[#name] = “Director” put myList -- [#Version: 8.0, #name: “Director”]
If the put myList instruction displays this result -- [#Version: 8.0000, #name:”Director”]
(with four digits after the decimal point), issue the set the floatPrecision to 2 instruction, and then issue the put myList instruction again. The new result is -- [#Version: 8.0, #name:”Director”]
Deleting properties With property lists, you have two options for deleting a property. You can delete by using the name of the property with the deleteProp command, or you can delete by index, using the deleteAt command.
3486-6 ch12.f.qc
7/24/00
5:49 PM
Page 493
Chapter 12 ✦ Lists and Other Structures
deleteProp This command deletes an item from a list. If the property does not exist, you do not get an error.
Syntax: deleteProp(myList, propName) myList.deleteProp(propName)
If you want to delete the category property from a product, for example, you can use the following syntax: put the category of product -- “Science Fiction” deleteProp product, #category put the category of product -- This puts up an alert box “Script Error: Property not found”
deleteAt This command works identically with both linear and property lists. See the discussion of deleteAt under “Deleting Items from Linear Lists” in the “Working with Linear Lists” section of this chapter.
Searching a dictionary list The property list has a complementary concept in other programming languages: the dictionary. With the dictionary approach, each property of an object or list is like a term in a dictionary. Properties equate to the words that are defined in a dictionary, and data elements equate to the definitions of those words in a dictionary. It is probably with this view in mind that the engineers at Macromedia created the findPos() and findPosNear() functions.
findPos The findPos() function requires two parameters: a property list and a symbol. It returns the position of that property within the list. If it doesn’t find the property, then the function returns a value of .
Syntax: findPos(myList, aValueOrProp)
This function is analogous to the getPos() function for entries. Here is findPos() at work: set myList to [“lions”, “tigers”, “bears”] put findPos(myList, “tigers”)
493
3486-6 ch12.f.qc
494
7/24/00
5:49 PM
Page 494
Part III ✦ Learning to Program with Lingo
-- 2 -- “tiger” is the second item in myList put findPos(myList, “cats”) -- 0 -- “cats” is not found so 0 is returned
Now look at findPos() in a property list: set myList to [#c: 33, #a: 82, #d: 64] put findPos(myList, #c) -- 1 -- #c is indeed in position 1 put findPos(myList, 64) -- -- returns because 64 is not a property in myList (even though it is a value at a property)
If you wanted to find the value 64 in the preceding property list, you could use the getPos() function. It does work based on value whether you are using it on a linear or property list.
findPosNear The findPosNear() function is a little more intriguing. In a sorted list, findPosNear() compares the passed symbol with all of the other symbols, and indicates what position the passed symbol would take if it were sorted into the list. The result implies that the property currently occupying that position would be the closest “match” to the passed symbol. This works especially well with “type-ahead” projects, such as a Help File Index, where the user of the product types in a string expression and the program returns the closest match.
Syntax: findPosNear(myList, aValueOrProp) Note
To use findPosNear(), you must first sort the property list. If the property list is not sorted, both functions return 0 for linear lists and the last position for property lists.
Here’s the preceding example, using findPosNear(): set myList to [“lions”, “tigers”, “bears”] put findPosNear(myList, “cats”) -- 0 -- returns 0 in unsorted list sort myList put myList -- [“bears”, “lions”, “tigers”] put findPosNear(myList, “cats”) -- 2 -- returns correct position in sorted list
When you use findPosNear on myList, and pass in “cats”, it returns 2. Why? Because if you were to add “cats” to myList, it would fall between “bears” and “lions” — in the second position.
3486-6 ch12.f.qc
7/24/00
5:49 PM
Page 495
Chapter 12 ✦ Lists and Other Structures
And in a property list: set myList to [#c: 33, #a: 82, #d: 64] put findPosNear(myList, #b) -- 4 -- last position because list is unsorted sort myList -- sorts by property, not value at property put myList -- [#a: 82, #c: 33, #d: 64] put findPosNear(myList, #b) -- 2 -- in sorted list it returns correct position. Tip
Here’s a good benchmark for deciding whether to use linear lists or property lists: If the positions of the items within the object are more important, as they would be in a trivia contest or card game, then use linear lists. If the characteristics of the object — the object’s name or description, for example — are more important, then your object should probably be defined as a property list.
Processing with Lists Lists can take a certain amount of effort to understand, but the work is generally worth it. Lists play a big part in any kind of database design, and many of the more useful properties in Director (such as the actorList, the windowList, and the scriptInstanceList) are linear lists. Lists are processed much more quickly than strings. They can be used to make lists that shadow text blocks; these can then be processed and transferred back to strings or text field entries. In this section, we demonstrate several useful routines for converting, processing, and otherwise manipulating lists.
Counting lists By counting in advance the total number of items in the list, you can avoid “index out of range” errors in functions such as getAt(). Let’s take a look at the count() and other list functions. Using the count() function, you can restrict the getAt() command to a value that is not less than 1 (item 1 in the list) and that does not exceed the total number of items in the list, thereby avoiding the ugly alert box. The function shown in Figure 12-4 returns the name of a specific day of the week, contained in the parameter whichDay, based on its position in the list. The handler effectively limits the value used by the getAt() function to a valid range (no more than the actual number of entries in the list). In this example, the getDaysOfWeek routine defines the daysOfWeek list and then checks to make sure that the day entered (whichDay) falls between 1 and the count of the number of items in the list, in this case 7. If it doesn’t, the routine displays a dialog box reflecting the bad day (and yes, we’ve had bad days like that, too) and then quits the program. Otherwise, the correct day of the week is returned.
495
3486-6 ch12.f.qc
496
7/24/00
5:49 PM
Page 496
Part III ✦ Learning to Program with Lingo
Figure 12-4: Using the count() function in a handler
You might wonder whether you are able to use this same technique using chunk expressions and items in a text string. The answer is yes you can, quite easily. String operations, however, are typically slower than the equivalent list functions — in some cases, an order of magnitude slower. Moreover, although this can be done with relatively simple text items, the more complex operations would become bogged down in chunk references. Whenever you see an operation that can be handled with text items, think about whether the actions can be transformed into list operations instead.
Converting a list to a string With lists, the string() function can convert even a very large and complex list structure into a string, making it useful for intermediate-term storage of lists beyond the scope of the movie. The converted information retains a certain amount of type information — for example, if you have a list of symbols, the function retains the symbol notation: daysOfWeek = [#Sun, #Mon, #Tue, #Wed, #Thu, #Fri, #Sat] put string(daysOfWeek) -- “[#Sun, #Mon, #Tue, #Wed, #Thu, #Fri, #Sat]”
The string() function performs a little magic on lists that contain strings. The function retains the quotation marks inside the list string, and the quotation marks, therefore, don’t wind up breaking up the string and generating an error: pets = [“cat”, “dog”, “fish”, “hamster”] put string(pets) -- “[“cat”, “dog”, “fish”, “hamster”]”
The value() function works in reverse of the string() — if you have a string in the shape of a list, the value() function converts it back into a list. This function can be very handy for storing list data, as long as the list data itself is relatively simple (that is, no lists within lists or objects within lists).
3486-6 ch12.f.qc
7/24/00
5:49 PM
Page 497
Chapter 12 ✦ Lists and Other Structures
pets = [“cat”, “dog”, “fish”, “hamster”] petString = string(pets) put string(pets) -- “[“cat”, “dog”, “fish”, “hamster”]” put value(petString) -- [“cat”, “dog”, “fish”, “hamster”]
You can get away with storing lists within lists as strings, but it is a less reliable operation. Lists that should convert to strings and back to lists occasionally become corrupted, while other seemingly improbable candidates go through the conversion process just fine. In general, you’re better off saving the data in some other format and then loading the lists later, rather than attempting to save a string-converted list for reconstitution later. Remember that when you convert lists to strings in this manner, the outcome may not be quite what you were hoping for. We have frequently found it necessary to take a multiple-line or multiple-item selection in a text member or field and convert it into a list, or vice versa. Although Director has no explicit routines to do this, writing your own is simple.
Converting items to a list You can use a scrolling field to create a list box. A list box is just a list of items on the screen; users can scroll through the list and select the item they desire. The text in the list box should not wrap. To implement a list box, your tasks include a lot of list-type activities, such as: ✦ Inserting items into a list ✦ Retrieving an item at a specific position ✦ Finding the position of an item in the list We need to create a list that corresponds to the list of items in the field. The first item in the list will correspond to the first item in the field, the second item in the list corresponds to the second item in the field, and so on. Using and manipulating the list is much faster than using chunk expressions to manipulate a string, and you have flexibility that is unavailable using only string functions. On the CD-ROM
The routines TextToList(), GetFolderList(), ListToText(), and AddTo SortedText are available on the CD-ROM for this book in the CHAPTER 12 folder. The LISTTOTEXT2.DIR file has the finished routines.
Two functions that are indispensable when working with shadow lists are the TextToList() and ListToText() functions.
497
3486-6 ch12.f.qc
498
7/24/00
5:49 PM
Page 498
Part III ✦ Learning to Program with Lingo
The TextToList() function, shown in Figure 12-5, takes as parameters a string or text field reference and an optional delimiter. The delimiter is included so that you can pull data out of a sequence of items as well as from lines of text. Normally, the routine defaults to the system item delimiter, typically a comma. You can convert lines of text into items in a list by passing RETURN as the delimiter. As Figure 12-5 shows, the code for the handler is relatively simple.
Figure 12-5: The TextToList() function
Almost all the code in the TextToList() function is devoted to making sure that the right delimiter is used. The code that reads items from a string or text field and adds them to a list takes up maybe five lines. Thus, to convert a sequence of items — say, animals at a pet store — into a list, all you need to do is to write the following code: strAnimals = “fish,cat,dog,hamster,snake,bird” listAnimals = TextToList(myAnimalStr, “,”) put listAnimals -- [“fish”, “cat”, “dog”, “hamster”, “snake”, “bird”]
As a more practical example, you can convert a file path into a list of folders (see Figure 12-6).
Figure 12-6: The GetFolderList function
3486-6 ch12.f.qc
7/24/00
5:49 PM
Page 499
Chapter 12 ✦ Lists and Other Structures
You can test this function in the Message window by using the following instructions (minus the lines of comments): -- The following is a Macintosh path because it uses colons as a path delimiter. myPath = “Hard Drive:Documents:Myfile” put GetFolderList (myPath) -- [“Hard Drive”, “Documents”, “Myfile”]
Alternatively, you can test it with one of Lingo’s functions or properties that evaluate to a path, such as the applicationPath: put GetFolderList(the applicationPath) -- [“Macintosh HD”, “Director 8”, “”]
Converting a list to items The inverse function, ListToText(), is a little more complex (see Figure 12-7). Because it is often used to output a list as a series of lines, the RETURN character is the default delimiter.
Figure 12-7: The ListToText() function
What we are doing in the repeat loop is adding the entry to a buffer, and then adding the delimiter. This works fine until the last entry: The disadvantage of the repeat with ...in loop is that there is no way to know when you have reached the last entry without comparing the entry, and that can add time to the routine. As a consequence, after all the entries have been added to the buffer, we remove the last delimiter from the end of the buffer, and then output the buffer as a string. Return to the list box concept. The following lines of code might be found in a button that reads the contents of one text box, “Name”, and then adds the contents, sorted, into the list of a second text box, “AllNames” (see Figure 12-8).
499
3486-6 ch12.f.qc
500
7/24/00
5:49 PM
Page 500
Part III ✦ Learning to Program with Lingo
Figure 12-8: Button behavior that uses both TextToList() and ListToText()
The sort algorithm that Director provides for lists is much faster than anything you could write to process text in Lingo — so much so that the time to convert to a list, sort the list, and convert back to text is negligible in comparison. Indeed, this particular routine is useful enough to convert to a standard handler (see Figure 12-9). Figure 12-9: Code from mouseDown (in Figure 12-8) turned into a standard handler.
The routine is then called from a mouseDown or mouseUp script of a button sprite with the field names as parameters. Figure 12-10 shows the routine being called from a mouseDown. Figure 12-10: AddToSortedText being used in mouseDown handler
There is no reason why the delimiter in the ListToText() function has to be a single character. If you want to output a list as a series of paragraphs with a line between each paragraph, call the function using this instruction: ListToText(myList, RETURN&”--------”&RETURN)
3486-6 ch12.f.qc
7/24/00
5:49 PM
Page 501
Chapter 12 ✦ Lists and Other Structures
Arithmetic with lists You can use the arithmetic operators (+, -, *, /) on lists as well. This feature is one of the cooler (though less intuitive) things built into Lingo: set list1 to [2, 2] put list1 + 3 -- [5, 5] put list1 * 4 -- [8, 8] put list1 * .6 -- [1.2000, 1.2000] put list1/0.5 -- [4.0000, 4.0000]
And you can even perform arithmetic on multiple lists: set list1 to [2, 2] set list2 to [3, 3] put list1 + list2 -- [5, 5] put list1 - list2 -- [-1, -1] put list1 * list2 -- [6, 6]
This holds true for property lists as well: set propList1 to [#a: 1, #b:2] put propList1 * 2 -- [#a: 2, #b: 4]
It really gets wild when you start adding property lists to linear lists: set list1 to [2, 2] set propList1 to [#a: 1, #b:2] put list1 + propList1 -- [[#a: 3, #b: 4], [#a: 3, #b: 4]] -- now let’s change the order of the addition put propList1 + list1 -- [#a: [3, 3], #b: [4, 4]]
Note how the positions of the operands make a difference in the results. Adding a linear list (list1) to a property list (propList1) results in a linear list of property lists. Adding the property list to the linear list results in a property list in which the property values are linear lists! It makes perfect sense after you think about it (and after your headache goes away).
501
3486-6 ch12.f.qc
502
7/24/00
5:49 PM
Page 502
Part III ✦ Learning to Program with Lingo
What about adding lists of differing lengths? In this case, the resulting list is truncated: set list1 to [1,2] set list2 to [1,2,3,4] put list1 + list2 -- [2, 4]
Is it a list? Sometimes you might need to check whether a variable is a list or not. Because variables in Lingo can hold any type of value, any type of data could be in that variable. You might be expecting a return value of a list and get , an integer, or perhaps a string. . There are two ways to approach testing.
listP( ) This function returns 1 if the value it is passed is a list (property or linear) and 0 if it is something else.
Syntax: listP(aValue) aValue.listP
The first version of the syntax is straightforward. The second one you need to be more careful with. If you add parentheses after aValue.listP, you get a syntax error. This is not consistent behavior when compared with other list functions, such as count(), where it does not matter whether you use parentheses with the dot notation. The P in the listP() function probably stands for predicate. In computer science, functions that return true or false are sometimes called predicates. Lingo has several other predicate functions for testing the type of a variable: integerP(), floatP(), stringP(), objectP().
ilk( ) The ilk() function is useful in determining the type of list a variable holds.
Syntax: ilk(myList) myList.ilk ilk(myList, #type) myList.ilk(#type)
The return value is a symbol if only a list is used as an argument. It returns a Boolean value if you pass in a second parameter.
3486-6 ch12.f.qc
7/24/00
5:49 PM
Page 503
Chapter 12 ✦ Lists and Other Structures
Using the preceding examples: put ilk(list1) -- #list put ilk(propList1) #propList
If you want a Boolean test to determine whether a list is a certain type, add an argument to the function: put ilk(list1, #linearList) -- 1 -- remember, 1 means TRUE put ilk(list3, #linearList) -- 0 -- and 0 means FALSE put ilk(list3, #propList) -- 1
Remember, the number 1 means TRUE and 0 means FALSE. And you can be a little more general in your testing by just testing whether it is a list, which is an alternative to using listP(): put ilk(list3, #list) -- 1 put ilk(list1, #list) -- 1
Joining two lists Lingo does not have a “join” or “combine” command. There are times when such a command would be useful. Fortunately, it is easy to write a function that does this (see Figure 12-11). Figure 12-11: The JoinLists() function illustrates how to combine two lists, property or linear.
503
3486-6 ch12.f.qc
504
7/24/00
5:49 PM
Page 504
Part III ✦ Learning to Program with Lingo
JoinLists() takes two lists as parameters. It tests them to see if they are both
the same kind. If they are not, an alert pops up and the program halts. If they are of the same type, then a new, empty list is created. This is why we need to test for the type — to know what kind of list to create. We need to create a new list so that we do not alter list1 or list2. We then return the new, combined list.
Creating a Simple Address Book Program Lists are perfect for creating small databases. An address book is essentially a database of names and addresses. This program is not full-featured, but more a vehicle to show you how to use lists. After it’s complete, you can extend the program if you want; we’re sure you’ll see many ways to improve it. It also gives you ideas on how to trap user input, instead of keeping track of names and addresses — maybe you are gathering information from users in the form of a test or questionnaire. On the CD-ROM
You can find the completed addressbook.dir movie on the accompanying CD-ROM in EXERCISE:CH12 (EXERCISE\CH12).
The program features three different screens, each one on its own frame. One is for browsing the data, one is for editing it, and one is for creating new entries. Essentially, the three screens are the same except for the buttons at the bottom. Each screen has a name, street, city, state, and zip field (see Figure 12-12). Add Browse, New, and Edit markers to frames 1 to 3, respectively. For each of the fields for input — Name, Street, City, State, and Zip — create a text cast member, and draw them right on the Stage so that they occupy sprites 1 through 5. Name each one as we did (see Figure 12-13). Then create another text cast member that holds the bold type. Extend these sprites so that they span all three frames. Last, add the buttons. To frame Browse, add Edit, New, Prev, and Next. On frame New, put Done and Cancel. On frame Edit, add Done, Cancel, and Delete. It is important that the Done button be a separate sprite in frames New and Edit. Cancel can span both of those frames because it has the same functionality for both.
3486-6 ch12.f.qc
7/24/00
5:49 PM
Page 505
Chapter 12 ✦ Lists and Other Structures
Frame "Edit" (Frame 3) Frame "New" (Frame 2) Frame "Browse" (Frame 1)
Figure 12-12: All three screens are shown here at the same time. All look the same, except for the bottom buttons. In the program, you view only one screen at a time.
Script channel for frame behaviors Zoom menu (this score is set to 1600%)
Buttons
Text members used for adding, editing and displaying each record
Text member Figure 12-13: The Score of addressbook.dir with the Sprite Toolbar and the effects channels hidden, so that the Score does not take up as much space.
505
3486-6 ch12.f.qc
506
7/24/00
5:49 PM
Page 506
Part III ✦ Learning to Program with Lingo
Next, add functionality to the buttons — eight button behaviors in all. The first six are quite simple (see Figure 12-13). Try to keep the code simple so that it can be easily transferred to more complex sprite button behaviors. For this example, you are using the button from the Tool palette. This type of button is good for creating quick prototypes, but graphic designers tend to cringe at their usage. One way to keep the code simple is to have it call a movie script. This enables you to design the program from the top down. The bottom three scripts in Figure 12-14 are calling handlers that you haven’t written yet, but it is easy to guess their functionality. It also enables you to easily move the code to another behavior, if necessary; all you have to move is one statement.
Figure 12-14: Six of the eight sprite behaviors for this movie that have been applied to buttons.
We begin all of the sprite behavior names with the prefix “B_”, which stands for behaviors. We begin all of the frame behaviors with “Frame:”. This works well when we select all of the scripts in the cast window and then sort them by name (Modify ➪ Sort). This way, they appear in the Behaviors pop-up menu in alphabetical order and are grouped by how they are used (either on frames or sprites), as shown in Figure 12-15. Another trick is to add two carriage returns at the top of each script window, so that part of the script does not appear in the Behaviors pop-up menu.
3486-6 ch12.f.qc
7/24/00
5:49 PM
Page 507
Chapter 12 ✦ Lists and Other Structures
Behaviors pop-up
Figure 12-15: By using naming conventions and sorting cast members, you can make your behaviors pop-up menu more readable.
The Next and Prev button behaviors are a little more complicated, but each is almost identical to the other. They check each time there’s an exitframe message to see whether they should be visible. If you’re on the first record, you don’t want the Prev button to be visible. The same is true for the Next button when you are on the last record. On a mouseUp, the B_Prev script passes a –1 as an argument to the ChangeRecord handler, as shown in Figure 12-16. Think of -–1 as going to the left, or previous record. B_Next does the same, except it passes a 1. The three frame behaviors are shown in Figure 12-17. For the Browse frame, it needs to set the five text cast members to a non-editable state; these members are in sprites 1 to 5. Then it calls ChangeRecord and sets it to the current record. Zero is passed in ChangeRecord, which means it is not incrementing or decrementing the record you are viewing. The scripts for the Edit and New frames each need to make the text cast members editable. The New frame also needs to clear those members out by putting an empty string in each.
507
3486-6 ch12.f.qc
508
7/24/00
5:49 PM
Page 508
Part III ✦ Learning to Program with Lingo
Figure 12-16: The Prev and Next buttons have nearly identical code.
Figure 12-17: The three frame scripts each loop on the frame but they vary in their beginSprite handlers.
3486-6 ch12.f.qc
7/24/00
5:49 PM
Page 509
Chapter 12 ✦ Lists and Other Structures
Our last task is the Movie scripts. Now we’ll finally see how to work lists and list operations into this program! The program starts by checking to see whether gAddressBook was initialized, and if it wasn’t initialized, it puts some dummy information into the variable. This information comes from the GetStarterList() function. GetStarterList() returns a linear list that is full of property lists. Each property list represents one record. After that, gIndex is initialized to 1. Because we are starting the program, we start on the first record. Figure 12-18 shows what the handlers should look like.
Figure 12-18: The prepareMovie handler checks to see whether gAddressBook was initialized, and if it wasn’t initialized, it puts in a few dummy records.
Those aren’t all the movie scripts — you have to contend with a few more. The ChangeRecord handler is called from three different spots; see Figure 12-19 for the handler’s definition. The first thing that happens in ChangeRecord is that the global variable gIndex is changed by adding the value of the parameter dir (short for direction). Then aRecord gets a reference to one of the property lists within the linear list gAddressBook. Each property list within gAddressBook has five elements. We loop five times: the first time setting the text of the member of sprite 1 to the value at position 1 in the property list aRecord; the second time setting the text of the member of sprite 2 to the value at position 2 in the property list aRecord; and so on through position 5. Figure 12-19: ChangeRecord fills the text cast members with the information from the current record.
509
3486-6 ch12.f.qc
510
7/24/00
5:49 PM
Page 510
Part III ✦ Learning to Program with Lingo
The last four movie handlers to be created are interesting because three of them mimic list commands (see Figure 12-20). Figure 12-20: Three of these handlers bear names similar to list commands, and their functionality is quite similar.
The GetFieldInfo() function gets the value of the five text cast members. We call it GetFieldInfo() because the text cast members are being used like fields in a database. Calling it GetFieldInfo() seemed like it would be doing something different. This function gets the text and puts it into a property list, with property labels that correspond to the data they hold. Realistically, it could have been made into a linear list, because for this limited program we are referencing values by position. However, making it a property list makes the code more readable, easier to debug, and anticipates expanding the code at a later point, when you may be accessing only certain values from each property list. The remaining three handlers — AppendRecord(), SetRecord(), and Delete Record() — do for our little database what append, setAt, and deleteAt do for lists. AppendRecord() is called from the script B_New Done on the Done button in the New frame. It gets a property list of the new data from GetFieldInfo() and puts it at the end of the gAddressBook list. Then it increments gIndex and goes to the
Browse frame. SetRecord() is called from the script B_Edit Done on the Done button in the Edit frame. It gets a property list of the new data from GetFieldInfo() and sets that property list on top of the old list that was in the same position. Then it goes to the Browse frame.
3486-6 ch12.f.qc
7/24/00
5:49 PM
Page 511
Chapter 12 ✦ Lists and Other Structures
DeleteRecord() is called from the script B_Delete on the Delete button in the Edit frame. It deletes the current record from gAddressBook. It knows which to delete
because we have been keeping track of which one we were on by incrementing/ decrementing gIndex. That’s it! There are many things this example does not do that would be useful. It would be nice, for example, to save information, copy and paste in fields, and check for errors in the last element in the list. Still, this example does illustrate: ✦ How to iterate through lists ✦ How to input user information into a list, store it, retrieve it, and delete it ✦ How to write many small behaviors and handlers ✦ How to use many of the control structures discussed in the preceding chapter, such as repeat loops, if...then, and if...then else ✦ How to navigate Lingo (such as go) to jump between frames or stay on the same frame ✦ How to change text members through Lingo ✦ How to declare and use global (and local) variables
Points and Rects Lingo supports two data structures that are common in graphics: points and rects. These two data types also are considered lists by the ilk() function and can perform many list operations.
Points Points are x and y coordinates. The first number in a point is the x coordinate, or locH. The second number is the y coordinate, or locV. As you learn in Chapter 15, locH and locV are sprite properties. They reflect the sprite’s location on a twodimensional plane. An easy way to remember this is loc is short for location. H and V are short for horizontal and vertical, respectively. A point is a data structure that you can put into a variable and manipulate. When you get the loc of a sprite, it returns a point. Try throwing a sprite on the Stage and type the following in the Message window: put the loc of sprite 1 -- point(246, 126)
511
3486-6 ch12.f.qc
512
7/24/00
5:49 PM
Page 512
Part III ✦ Learning to Program with Lingo
The point you get is most likely different from the one we got, but you should be able to tell it is returning the location of the sprite. Now put it into a variable: put the loc of sprite 1 into myLoc put myLoc -- point(246, 126)
The myLoc variable now holds a point. It happens to be the loc of sprite 1. If we alter the value of myLoc, it does not have any effect on sprite 1 until we actually reset the loc of sprite 1 to myLoc. (We’ll do more of that in Chapter 15. For now, we are concerned with the data.) The point data type looks a lot like the list type when you use parentheses instead of brackets. Points are considered both a data type and a function in Lingo. Suppose that you want to create a point based on variable values: set x to 12 set y to 342 set myPoint to point(x, y) put myPoint -- point(12, 342)
Every point has a locH and locV that can be retrieved by using the property names: put the locH of myPoint -- 12 put myPoint.locV -- 342
Another common use is to store the location of the mouse. This is useful in conjunction with rects, which you’ll see in a moment: set myLoc to the mouseLoc
Because it has properties, you might think you can use getProp() on it to retrieve the value. This does not work because it is not considered a property list. You can, however, use getAt(), getPos(), getOne, and getLast(): put getAt(myLoc, 1) -- 246
The same holds true for setAt: setAt myLoc, 1, 100 put myLoc -- point(100, 246)
3486-6 ch12.f.qc
7/24/00
5:49 PM
Page 513
Chapter 12 ✦ Lists and Other Structures
As with lists, you can perform arithmetic on them: put myLoc + 10 -- point(110, 256)
Rects A rect (short for rectangle) is a structure that contains four numbers, which represent the left, top, right, and bottom sides of the rectangle. Where points have the properties locH and locV, rects have the properties left, top, right, and bottom. The first number represents the position of the left side of the rectangle, the second is the top, the third is the right, and the fourth number is the bottom.
Syntax: rect(left, top, right, bottom) rect(point1, point2)
Put a sprite on the Stage and then type in the Message window: set myRect to the rect of sprite 1 put myRect -- rect(114, 75, 238, 199)
Rects, like points, are considered both a data type and a function in Lingo. To get or set the individual values, type code like the following: put the right of myRect -- 476 put the top of myRect -- 150
With rects, you can do arithmetic on them, just as you can with lists: put myRect -- rect(228, 150, 476, 398) put myRect + 2 -- rect(230, 152, 478, 400) put myRect * 3 -- rect(684, 450, 1428, 1194) put myRect * 1.2 -- rect(273.6000, 180.0000, 571.2000, 477.6000) put myRect + myRect -- rect(456, 300, 952, 796)
513
3486-6 ch12.f.qc
514
7/24/00
5:49 PM
Page 514
Part III ✦ Learning to Program with Lingo
Four numbers can define a rect, but two points can also define a rect. The points do not remain points; they convert to left, top, right, and bottom values. put rect(the loc of sprite 1, the mouseLoc) -- rect(57, 50, 324, 217)
Rects are often used to hold the dimensions of sprites or members. You can use the same list functions that work with points: getAt(), getPos(), getOne, getLast, and setAt. But rects are not limited to these functions. There are several rect functions: ✦ inflate() ✦ inside() ✦ intersect() ✦ map() ✦ offset() ✦ union() It is important to remember that a rect is just a structure in memory; you do not see visuals on the Stage when you use them (unless you are setting a sprite’s rect to the rect in your variable).
inflate( ) You use this function to increase (or decrease) the size of a rect around its center.
Syntax: inflate(myRect, horz, vert) myRect.inflate(horz, vert)
Although rects are just structures in memory, it helps to visualize what happens with these functions. In Figure 12-21, the gray rectangle represents the original rect and the black rectangle represents the rect returned by the function (after it’s been enlarged). The horz and vert values are how much each side moves. So, if you pass a 10 in the horz spot, the overall width of the rect is 20 (the left side moves 10 and the right side moves 10).
Rect returned from inflate () Original rect
Figure 12-21: Inflating a rect
3486-6 ch12.f.qc
7/24/00
5:49 PM
Page 515
Chapter 12 ✦ Lists and Other Structures
You might think this is unnecessary because you can do arithmetic on rects. But consider the following: put rect(0, 0, 160, 120) + 10 -- rect(10, 10, 170, 130)
You didn’t make it bigger, you just moved it 10 to the right and 10 downward. You could set each of the individual values to make it larger, but that is unnecessary given this function: put inflate(rect(0,0,160,120), 10, 10) -- rect(-10, -10, 170, 130)
You can also use inflate() to shrink rects; just pass in negative values: put inflate(rect(0,0,160,120), -10, -10) -- rect(10, 10, 150, 110)
inside( ) We use this function often to create clickable areas in movies where there is no sprite. It checks to see if a point is inside a rect.
Syntax: inside(myPoint, myRect) myPoint.inside(myRect)
Perhaps now that we have up to 1000 sprite channels, we might not use this function as often. Still, it is more memory efficient than using a cast member in a sprite channel. So, if you are aiming for speed or size, this is one way to go. Figure 12-22 provides an example of a frame behavior.
Figure 12-22: Creating a clickable area without a sprite
515
3486-6 ch12.f.qc
516
7/24/00
5:49 PM
Page 516
Part III ✦ Learning to Program with Lingo
This example can be expanded to take advantage of your knowledge of repeat loops and lists. Figure 12-23 shows the expanded version (with comments). Now we have a linear list of rects — myRectList — that we loop through each item in the list, using a repeat...while loop. If you click a hot spot, it gives an alert and the rect data.
Figure 12-23: Testing for various hot spots on the Stage
intersect( ) This function returns a rect, and the dimensions of the rect are the size of the overlap between two rects. If the two rects do not intersect, then rect(0, 0, 0, 0) is returned.
Syntax: intersect(rect1, rect2) rect1.intersect(rect2)
In Figure 12-24, the gray squares represent rect1 and rect2. The black square represents the return value (a rect). Imagine if the two gray squares were not touching, there would be no intersecting rect to return. That explains the return value rect(0, 0, 0, 0) — a rect of no dimension. Create some rects in the Message window by typing the following code: rect1 = rect(50, 50, 100, 100) rect2 = rect(75, 75, 200, 200)
Test whether they intersect, as follows: put intersect(rect1, rect2) -- rect(75, 75, 100, 100)
3486-6 ch12.f.qc
7/24/00
5:49 PM
Page 517
Chapter 12 ✦ Lists and Other Structures
Rect returned from intersect () rect1
rect2
Figure 12-24: The result of two rects intersecting
You can do this with dot notation if you prefer: put rect1.intersect(rect2) -- rect(75, 75, 100, 100)
Now create a third rect that does not overlap rect2: rect3 = rect(200, 200, 300, 300) put intersect(rect2, rect3) -- rect(0, 0, 0, 0)
map( ) This function takes a point or rect in one rect (the second argument) and returns the point or rect relative to the other (the third argument).
Syntax: map(point1, rect1, rect2) map(rect1, rect2, rect3) On the CD-ROM
If you prefer not to follow the steps, refer to map.dir in the EXERCISE:CH12 (EXERCISE\CH12) folder on the accompanying CD-ROM.
This example requires a few steps, so follow along: 1. Using the rectangle shapes from the Tool palette, create two rectangles on the Stage. 2. Create a bitmap dot and put it in sprite 3. We’re using a bitmap so that we can center the regPoint of the member. Your screen should look like Figure 12-25. 3. Create the frame behavior shown in Figure 12-26.
517
3486-6 ch12.f.qc
518
7/24/00
5:49 PM
Page 518
Part III ✦ Learning to Program with Lingo
rect1 has same values as this rectangle rect2 has same values as this rectangle
Figure 12-25: Layout of the Stage
Figure 12-26: Frame behavior using the map() function when the mouse is clicked
4. Click the Recompile All Scripts button. 5. Play the movie (Control ➪ Play). 6. Now click around in the small rectangle. Note how the sprite moves around in the relative location in the larger rectangle. On the CD-ROM
The CD-ROM that accompanies this book contains a file called map2.dir in the EXERCISE:CH12 (EXERCISE\CH12) folder that illustrates an alternative approach, in which we specify rects in the code, using an image of two boxes.
This exercise illustrates another aspect of the map() function: The two rectangles do not have to be similar in proportion. As you might have noticed in Figure 12-27, we simply picked up the rects of the sprites.
3486-6 ch12.f.qc
7/24/00
5:49 PM
Page 519
Chapter 12 ✦ Lists and Other Structures
offset( ) The offset function enables you to change a rect’s position. It returns a rect that has its left and right, or its top and bottom, or both, properties modified.
Syntax: offset(myRect, horz, vert) myRect.offset(horz, vert)
In Figure 12-27, the gray square represents the rect passed into the function, and the black square represents the rect returned by the function. In this case, the rect is being shifted more to the right than down. If you wanted to move the invisible hot spot created in Figure 12-22, offset() is the function to use: myRect = rect(0, 0, 100, 100) put offset(myRect, 20, 50) -- rect(20, 50, 120, 150)
Original rect
Rect returned from offset ()
Figure 12-27: Moving a rect
union( ) This function returns a rect that encompasses both of the rects passed in.
Syntax: union(rect1, rect2) rect1.union(rect2)
In Figure 12-28, the gray squares represent rect1 and rect2, and the black square represents the return value (a rect). Note that the rect returned is the smallest possible rect that can enclose the two: set rect1 to rect(57, 50, 84, 77) set rect2 to rect(62, 127, 117, 176) put union(rect1, rect2) -- rect(57, 50, 117, 176)
The union() function does not require that the two rects touch.
519
3486-6 ch12.f.qc
520
7/24/00
5:49 PM
Page 520
Part III ✦ Learning to Program with Lingo
Rect returned from union () rect1
rect2 Figure 12-28: The union of two rects
Converting between rects, points, and lists You can do arithmetic operations between rects, points, and lists. The first operand dictates the type of the resulting value. If you add a rect and list, you get a point. If you add a list and a rect, you get a rect. The following code illustrates this in the Message window: put rect(1, 2, 3, 4) + [1, 2, 3, 4] -- rect(2, 4, 6, 8) put [1, 2, 3, 4] + rect(1, 2, 3, 4) -- [2, 4, 6, 8] put point(1, 2) + [3, 4] -- point(4, 6) put [3, 4] + point(1, 2) -- [4, 6]
The data type you use first is the type you are returned. This is not the case when you add rects and points: put rect(1, 2, 3, 4) + point(1, 2) -- [2, 4] put point(1, 2) + rect(1, 2, 3, 4) -- [2, 4]
The result is a list whenever you add a rect and a point. This also occurs when you add rects or points to lists that have a different number of elements than the rect or point, as follows: put rect(1, 2, 3, 4) + [1,2] -- [2, 4] put [1, 2] + rect(1, 2, 3, 4) -- [2, 4]
3486-6 ch12.f.qc
7/24/00
5:49 PM
Page 521
Chapter 12 ✦ Lists and Other Structures
Colors The rgb and paletteIndex color data structures are new types in Director. Where the ilk function identifies rects and points as lists, it does not see rgb colors as lists. Nevertheless, you can treat them like lists in many ways. You can’t use any of the get and set functions, but you can do arithmetic operations on them, and you can access the red, green, blue properties in a way similar to accessing to property lists.
Syntax: color(#rgb, r, g, b) color(#paletteIndex, index) rgb(hexStr) rgb(r, g, b) paletteIndex(index)
When you create a new color with the color function, the value returned is of the type #rgb or #paletteIndex. It is in the form rgb(r, g, b) or paletteIndex(index), respectively. Now do a little color experimentation: set newColor to color(#rgb, 204, 55, 20) put newColor -- rgb( 204, 55, 20 ) put newColor.red -- 204 put the blue of newColor -- 20 put newColor.colorType -- #rgb put newColor.hexString() -- “#CC3714” put newColor.paletteIndex -- 65 set palColor to color(#paletteIndex, 35) put palColor -- paletteIndex( 35 )
When you get the paletteIndex of an rgb color, the index of the closest color on the current palette is returned. In this case, we are using the System-Mac color palette. You can force an rgb color-type to the paletteIndex color-type. Watch out, though, when you convert to a palette and then back to an rgb, because you most likely
521
3486-6 ch12.f.qc
522
7/24/00
5:49 PM
Page 522
Part III ✦ Learning to Program with Lingo
won’t get the same color back. Continuing with the preceding example, note how newColor — when converted to #paletteIndex and then back to #rgb — has had its green and blue values change: newColor.colorType = #paletteIndex put newColor -- paletteIndex( 65 ) newColor.colorType = #rgb put newColor -- rgb( 204, 51, 0 )
If you start with the paletteIndex, convert to rgb, and then convert back, you won’t lose any information, because the palette colors are a subset of the rgb colors: newColor = paletteIndex(35) newColor.colorType = #rgb put newColor -- rgb( 255, 0, 0 ) newColor.colorType = #paletteIndex put newColor -- paletteIndex( 35 )
The results of arithmetic operations are from 0 to 255. The result does not exceed 255, nor is it less than 0. Additionally, values are always integers (note how 55, the green value in the following example, is evaluated to 27 after it is multiplied by .5). set newColor to color(#rgb, 204, 55, 20) put newColor * .5 -- rgb( 102, 27, 10 ) put newColor * 100 -- rgb( 255, 255, 255 ) put newColor * -1 -- rgb( 0, 0, 0 )
You can use these values to change the color of sprites. It works best on sprites whose member is a 1-bit bitmap. It also works well on fields and text cast members, as well as on shape or vector members.
Dates Lingo now sports a date format. Like colors, the date data type is not identified as a list by the ilk function. Nevertheless, it, too, shares many list-like qualities.
Syntax: date(string) date(integer) date(year, month, day)
3486-6 ch12.f.qc
7/24/00
5:49 PM
Page 523
Chapter 12 ✦ Lists and Other Structures
The parameters for the date format must be in the following format: put date(“20000601”) -- date( 2000, 6, 1 ) put date(20000601) -- date( 2000, 6, 1 )
Regardless of which format you use, a date structure is returned. But you must always put it in the year, month, day format: set myDate to date(2000, 6, 1) put the year of myDate -- 2000 put myDate.month -- 6
One of the neat things that you can do with dates is to add or subtract them: set xmas to date(2000, 12, 25) set myDate to date(2000, 6, 1) put xmas - myDate && “of days until Christmas!” -- “207 of days until Christmas!”
Another interesting feature of dates is when you put a wrong one. For example, June only has 30 days. Look what happens when we enter 31: put date(2000, 6, 31) -- date( 2000, 7, 1 )
It rolled over to reflect an actual date. It works for months as well: put date(2000, 13, 1) -- date( 2001, 1, 1 )
Summary Before you continue and create parent scripts and child objects in Chapter 13, recall some of the things that this chapter revealed about lists: ✦ Lists are collections of data that can be stored in a single variable. ✦ There are two kinds of lists: linear and property. ✦ You access linear lists by position. You access property lists by position or property name. ✦ There are many ways to get and set list values.
523
3486-6 ch12.f.qc
524
7/24/00
5:49 PM
Page 524
Part III ✦ Learning to Program with Lingo
✦ Processing items in lists is much faster than processing items in strings. ✦ You can manipulate rects and points like lists, and they have many functions of their own. ✦ Colors and dates are complex structures that have some similarity to lists. Chapter 13 discusses using Lingo for object-oriented programming.
✦
✦
✦
3486-6 ch13.f.qc
7/24/00
5:49 PM
Page 525
13 C H A P T E R
Object-Oriented Programming with Lingo
I
f you’re new to programming, it probably won’t help to compare and contrast object-oriented programming (OOP) with structured programming. OOP is a method of solving a logical problem. It’s a way of thinking about the problem at a higher level — closer to how humans think. While OOP sometimes takes a little extra coding, you might find it makes programming significantly easier. Suppose that you want to create a space game. In it, there’s a spaceship, big rocks, small rocks, and laser pulses. The spaceship has weapons, engines, and shields. The weapons might be variable: You might be able to have more than one or only one. Those things, in turn, have actions that they can take. A ship can fly, shoot, be hit, and explode. Note how you are thinking about the game. You’re not thinking in terms of sprites, the Score, handlers, and functions. You are thinking about things — objects.
What Is Object-Oriented Programming? The idea of OOP has been around since the late 1960s, so it is not a new idea, but it has gained widespread popularity in the last ten years or so. With OOP, you create structures in memory that model real-world objects. The object is the basis of OOP. To be considered object-oriented (OO), a language should support abstraction, encapsulation, inheritance, and polymorphism.
✦
✦
✦
✦
In This Chapter Lingo as an object-oriented programming tool Relationships: Parent scripts, child objects, and ancestors Building child objects in memory Creating multiple child objects from a single parent script Using the actorList
✦
✦
✦
✦
3486-6 ch13.f.qc
526
7/24/00
5:49 PM
Page 526
Part III ✦ Learning to Program with Lingo
Abstraction Abstraction is another term for getting away from the details. A computer, for example, is an abstraction of a monitor, box (CPU), and modem. A monitor is an abstraction of glass, wires, plastic, and metal. When you think of a computer, you don’t think of it as chips, wires, metal, and plastic; instead, you group all of that together and think of it as the item called a computer. The computer has functionality that comes along with that thinking. You can create files and directories, you can run programs, and you can communicate via the modem. Object-oriented programming enables you to think at a higher level (more abstract), which makes problem solving simpler. In the space game mentioned earlier, you think about the spaceship moving through space, avoiding rocks, and you think about rocks being hit and broken by laser pulses. It is much easier to design and discuss the desired functionality of your program by thinking like this than by talking about a sprite of a bitmap cast member changing its loc every exit frame while watching for collisions. You still have to handle that sort of detail at some point, but that’s after you know how things in the program should interact.
Encapsulation Encapsulation is hiding information. The idea of encapsulation is that your object contains data that only it can access through its own handlers. Some languages enable the programmer to enforce encapsulation by enabling the programmer to define some of the data as touchable only by the object itself. Lingo does not support this technique; any encapsulation you do with Lingo is by design. Encapsulation of data has benefits in protecting an object from having its data incorrectly changed from outside sources. By not exposing the data, you also prevent errors to outside sources reading incorrect data. Good encapsulation can make bug tracking easier, because you have a better idea of where to look for the problems. It also makes changing the program easier. If you want to change what your spaceship’s weapon does, you just look in the script for the weapon and change it. You don’t need to search through a bunch of disparate handlers, looking for references to your weapon — you know exactly where to find them.
Inheritance Inheritance is the capability of an object to inherit data and actions from another object. With inheritance, you can define objects that are very general and have common functions such that classes that are more specific could inherit the common functionality and have additional functionality. Lingo supports inheritance through an object’s ancestor property.
3486-6 ch13.f.qc
7/24/00
5:49 PM
Page 527
Chapter 13 ✦ Object-Oriented Programming with Lingo
Polymorphism Polymorphism refers to having different objects with the same interface, but the implementations are different. Suppose that you had car and plane objects, and each of these understands the move command. When you tell the car to move, it drives. When you tell the plane to move, it flies. Each knows how to move, but each moves in a different way. You don’t need to know the details of how they move; you just need to know that they can move.
Parent Scripts and Child Objects Objects, such as lists and rects, are not something you see on the Stage. They are structures in memory. In Lingo, objects made from parent scripts are called child objects. Parent scripts are like templates: They tell you what properties and handlers an object has. When you create an instance (child object) of a parent script, you give that instance values for the properties.
Comparisons with C++ Lingo implements objects in more than one way. First, Lingo uses parent scripts to create child objects. If you’re coming from another object-oriented programming language, such as C++ or Java, this approach might seem the most familiar to you. Check out Table 13-1 for some similarities between C++ and Lingo. In OOP, objects combine data with actions. In Lingo terms, variables are the data and handlers perform the actions. Let’s start with the most basic object you can create (see also the sidebar “new( ) versus rawNew( )” below).
Table 13-1 Lingo OOP and C++ Comparisons Lingo
C++
Notes
Parent script
Class
The parent script is different from other movie scripts because the cast member must be named (to be called by the new function) and contain a new handler with instructions for creating an object. It also can contain property declarations.
Child object
Class instance
A child object can have properties, and it can be controlled and modified by using Lingo scripts. Child objects exist only in memory, not in the Score or cast. Continued
527
3486-6 ch13.f.qc
528
7/24/00
5:49 PM
Page 528
Part III ✦ Learning to Program with Lingo
Table 13-1 (continued) Lingo
C++
Notes
Property variable
Instance variable
Handler
Method
A property variable is the parent script’s equivalent of a global variable. Property variables persist after the parent script handler executes — just like global variables. Further, each child object can maintain its own values for each property variable. In other words, each child object (though created from the same parent script) can assign different data to the same property variables. A handler in a parent script is no different from a handler in a movie script. The structure, functions, keywords, commands, and instructions available are common to all Lingo handlers. Most of the time, the first parameter of a parent script handler is the variable me.
Me
this
me is a reference to the child object.
Ancestor
Superclass
ancestor is an object property used to enable child objects to inherit handlers and properties from other objects. It contains a reference to another child object.
Creating an Object 1. Open a new script window by pressing Command+0 (zero) or Ctrl+0 (zero). 2. Click the Cast Member Properties button to open the Property Inspector. 3. Select Parent from the Script Type pop-up menu under the Script tab in the Property Inspector. 4. Name the member basic in the Name field. 5. Click OK. 6. Type in the script window exactly what is in Figure 13-1. Figure 13-1: The world’s most basic parent script
3486-6 ch13.f.qc
7/24/00
5:49 PM
Page 529
Chapter 13 ✦ Object-Oriented Programming with Lingo
The basic parent script has only one handler, the new function. We know new is a function because of the return statement: It returns a value. The new function has one parameter: me. This is a Lingo convention, calling the first parameter of a parent script handler me. It can really be any name, but it will be less confusing if we stick to the convention. The me parameter is a reference to this object. In the Message window, type the following: myObj = new(script “basic”)
When you call the new function of the script basic, (script “basic”) is the argument to that function. Director creates a unique instance of this script in memory. Now type this: put myObj --
Note the result when you used the put command on myObj. It puts the reference to the object, which tells you it is an offspring (a child) of the parent script basic. The last item, 2838d70, is a unique identifier for this object. It will be different on your machine, and different every time you create a new object.
What are objects? Objects are very similar to property lists. A good way to understand what an object is and why you’d want to bother with one is to start with a property list. The address book program in Chapter 12 uses property lists. Each list has the format [#name: “”, #street: “”, #city: “”, #state: “”, #zip:””]. In the address book program, we created a list of these lists, but for now, just create a single variable holding one of these person lists, as follows: JohnDoeList = [#Name: “John Doe”, \ #Street: “123 Main St. “, \ #City: “Anytown”, \ #State: “CO”, #Zip: “12345”]
To put this list into five different text cast members, it was necessary to call a handler in a separate movie script. That handler was written to deal with that kind of script. It won’t work with a list that has different property names. It is tailored for the address book record list. Another problem is that the handler is separated from the data on which it acts. Those two pieces of the program are somewhat separate, yet they are tightly interdependent. You can also create more handlers to deal with this kind of list. Those, too, would go in movie scripts and might be interspersed with other movie script handlers that have nothing to do with this kind of list. In other words, this situation calls for an object.
529
3486-6 ch13.f.qc
530
7/24/00
5:49 PM
Page 530
Part III ✦ Learning to Program with Lingo
new() versus rawNew() Director 8 introduces the rawNew() function. Using rawNew(), you can create an instance of a parent script without invoking its new() handler. This method is about 50 percent faster than creating an instance using the most basic new() handler. So, technically, the most basic parent script is an empty one! A script can be instantiated by using new() even if it does not have a new() handler. If you compare the speed of creating instances by using new() without the new() handler in the script versus rawNew(), you’ll still find rawNew() to be about 10 percent faster. Why would you want to bypass the new() handler? Suppose that you want to create hundreds of instances of objects, but do not need to initialize their properties until later, on an individual basis. Using rawNew() would be a much more efficient way to do it. Then you can call the new() handler when you want to or you can directly initialize properties.
Creating a Parent Script for Person Objects 1. Open a new script window by pressing Command+0 (zero) or Ctrl+0 (zero). 2. Click the Cast Member Properties button to open the Property Inspector. 3. Select Parent from the Script Type pop-up menu in the Property Inspector. 4. Name the member person in the Name field. 5. Click OK. 6. Type in the script window exactly what is in Figure 13-2.
Figure 13-2: The person parent script
The person script has five properties, just like our property list person. Each property is a variable that needs to be declared with the keyword property.
3486-6 ch13.f.qc
7/24/00
5:49 PM
Page 531
Chapter 13 ✦ Object-Oriented Programming with Lingo
Tip
With global variables, we use the prefix g; with property variables, we use the prefix p. This is just a stylistic convention — they can be any legal variable name. The reason we do this is that the property variable type has the scope of this entire script window; any handler inside this script window can access these properties. Because the use of the property may be in a handler much further down in a script window, it is nice to know, at a glance, that a particular variable is a property without having to scroll all the way back to the top of the window. Another benefit is that you don’t have to worry about accidentally using a Lingo keyword.
The scope of a property variable is greater than that of local variables (whose life span is the length of the handler they are in). Yet, the scope of a property variable is less than that of a global, which can be accessed from anywhere in the movie — even in subsequent movies. The properties are on their own lines in Figure 13-2, but they could all be on the same line as the word property, separated with commas, as shown in Figure 13-3.
Figure 13-3: Another way to declare properties in a parent script window
We usually do it the first way (as in Figure 13-2), because it enables us to put comments right after the variable name, so it could read as follows: property pName -- first and last name property pStreet -- complete street address
Right now, there is only one handler, which is the new() function. It takes five parameters, whose values we promptly put into property variables before returning from the function. We want to be able to put a child object created from this parent script into the five text fields, as we were doing with property lists. Therefore, we will write a handler, and the handler will go into the same script window as the new function and properties. Add the PutInfo handler, as seen in Figure 13-4.
531
3486-6 ch13.f.qc
532
7/24/00
5:49 PM
Page 532
Part III ✦ Learning to Program with Lingo
Figure 13-4: A PutInfo handler is added to the person parent script.
The nice thing about this is that we are grouping the action (the handler) with the data (the object’s properties). This object now knows how to take its data and put it into the five text cast members. No one else is messing with this object’s data. That is the encapsulation aspect of OOP. The object’s data is encapsulated, and the only one to get or set this data is the object’s own handlers. You are allowed to access an object’s properties outside of the object (breaking the concept of encapsulation) with Lingo, but that is based on how you write your code. Now create a JohnDoeObj object as follows: JohnDoeObj =
new(script “person”, “John Doe”, \ “123 Main St”, “Anytown”, “CO”, “12345”)
put JohnDoeObj --
You can see from “putting” the object in the Message window that it is the child object of the person script. This person object knows how to do one thing: put its information into the five text cast members. Now, tell it to do just that, as follows: JohnDoeObj.PutInfo()
If you don’t want to use dot notation, write the following instead: PutInfo JohnDoeObj
As mentioned in Chapter 12 on lists, we like to use parentheses, so we would write the preceding statement as shown here: PutInfo(JohnDoeObj)
3486-6 ch13.f.qc
7/24/00
5:49 PM
Page 533
Chapter 13 ✦ Object-Oriented Programming with Lingo
Parentheses are not required with the syntax, Handler(Object) because it is not a function, but we like them there to improve readability. Visually, parentheses group the handler with the object better. Another visual clue is that handlers are defined with an uppercase letter. The parentheses are required for the dot notation syntax Object.Handler(). If you left them off, Lingo would think you are trying to access a property of the object instead of calling one of its handlers. So, what have we done here? We’ve taken the usefulness of a property list as a way to store data, and we’ve coupled it with functionality. There’s more to it than just that, however. We’ve created a template of a person record of an address book. It’s like creating your own special kind of list, one that you can add to as well as change how it functions. Yes, an object in Lingo is like a property list in many ways and can use property list functions. The list operators [] work on objects. The dot notation, property list functions, and the the propertyName of object syntax all work for objects as well, as shown here: put JohnDoeObj[#pName] -- “John Doe” put JohnDoeObj.pStreet -- “123 Main St” put JohnDoeObj.getProp(#pCity) -- “Anytown” put the pState of JohnDoeObj -- “CO”
We hope these similarities help you feel more comfortable with working with objects. Let’s create another child object of the person parent script: JaneSmithObj = new(script “person”, “Jane Smith”, “987 Central Ave.”, “Othertown”, “AZ”, “98765”) put JaneSmithObj -- JaneSmithObj.PutInfo()
We now have two objects made from the same parent script. Each object has its own space in memory. They are instances (child objects, or offspring) of the same template (parent script). They have the same properties as each other, but the value each of those properties contains is different. For one object, the pName property holds “John Doe”; for the other, it holds “Jane Smith.” Besides these familiar functions and operators, we can now create new handlers that this object can respond to, as we did with PutInfo. Now add the Introduce handler to the end of the person script (see Figure 13-5).
533
3486-6 ch13.f.qc
534
7/24/00
5:49 PM
Page 534
Part III ✦ Learning to Program with Lingo
Figure 13-5: The Introduce handler is placed at the end of the script person. Caution
All variables created in the Message window are global variables. Globals persist between different Director movies. Global variables stay in memory until the program ends, the command clearglobals is used, or VOID is assigned to the variable. Objects created before this change was made, ones that are still in memory, such as globals, do not recognize the Introduce handler. When you create a child object, the object contains a copy of the script. Because our JaneSmithObj was created in the Message window before we added the Introduce handler, the object does not recognize the handler. It has an older copy of the person script. You have to re-instantiate the object to enable the functionality.
Re-instantiate JaneSmithObj as follows: JaneSmithObj = new(script “person”, “Jane Smith”, “987 Central Ave.”, “Othertown”, “AZ”, “98765”)
This is a new object in the JaneSmithObj variable. Now “she” understands the new handler, Introduce, as shown here: Introduce(JaneSmithObj) -- “My name is Jane Smith, I am from Othertown.”
Revisiting the address book program With the person parent script and a few changes to some movie script handlers, you can change the address book program from Chapter 12. Copy the person script cast member, open your address book program, and then paste it into the cast. Then make the changes shown in Figure 13-6 to the handlers shown.
3486-6 ch13.f.qc
7/24/00
5:49 PM
Page 535
Chapter 13 ✦ Object-Oriented Programming with Lingo
Figure 13-6: With minor changes to four movie scripts, the address book is now object oriented.
The biggest change is in the GetStarterList handler. There, you create and return (in the same statement) a list of three new person objects. In ChangeRecord, you’ve replaced a cryptic repeat loop with the statement: aPerson.PutInfo(). Doesn’t it seem easier just to tell the current person object to put its information? In the statement just above that one, you used the list operators instead of the getAt() function to access the current object. You didn’t need to change the other two handlers, AppendRecord and SetRecord. Functionally, they would still work, but we thought it would read more clearly if we changed the name of the local variable newRecord to newPerson.
Controlling sprites with objects Chapters 14 and 15 go further into sprite manipulation through Lingo. For the moment, we’ll give you a brief introduction. The parent script SpriteObj, shown in Figure 13-7, has three handlers: the obligatory new() function, plus the SetUpSprite handler and the GetChannel() function.
535
3486-6 ch13.f.qc
536
7/24/00
5:49 PM
Page 536
Part III ✦ Learning to Program with Lingo
Figure 13-7: The parent script SpriteObj
Creating an Object that Controls a Sprite 1. Create a new parent script, as shown in Figure 13-7. 2. Create a cast member to use as a sprite (vector, bitmap, text, and so on) and name it myMember. 3. Create a go to the frame script in the frame script for frame 1. 4. Play the movie. It is now looping on frame 1. 5. In the Message window, type the following: mySprite = new(script “SpriteObj”, member “myMember”) mySprite.SetUpSprite()
6. Your member appears on the Stage in a random position. Tip
Many experienced Director users are still unfamiliar with the technique of putting sprites into an empty Score. This technique isn’t new: we’ve been using it since version 4.0 of Director. The trick is to puppet the sprite and set the sprite properties shown in SetUpSprite. In earlier versions, you needed to set the type of sprite as well.
3486-6 ch13.f.qc
7/24/00
5:49 PM
Page 537
Chapter 13 ✦ Object-Oriented Programming with Lingo
Creating ancestors Objects have the capability of inheriting behaviors and properties from other objects. Lingo has an object property called ancestor. Unlike the variable me, this is not just a naming convention. When an object receives a message (one of its handlers is called), it looks to see whether it has that handler; if it doesn’t, you get a syntax error. If that object has the ancestor property, however, the message will be sent to the ancestor. Again, if that object doesn’t have the handler, you get an error. Of course, the ancestor can have ancestors, and the message will be sent all the way up. Inheritance is one way to reuse code. A good example is the SpriteObj parent script created in Figure 13-7. It is generic and lends itself to being an ancestor object. This would be a good place to start building the space game.
Creating an Object with an Ancestor 1. Create a parent script named RockObj, as shown in Figure 13-8. The important thing to look at is the initialization of the ancestor property in the new() function. After it creates an instance of a SpriteObj parent script, it calls SetUpSprite with me as an argument. Because it uses me, Lingo expects to find SetUpSprite in this object’s script. This handler does not exist in the RockObj script, but it does have an ancestor as a property, so Director knows to look in the ancestor script next to see whether it has the handler. Sure enough, it does. The prepareFrame handler rotates the rock and moves the sprite.
Declaration of the ancestor property variable Initialization of ancestor property variable
"me" is needed to access ancestor's pSprite property Figure 13-8: The RockObj parent script. Don’t worry if you’re foggy on trigonometry — just type what you see.
537
3486-6 ch13.f.qc
538
7/24/00
5:49 PM
Page 538
Part III ✦ Learning to Program with Lingo
2. Create movie scripts as shown in Figure 13-9. The prepareFrame event handler initializes the global variable gRocks to an empty list. The AddRock handler takes a reference to a member as a parameter. It creates a new instance of a RockObj and adds it to the list of rocks. The prepareFrame event handler loops through all of the rock objects in gRocks and sends each a prepareFrame message. Then it loops on the frame. A prepareFrame handler can be in a movie script. If a frame doesn’t have a prepareFrame handler of its own to trap the prepareFrame event (as the playback head moves), the event is passed to the movie script.
Figure 13-9: The movie script window with three simple handlers
3. Create a rock made from a vector shape and name it rock vector. 4. Add a button to the Stage and name it Add Rock. 5. Add a behavior to that button by pressing Ctrl+click ➪ Script (right-click ➪ Script). 6. Type the behavior as shown in Figure 13-10. The only statement in the mouseUp event handler is a call to the AddRock handler. It passes in one argument, a reference to a member.
Figure 13-10: The behavior for the button sprite
3486-6 ch13.f.qc
7/24/00
5:49 PM
Page 539
Chapter 13 ✦ Object-Oriented Programming with Lingo
7. Play the movie. 8. While the movie plays, click the Add Rock button (see Figure 13-11).
The only item in the score is the "Add Rock" button
Figure 13-11: The movie playing with a few rocks added. Note that the only thing in the Score is the button. The exitFrame handler is in the movie script.
This is a neat little program, but there is one problem with these rocks: They fly off the screen, never to be seen again. Make an additional handler, called CheckBounds, and call it from the prepareFrame handler, as shown in Figure 13-12. Note
To some extra-logical readers, it might seem odd to name a parent script something with Obj as a suffix, because the parent script itself is not an object but a template from which objects are made. When used in a line of code, however, it reads quite well. For example, where we say ancestor = new(script “SpriteObj”, aMember), what we want in ancestor is an object of the SpriteObj script.
9. Save this movie as Rocks – ancestors.dir.
539
3486-6 ch13.f.qc
540
7/24/00
5:49 PM
Page 540
Part III ✦ Learning to Program with Lingo
Figure 13-12: Add the handler CheckBounds to make sure that the rocks wrap around to the other side of the screen.
Using the actorList The actorList is a movie property that is global in scope. It is used in conjunction with child objects. Child objects added to the actorList automatically receive a stepFrame event every time the Stage is updated. Objects remain in this list even when you go to other movies. It can be cleared by setting it to an empty linear list. You can quickly change the Rocks movie to use the actorList. To use the actorList in the Rock Movie: 1. Create a duplicate of the file Rocks – ancestors.dir movie you just saved. 2. Open the RockObj parent script and rename the PrepareFrame handler to StepFrame, as shown in Figure 13-13. 3. Remove the global variable gRocks from the movie script window. Change the prepareMovie handler so that it sets the actorList to an empty list. Change AddRock so that it adds the new rock to the actorList . Delete the repeat loop from the prepareFrame handler (see Figure 13-14). 4. Play the movie and add some rocks. The result is the same as earlier.
3486-6 ch13.f.qc
7/24/00
5:49 PM
Page 541
Chapter 13 ✦ Object-Oriented Programming with Lingo
Figure 13-13: The RockObj parent script’s PrepareFrame handler is renamed StepFrame.
Figure 13-14: All three movie scripts have minor changes. Note that the global variable gRocks is no longer needed.
Advantages of the actorList Well, you rewrote the Rocks movie so that it does the same thing. Which way is better? ✦ Using the actorList gives you a way to automatically send stepFrame events to an object. ✦ A stepFrame is generated when the Stage is updated by the playback head moving or when the updateStage command is used. ✦ Using the actorList avoids your having to declare a global variable. ✦ The scope of the actorList already is global. ✦ We’ve heard claims of the actorList being a faster way of sending messages. We don’t have hard data on the validity of these claims and we haven’t seen humanly noticeable results when we’ve compared the two methods. Still, it’s worth trying if you are trying to squeeze more speed out of a movie.
541
3486-6 ch13.f.qc
542
7/24/00
5:49 PM
Page 542
Part III ✦ Learning to Program with Lingo
Disadvantages of the actorList Yes, there is a downside to the actorList. Most of the time, we choose to use the first method for these reasons: ✦ The global nature of the actorList enables the objects in it to persist even when you go to a new movie. They will continue to get stepFrame events, possibly causing havoc. Child objects in a global list that go to another movie will do nothing unless their handlers are called. ✦ By using a global list to selectively send messages, such as prepareFrame, you can easily enable and disable the activity of your objects throughout your movie. ✦ the actorList can turn into a dumping ground for objects of different types. ✦ Clearing the actorList may be unwise at the start of a movie, because you might end up getting rid of an object from a previous movie that was supposed to be there. It is almost as bad as calling clearglobals.
Using parent scripts instead of globals As mentioned in this and earlier chapters, a global variable can persist between movies. Sometimes this is not the behavior you desire. When you create a movie in a window (MIAW), you might not want to use global variables, because the Stage or other MIAWs might inadvertently use them. One way around this problem is to create a parent script with properties that you want to use like global variables. You then can use the following syntax: set the propName of script “myScript” to aValue propName is the name of the property you want to set; myScript is the name of the parent script; and aValue is the value to which you are setting the property.
Advantages of using parent scripts in place of globals This method of storing data has several advantages over using global variables: ✦ You can access the value from anywhere in the movie without having to declare a global. ✦ Your values will not show up when a showglobals command is issued. ✦ Your values exist only in the current movie. ✦ Your values are hidden from people examining your movie better than with globals.
3486-6 ch13.f.qc
7/24/00
5:49 PM
Page 543
Chapter 13 ✦ Object-Oriented Programming with Lingo
Disadvantages of using parent scripts in place of globals Some of the advantages of this technique can be disadvantages as well: ✦ Your values are limited to the current movie. ✦ You need to write specific code to put these values to the message window, instead of just being able to issue a showglobals command. ✦ Recompiling clears out these values. ✦ The code to get or set the value is longer. This technique is similar to using class variables in other languages. If you would like to take this strategy further, see the sidebar “Class Variables in Lingo.”
Class variables in Lingo If you’ve programmed in C++, you are probably familiar with class member variables and methods, as opposed to instance variables. Class variables are static: the value one holds is shared across all instances of the class. You can do something similar in Lingo. Instead of setting an instance of a class as a variable, set it to a referenceto a script, as in the following: ancestor = (script “sharedInfo”) This technique enables you to have properties share the same value across child objects of the same parent script. Why would you want to do this? Suppose that you are instantiating hundreds of objects and you want to save memory where possible. Instead of having each object hold the same piece of data (and that piece having to be written to hundreds of objects when you want to change it), you have only one that is shared by all. You could use an object that is a global variable as the ancestor, and have all of the objects share the same instance, but using a global would break encapsulation. If you’re an OOP diehard, breaking encapsulation is probably distasteful to you. Besides, who wants all those globals floating around between movies and filling the Message window when you do the showglobals command? Here’s a simple use for a static variable (see the following figure) Continued
543
3486-6 ch13.f.qc
544
7/24/00
5:49 PM
Page 544
Part III ✦ Learning to Program with Lingo
Continued
TestCounter creates 100 instances of the parent script smallObj. When you try TestCounter in the Message window, you get this result: TestCounter -- 100 Each time through the loop, a new instance of the script smallObj is created. Each time a new instance of smallObj is created, it increments the pCount property of its ancestor script, “counter”. Because the ancestor script is a reference to a script instead of an instance, all of the objects created shared the property pCount. Each object, therefore, “knew” how many instances of smallObj were created, from the first to the last. For example, if we change TestCounter to that shown in the figure below, and execute it from the Message window, you get this result: TestCounter -- 3 -- 3 -- 3 One of the nice aspects of this method is that the values are not cleared after recompiling as they are if done something like the following: set the pCount of script “counter” to 10 put the pCount of script “counter” -- 10
3486-6 ch13.f.qc
7/24/00
5:49 PM
Page 545
Chapter 13 ✦ Object-Oriented Programming with Lingo
Recompile the scripts by choosing Control ➪ Recompile All Scripts: put the pCount of script “counter” --
This variation on TestCounter shows the creation of three independent objects, all of which reference the same script counter variable via inheritance.
Behaviors and Child Objects Behaviors have an important relationship to OOP and to parent scripts and child objects (see Chapters 14 and 15 for a more detailed discussion). In Director, parent scripts and behaviors are almost identical in their implementations. Objects can be written with or without sprites in mind. Behaviors are written with the intention of being used with sprites.
Converting a parent script to a behavior Parent scripts can be adapted easily to work as behaviors, and the reverse, converting behaviors to parent scripts, can also be done. Let’s do that with our Rock movie. Open a copy of your Rock movie. Make the changes to the RockObj parent script as shown in Figure 13-15. 1. Remove the ancestor declaration property ancestor from the top of the screen, and add property pSprite in its place. 2. Remove the first two statements in the new() function and add pSprite = sprite(me.spriteNum) in their place. 3. Click the Cast Member Properties button to open the Property Inspector. 4. Click the Script Type pop-up menu under the Script tab in the Property Inspector, and select Behavior.
545
3486-6 ch13.f.qc
546
7/24/00
5:49 PM
Page 546
Part III ✦ Learning to Program with Lingo
5. Technically, we’re finished with this script. Yet, make one more change. Every occurrence of me.pSprite in the prepareFrame and CheckBounds handlers can be changed to just pSprite. Although me.pSprite will still function, you are making the movie do extra work. Because the property pSprite is now in the same script window, it is unnecessary to use the me reference. In fact, accessing via the me reference is a little slower.
Figure 13-15: The RockObj parent script has become a behavior.
Now you can delete the other scripts. You no longer need the SpriteObj parent script or the movie scripts. All you need now is a go to the frame on the frame script. We could have kept the one in the movie script, but because all of our other work is in the Score, it makes sense to have this script there as well (see Figure 13-16).
Figure 13-16: Place a simple go to the frame script in script channel at frame 1.
3486-6 ch13.f.qc
7/24/00
5:49 PM
Page 547
Chapter 13 ✦ Object-Oriented Programming with Lingo
You can also delete the Add button, because we are not dynamically adding sprites with behaviors (although it is possible). We will use the Score to add a few rocks, and then apply the RockObj behavior. If you don’t see the script available in the Behaviors pop-up menu, then you might have forgotten to change the type of script to Behavior. Parent scripts (as well as movie and cast member scripts) do not appear in the Behaviors pop-up. Now, just play the movie, as shown in Figure 13-17.
RockObj behavior applied to rock vector sprites
Figure 13-17: Although the behaviors version of the Rocks movie has only three cast members, there are sprites in the Score.
Because that was so easy, let’s add a spaceship!
Adding a Spaceship to the Rocks Movie 1. Create ship artwork with a vector shape. 2. Put the ship artwork into the first available sprite channel. 3. Create the behavior shown in Figure 13-18.
547
3486-6 ch13.f.qc
548
7/24/00
5:49 PM
Page 548
Part III ✦ Learning to Program with Lingo
Note
Note that the ship uses the same statement as the rock to rotate it, but it bases the direction to rotate on user input. Since Director 7, the keyPressed() function has had new functionality. It enables you to detect whether a key is pressed based on the keyCode (as shown) or on a string of a single character, and returns 1 or 0 (TRUE or FALSE). This enables you to detect whether a key is down, even when other keys are pressed as well. In the ExitFrame handler, we’ll rotate the ship if the left or right arrow is pressed, but we’ll also accelerate the ship if the up arrow is pressed. This was impossible to do in previous versions of Director.
Figure 13-18: The ShipObj behavior illustrates the use of keyPressed() functionality for user input.
4. Apply the behavior to the ship sprite. 5. Play the movie. Not bad for a movie with only five cast members (see Figure 13-19)!
3486-6 ch13.f.qc
7/24/00
5:49 PM
Page 549
Chapter 13 ✦ Object-Oriented Programming with Lingo
Figure 13-19: The Rocks movie now has a new inhabitant. Tip
You can make one further optimization. You are able to specify the number of sprite channels in your movie (see Figure 13-20). You can have as many as 1000, but you can improve performance by only using what you need. For this movie, we specified 12.
Choose from 1 to 1000 score channels
Figure 13-20: You can specify the number of sprite channels in your movie.
549
3486-6 ch13.f.qc
550
7/24/00
5:49 PM
Page 550
Part III ✦ Learning to Program with Lingo
This example illustrates the convenience of behaviors. They enable you to think in object-oriented ways, but they greatly simplify the implementation. While we are not doing anything as advanced as dynamically putting sprites in the Score or using inheritance, we have achieved our goal in an elegant, easy-to-understand manner. This doesn’t mean that you should throw out parent scripts; they have their uses in controlling sprites, cast members, and nonvisual data. After you’ve got your functionality set with behaviors, you can always easily modify them to make them parent scripts. In fact, behaviors are a good way to prototype your parent scripts.
Other offspring tricks Another interesting trick that you can do with the children of parent scripts and behaviors is to use them interchangeably in the scriptInstanceList of a sprite. All sprites keep a list of the behaviors attached to them, which are kept in the scriptInstanceList of the sprite. At any time, should you so desire, you can add other instances (objects) to the list. They do not have to be instances of behaviors; they can be instances of parent scripts. By the same token, you can get any script instance of a sprite and put it into a variable and call its functions and access its properties from the variable.
Cast Member Scripts Cast member scripts have, for the most part, been supplanted by behaviors. In fact, you can’t even get to the cast member script anymore by Ctrl+clicking (right-clicking). You can still reach them, however, through the Cast Member Script button on the Cast window and by clicking the Cast Member Script button on the Member tab in the Property Inspector. Using cast member scripts does have similarities to object-oriented programming. You are combining data (a cast member) with actions (the cast member script). You are able to create your own handlers inside a cast as well as use many of the event handlers that sprite behaviors support (the exceptions are beginSprite, endSprite, and new). In versions 4 through 6.5 of Director, cast member scripts supported property variables. As of version 7, however, the properties no longer remember their values, making this feature, for the moment, dead.
3486-6 ch13.f.qc
7/24/00
5:49 PM
Page 551
Chapter 13 ✦ Object-Oriented Programming with Lingo
Summary Object-oriented programming enables the programmer to think about the problem at a higher level. In this chapter, you learned that: ✦ Lingo is an object-oriented language. ✦ Parent scripts and child objects have similar counterparts in C++ and Java. ✦ Child objects are similar to property lists, and that you can use property list functions on them. ✦ You can define your own handlers in parent scripts. ✦ In Director, the ancestor property implements inheritance and facilitates code reuse. ✦ Parent script properties can be used like class variables in other languages. ✦ Behaviors and parent scripts have a great many similarities, and it is easy to convert between the two. ✦ Behaviors are a rapid way to create objects. Chapter 14 discusses the subject of building buttons.
✦
✦
✦
551
3486-6 ch13.f.qc
7/24/00
5:49 PM
Page 552
3486-6 ch14.f.qc
7/24/00
5:50 PM
Page 555
14 C H A P T E R
Building Buttons
✦
✦
✦
✦
In This Chapter
I
f you’ve been reading sequentially, you’ve just finished some pretty intense chapters on learning to program using Lingo. This chapter is a bit of a breather for you. It is focused on a very common and specific task — building buttons. Director 8 comes with a wide assortment of prebuilt behaviors for handling buttons. If you open one of those behaviors, you might be daunted by the amount of code it takes. It is easier to understand these complex behaviors after you’ve written some of your own. Maybe you need to do something that falls outside the scope of the prebuilt behaviors; maybe you prefer that your projects have your logic; or maybe you just want to understand how they work. This chapter is useful whether you are interested in building your own behaviors or just want to understand how something that seems so simple can be so complex.
Mouse Events Buttons typically have a minimum of two states: up and down. Another common state is the roll-state — the state of the button when a mouse rolls over it but the button has not yet been clicked. A button can also be grayed-out, a state in which it is inert. Events (and a little scripting) cause these states to change. Standard events for a button are the following: ✦ mouseEnter occurs when the cursor enters a sprite’s bounding rectangle. ✦ mouseWithin occurs repeatedly while the cursor is inside a sprite’s bounding rectangle. ✦ mouseDown occurs when the user clicks a sprite. ✦ mouseLeave occurs when the mouse leaves the bounds of the sprite (whether the mouse is up or down).
Building your own button behaviors Mouse events Swapping cast members with Lingo Creating your own handlers within the behavior to be called by mouse event handlers Creating a Parameters dialog box
✦
✦
✦
✦
3486-6 ch14.f.qc
556
7/24/00
5:50 PM
Page 556
Part IV ✦ Controlling Media with Lingo
✦ mouseUpOutside is a sprite that received a mouseDown but the mouse button was released outside of its bounds. ✦ mouseUp occurs when the mouse button is released over a sprite that received a mouseDown event. These events are only sent to sprites that have behaviors attached to them. To make use of these events, you need to create a behavior. Figure 14-1 shows a screen with eight buttons. The top row is for illustrative purposes, showing all the available states. You apply the scripts to the bottom row of buttons.
Figure 14-1: A bunch of “dumb” buttons waiting for behaviors.
Creating and applying a behavior To better understand event handlers and how they work with sprites, work though the following steps. You are creating a behavior that has all of the most common sprite-related events, when those handlers have a single put statement so you can see them execute in the Message window. On the CD-ROM
All of the various Stages of the buttons.dir movie are on the CD-ROM in the folder EXERCISE:CH14 (EXERCISE\CH14). Start from scratch with buttons.dir, and if you get stuck anywhere along the line, check out button1.dir through button5.dir.
3486-6 ch14.f.qc
7/24/00
5:50 PM
Page 557
Chapter 14 ✦ Building Buttons
Creating a Behavior 1. Open the movie buttons.dir. 2. Select the four bottom buttons by clicking the first one and holding down the Shift key while clicking the others. Alternatively, you can open the Score window and select sprites 5 through 8. 3. In the Behaviors pop-up menu on the Score or in the Sprite Inspector, choose New Behavior. Alternatively, you can Ctrl+click (right-click) one while they’re all selected, and then choose Script from the pop-up menu. 4. You’re presented with an almost empty behavior, just an on mouseUp handler waiting for more code. Enter the code shown in Figure 14-2. Name it B_mouse events. 5. Open the frame script for frame 1 and add a go to the frame statement to the on exitFrame handler. 6. Open the Message window. 7. Play the movie. As it plays, roll the mouse over the buttons, and click and release over the buttons and off them. Note the feedback in the Message window.
Figure 14-2: A script that puts the sprite reference and the name of each mouse event to the Message window as the event occurs.
557
3486-6 ch14.f.qc
558
7/24/00
5:50 PM
Page 558
Part IV ✦ Controlling Media with Lingo
Sprite references In Figure 14-2, the beginSprite handler sets a property called pSprite. As Chapter 13 explains, the me parameter contains an instance of the behavior for the sprite to which it is attached. Every behavior has one property built-in, and that is the spriteNum. The spriteNum is the number of the sprite channel for the sprite to which the behavior is attached. The statement pSprite = sprite(me.spriteNum) gets the value of spriteNum from me, and then the sprite keyword returns a reference to the sprite, such as (sprite 5). A good way to understand this is to go back to our trusty Message window. In it, type the following: mySprite = sprite 5 put mySprite -- (sprite 5) What’s the value of this? Well, instead of typing one of the following: put the loc of sprite 5 -- or put sprite(5).loc You can give it a meaningful name and skip typing the word sprite: put the loc of mySprite -- or put mySprite.loc -- point(135, 363) It also works well with dot syntax, as shown here: put mySprite.member.name -- “button” In the case of the mouse event behavior, we are calling the sprite reference pSprite. As mentioned in Chapter 13, we start all property variables with a p to remind us that they are properties. This is just a convention we use; you can name it any legal variable name.
Your Message window probably looks something like the following: -----------
“(sprite “(sprite “(sprite “(sprite “(sprite “(sprite “(sprite “(sprite “(sprite “(sprite
6) 6) 6) 6) 7) 7) 7) 8) 7) 8)
mouseEnter” mouseDown” mouseUp” mouseLeave” mouseEnter” mouseDown” mouseLeave” mouseEnter” mouseUpOutside” mouseUp”
3486-6 ch14.f.qc
7/24/00
5:50 PM
Page 559
Chapter 14 ✦ Building Buttons
-- “(sprite 8) mouseDown” -- “(sprite 8) mouseLeave” -- “(sprite 8) mouseUpOutside”
Try uncommenting the statement in the mouseWithin handler and playing the movie again. You’ll understand why we commented it out when you roll over one of the buttons. Every time the playback head moves, if the mouse is over the sprite, it is sent a mouseWithin event. If your frame rate is set to 15 fps, you have 15 mouseWithins put to your Message window every second. Remember that the playback head is moving, even when it is looping on a single frame. See the “Sprite References” sidebar for more information on the topic.
Adding behavior to the behavior Continuing with the Buttons example, let’s now add some functionality. We’re going to use three of the buttons in the cast to create a button with an up, down, and roll state. Open the script window for the script named B_mouse events and add the code shown in Figure 14-3. You can keep the put statement in there; it’s nice to have feedback while you’re developing.
Add this code
Figure 14-3: A button behavior with three states
559
3486-6 ch14.f.qc
560
7/24/00
5:50 PM
Page 560
Part IV ✦ Controlling Media with Lingo
Now when you play the movie, your buttons behave like buttons — almost (we’ll address this “almost” in a little bit). In the script’s beginSprite handler, it assumes that the member currently in the sprite channel is the one you want to put in pUpMember. The next two — pDownMember and pRollMember — are derived on the assumption that they have the same name as pUpMember but with down and roll added, respectively. Remember that the && operator concatenates two strings and puts a space between them. So, when the name of pUpMember is accessed in the following line:
Note
pDownMember = member(pUpMember.name && “down”) (pUpMember.name && “down”) evaluates to “button down.” Then “button down” is used as a parameter to member() to return a reference to the member “button down”. See the “Member References” sidebar for more information on the subject.
This naming convention is usable even if the name of the button consists of multiple words. It is also good because all button states of the same group start with the same name. Using this convention, you can apply this behavior to the button sprite and it automatically uses all three cast members. If you made a mistake in your cast member naming convention, you’ll get a syntax error warning that Director couldn’t find the cast member.
Better Button Behavior You might think we’re about finished, and for some purposes, maybe we would be. But there is a problem with the way Director handles mouse events. 1. Play your movie and put the mouse over the button at the far right. 2. Click the button. 3. While holding down the mouse button, roll the cursor to the left. 4. The second button from the left becomes highlighted. 5. Release the mouse button over the second button. That button gets the mouseUp! Your Message window should say: -------
“(sprite “(sprite “(sprite “(sprite “(sprite “(sprite
8) 8) 8) 7) 8) 7)
mouseEnter” mouseDown” mouseLeave” mouseEnter” mouseUpOutside” mouseUp”
3486-6 ch14.f.qc
7/24/00
5:50 PM
Page 561
Chapter 14 ✦ Building Buttons
Member references First there were sprite references, and now there are member references. In Figure 14-3, three new properties were added to the script B_mouse events — pUpMember, pDownMember, and pRollMember. These properties were initialized in the beginSprite handler. To understand what a member reference is, go back to the Message window. In it, type the following: myMember = member “button” put myMember -- (member 11 of castLib 1) The myMember holds a value that refers to member 11 of castLib 1. Putting the member reference into a variable saves us from having to write code like this: myMemName = “button” put the type of member myMemName -- #bitmap Now you can do things like the following: put myMember.type -- #bitmap put myMember.name -- “button” put myMember.rect -- rect(0, 0, 98, 97)
You might prefer this sort of action. The built-in buttons on the Tool Palette respond in the same manner. We find several problems with this functionality: ✦ If you press the mouse button down on the Stage, and release over a button, it does not receive a mouseUp event, even though it gets a mouseEnter event. ✦ If you press the mouse button down on any other sprite with a script and release the mouse over a button, it does receive a mouseUp event. ✦ Given good user interface standards, one would expect only the button that received the mouseDown event to respond to the mouseUp event. Even Director’s own interface follows this standard. Try clicking the Save button on the Toolbar that runs across the top of the screen. Then, with the mouse button still down, roll over the Save All button. Note that it does not become highlighted, and when you release the mouse button over it, it does not activate. Try some of the buttons in the Paint window or Toolbar as well.
561
3486-6 ch14.f.qc
562
7/24/00
5:50 PM
Page 562
Part IV ✦ Controlling Media with Lingo
Controlling events a sprite receives It seems only appropriate that the buttons we create in Director should respond in the same manner as buttons in other programs. There is an easy way and a more involved way to get around this problem. The easy way is to set the system property the buttonStyle to 1 (the default is 0). A good place to do this is in an on prepare Movie event handler. Now the buttons you create will work like most buttons. The easy way is not as educational, nor does it take into consideration the poss-ibility that you want both styles of button behavior in the same movie. Another situation where you may want to go the more involved route is when you are modifying an existing movie that assumes the buttonStyle will be set to its default value. Given the obscurity of this property, this is not unusual. So let’s take a look at solving this problem the hard way. Due to the length, you add the code in two parts (see Figure 14-4).
Add this code
Add comments for clarity
Figure 14-4: Two new properties, plus a handler, have been added.
First, add the new properties pPressed and pReceiveEvents. These both hold Boolean values (TRUE or FALSE). They are initialized in the beginSprite handler. A new handler is defined for this behavior as well; it is called SetReceiveEvents. SetReceiveEvents is not a Lingo keyword; it is just a user-created handler, so we could have called it anything. The purpose of this handler is to change the value of
3486-6 ch14.f.qc
7/24/00
5:50 PM
Page 563
Chapter 14 ✦ Building Buttons
the property pReceiveEvents. This handler is called from other objects. SetReceive Events has one parameter: aState. aState holds a Boolean value of TRUE or FALSE, which is assigned to pReceiveEvents. It also checks to make sure that it isn’t the sprite that sent the SetReceiveEvents message. Now, some code needs to be added to the mouse event handlers, as shown in Figure 14-5. For each event, we test whether or not the object should be receiving events by testing the value of the property pReceiveEvents.
Add this code
Figure 14-5: The mouse events are beginning to grow in complexity.
Starting with the mouseEvent handler, another if statement is used to check whether pPressed is TRUE. If it is, the button goes down. If it is not, then it turns into the roll state. Next is the mouseDown handler. Assuming it receives events, the mouseDown handler sets pPressed to TRUE. It changes the member. Last, it sends the SetReceiveEvents message to all of the sprites, passing its sprite reference and FALSE (which prevents any of the other buttons from receiving mouse events).
563
3486-6 ch14.f.qc
564
7/24/00
5:50 PM
Page 564
Part IV ✦ Controlling Media with Lingo
Tip
“Sending a message” means calling the handler of an object. The command sendAllSprites enables you to call a specific handler in every behavior on every sprite. If the sprite does not have the handler, it ignores the message. mouseLeave doesn’t do anything different other than check to see whether it is receiving events. mouseUpOutside sets pPressed to FALSE, which makes sense — if the mouse button is up, it is no longer pressed. It also sends the SetReceive Events message to all sprites, this time passing TRUE to again enable them to
receive events. Last, mouseUp checks not only whether it can receive events, but also whether pPressed is true. pPressed is TRUE only if it was set to TRUE in the mouseDown event. It then switches the member and tells all the other sprites that they can get events once more. Now play the movie and test the buttons as you did at the beginning of this section. Don’t forget to have the Message window open. Now these buttons are behaving better! These new changes to the code give us some added capability as well. Just to show you it’s worth the extra work, play the movie and try this in the Message window: (sprite 5).mouseEnter() -- “(sprite 5) mouseEnter”
The movie must be playing when you try this and the next example, because behaviors are not instantiated until the movie actually plays and the playback head enters the frame the sprite is on. Our handy put statement lets us know the Message was received; we also know this because the button changes to a roll state. You can now control button presses from Lingo. (sprite 5).mouseDown() -- “(sprite 5) mouseDown” sprite(5).mouseUp() -- “(sprite 5) mouseUp”
It’s like a ghost pressing the buttons.
Adding an inert state You might be asking yourself “Are we done yet?” We’re glad you asked! Of course not; you can always add more code! Writing scripts is like creating art; you’re never really finished (unless you’ve got a deadline). Besides, we still haven’t used the member-named button inert yet. The inert state is a state that receives no events. In our example, a button becomes inert after it receives a mouseUp event.
3486-6 ch14.f.qc
7/24/00
5:50 PM
Page 565
Chapter 14 ✦ Building Buttons
To add this functionality, we need to add two more properties — pInertMember and pInert. pInertMember is a reference to the bitmap member-button inert. Add the properties as shown in Figure 14-6. Also, make the changes to beginSprite, SetReceiveEvents, and mouseUp, as shown in Figures 14-6 and 14-7.
Add this code
Figure 14-6: pInertMember and pInert properties are added to the behavior and added to beginSprite. SetReceiveEvents now also tests pInert.
Add this code
Change this code
Figure 14-7: pInert is set in the mouseUp handler. pInertMember is also used.
565
3486-6 ch14.f.qc
566
7/24/00
5:50 PM
Page 566
Part IV ✦ Controlling Media with Lingo
Play the movie again and click one of the buttons. It becomes gray and no longer responds to mouse events. Being a little obsessive is the sign of a good programmer, so let’s just make one more little addition. At the moment, we have no way to reenable an inert button. You can do it through Lingo, of course. Click a button to make it inert. You see the following in the Message window, for example, if you click the button in sprite channel 8: -- “(sprite 8) mouseEnter” -- “(sprite 8) mouseDown” -- “(sprite 8) mouseUp”
Now, in the Message window, type the following: (sprite 8).pReceiveEvents = TRUE (sprite 8).pInert = FALSE
You could also write it like this: sprite(8).pReceiveEvents = TRUE sprite(8).pInert = FALSE
Now you can roll over the button and click it. We just need to insert the code in the behavior. Let’s put it into the mouseDown handler, as shown in Figure 14-8.
Add this code
Figure 14-8: A few statements added to reenable the button when it is double-clicked. Tip
When you work on successive generations of a script (where each generation is saved separately), sometimes it’s helpful to compare the code from one version to another. Director does not support this, but programs such as Microsoft Word and BBEdit do. All you need to do is copy and paste the script into separate documents for comparison.
3486-6 ch14.f.qc
7/24/00
5:50 PM
Page 567
Chapter 14 ✦ Building Buttons
Creating a Parameters Dialog Box At this point, you have a great button behavior. It’s easy to use — just make sure you’ve named your cast members properly, and it automatically finds them. It behaves well. You might like it enough that you want others to use it . . . maybe even nonprogrammers. Nonprogrammers might find adhering to the naming convention too rigid, and might find going into the script — to add functionality in the mouseUp handler — scary. Here’s how Director makes your life (and their lives) easier. You get to write pages of fun code, and they just get to see what they need.
Building a dialog box First, we need to change our naming convention slightly. The naming convention is optional, but if you make this change and adhere to it, you’ll like the results. Earlier, the assumption was made that the up state for a button was just whatever name you wanted to call the button. Suppose that you called it “green button.” The subsequent states would have the same name, plus down, roll, and inert added to them. From this point, the up state should have up after it. So, we have the following: “green “green “green “green
button button button button
up” down” roll” inert”
When the user drags the behavior onto a sprite, we see the dialog box in Figure 14-9. The goal is to have the box take a good guess, based on naming conventions. If naming conventions weren’t followed, the first graphic in the movie appears in the pop-up menu for each button state (it just doesn’t look as cool). If the right member is not selected, the user can always click the pop-up menu next to the state and choose the desired member. Also included are check boxes to decide whether a button should be inert initially, whether it should be inert after it is used, and an Action pop-up menu to let the user choose from one of the Lingo commands you decide to put in it.
Figure 14-9: We want this dialog box to pop up when a user drags the behavior onto a sprite.
567
3486-6 ch14.f.qc
568
7/24/00
5:50 PM
Page 568
Part IV ✦ Controlling Media with Lingo
That’s what we want, but how do we get there? By using the event handler get PropertyDescriptionList. This handler runs when a behavior is applied to a sprite. In it, you define a property list that is used to build the dialog box shown in Figure 14-9. Add the handler shown in Figure 14-10 to the behavior B_mouse events. It doesn’t matter where you put it; we put it after the beginSprite handler. The handler returns the property list myList. myList is composed of smaller property lists. Each property list in myList corresponds to a property defined in the behavior. The first property added to myList is #pUpMember, which corresponds to the property pUpMember. When a user chooses a member for the up state of the button, that member is placed into pUpMember. The list for pUpMember list includes the following: ✦ #comment, which is used to the left of the control being created. ✦ #format for the value. This is the value’s type. We could have been more specific and chosen #bitmap, #vectorShape, or #filmloop, for example, but #graphic is handy because you are not limited to the type you want to use for each state of the button. This enables you to have an animated . GIF for the up state (if you want), and bitmaps or other graphics for the other states. ✦ #default is the value that appears when the dialog box first opens.
Figure 14-10: Use getPropertyDescriptionList to build the dialog box shown in Figure 14-9.
Farther down, you can see that pInert’s #format is set to #boolean. This presents the user with a checkbox. If it gets checked, TRUE is returned; if it doesn’t, FALSE is returned.
3486-6 ch14.f.qc
7/24/00
5:50 PM
Page 569
Chapter 14 ✦ Building Buttons
✦ The last list added is for the pAction property (we’ll declare that in a moment). It’s #format is #string. It also has a #range value, which is a linear list. Because the #format is #string, the linear list is filled with strings. This list is used to create a pop-up menu for the user. Here, we’ve added several common Lingo commands to choose from. See Figure 14-11 to see how it appears to the user in the Property Inspector. ✦ Not used in our program, but still useful is a variation of #range. Its format is either #float or #integer. The list #range has a property list with two properties: #max and #min. This creates a slider on the interface. The syntax is #range: [#max: 5, #min: 1]. Figure 14-11: The #range property enables you to specify what appears in a pop-up menu, as shown here. You can also use #range to create a slider.
At the top of the getPropertyDescriptionList handler, we create some variables. The first is memNames. It is a list of the names of all the members in the movie. This list is built from the function BuildList(), shown in Figure 14-12. Go ahead and add it right after the getPropertyDescriptionList handler. Figure 14-12: BuildList() returns a list of every name in every cast. It is called from getProperty DescriptionList.
569
3486-6 ch14.f.qc
570
7/24/00
5:50 PM
Page 570
Part IV ✦ Controlling Media with Lingo
BuildList() could easily be made into a movie handler, such as prepareMovie,
that is only called once at the beginning of a movie and sets a global variable that this behavior would access. For convenience and not efficiency, we put it right in the behavior. This way, if you ever want to give this behavior to someone, you don’t have to worry about remembering the movie script as well. Plus, it makes it easier to integrate into other movies by not having to merge one prepareMovie with another prepareMovie. It is all encapsulated in this one behavior (which is one of the attributes of object-oriented programming). Then, second through fifth statements in the getPropertyDescriptionList handler shown in Figure 14-10 are variables that hold member references. They get these member references from GetMember(). GetMember() takes two parameters (in addition to the me parameter): memNames and aName. memNames is a list of member names, and aName is a string. Specifically, aName is expected to be a substring of one of the member names. The second statement, upMem = GetMember(me, memNames, “ up”)
passes the memName list as an argument as well as the string literal “up.” GetMember(), shown in Figure 14-13, searches through memNames looking for a string that has (in this case) up in it. If it finds a string in the list containing it, a reference to that member is returned, breaking out of the loop and the handler. The variable upMem is then used to set the default for the #pUpMember property list in the myList property list.
Figure 14-13: GetMember searches through a list for a substring. It is called from getPropertyDescriptionList. BuildList() and GetMember() enable us to vary the naming of the buttons. Try
renaming the buttons, but keep the suffix on each. The Parameters dialog box displays the first member it finds with a name containing up in the “Up state” pop-up menu, the first member it finds with a name containing down in the “Down state” pop-up menu, and so on. To accommodate these changes, we needed to add the properties pInertAfterUse and pAction, as shown in Figure 14-14. The beginSprite function was changed drastically. We removed the initializations of all the properties that are given values by the Parameters dialog box.
3486-6 ch14.f.qc
7/24/00
5:50 PM
Page 571
Chapter 14 ✦ Building Buttons
Add this code
Change this code Figure 14-14: Two new properties and a very different beginSprite handler
The mouseUp handler has some changes as well, as shown in Figure 14-15. It uses both of the new properties declared in Figure 14-14.
Add this code
Figure 14-15: The restructured mouseUp handler makes use of both new properties: pAction and pInertAfterUse.
Documenting behaviors There are two event handlers that aid in the documentation of a behavior’s functionality: getBehaviorDescriptonList and getBehaviorToolTip. These are shown
571
3486-6 ch14.f.qc
572
7/24/00
5:50 PM
Page 572
Part IV ✦ Controlling Media with Lingo
in Figure 14-16. The getBehaviorDescription event handler returns a string that appears in the Behavior Inspector. The getBehaviorToolTip event handler returns a string used as a ToolTip when this behavior is in the Library Palette.
This string shows up here
Figure 14-16: Documenting a behavior is easy with the getBehaviorDescription event handler. The string you specify it to return appears in the Behavior Inspector.
Summary This chapter focused on the task of making a button that responds in a way that users have come to expect. It also illustrated the many events to which a sprite can respond. Specifically, you learned that: ✦ Button behaviors can be made quickly, but buttons that follow standard user-interface guidelines take a little more work. ✦ Sprites can send messages to other sprites. ✦ Mouse events are called by Director or from Lingo. ✦ You can put references to members and sprites in variables. ✦ You can create you own handlers within behaviors. ✦ Behaviors provide a way to create online documentation through the Behavior Inspector. The next chapter discusses how you can control sprites by using Lingo.
✦
✦
✦
3486-6 ch15.f.qc
7/24/00
5:50 PM
Page 573
15 C H A P T E R
Controlling Sprites with Lingo
M
anipulating sprites through Lingo is perhaps the heart of programming in Director. You’ve learned how to put sprites onto the Stage in earlier chapters (or through previous experience) — you’ve animated them through the user interface. That is just “click and go” results (which, in the right hands, can be impressive), but now you want your artwork to have a life of its own. You want it to move based on your input or in relation to other sprites on the Stage. In this chapter, you modify a movie that already has some elements in it (instead of creating them from scratch). We tell you which movie to open to work on, and periodically we tell you to save the movie with a new number (for example, mars landing 02.dir, mars landing 03.dir, and so on). Every time we tell you to save a movie, one that parallels yours is on the CD-ROM under the same name. These movies are useful if you become stuck at any point or simply want to skip ahead.
Moving Sprites To move sprites through Lingo commands, you need an understanding of the coordinate system in Director. Given experience in working with sprites on the Stage, or even page layout programs such as QuarkXPress, you might already be familiar with how coordinates are handled.
✦
✦
✦
✦
In This Chapter Manipulating sprites and their members Controlling navigation Using parent scripts with sprites Score recording Puppeting sprites
✦
✦
✦
✦
3486-6 ch15.f.qc
574
7/24/00
5:50 PM
Page 574
Part IV ✦ Controlling Media with Lingo
The loc of a sprite The Stage area is similar to the first quadrant of a Cartesian coordinate system, with one important exception: the values along the y-axis are flipped — values increase (become greater than zero) as you move toward the bottom of the Stage (see Figure 15-1). The upper-left corner is point(0, 0); assuming your Stage area is 640 × 480, the farthest point in the lower-right corner is point(640, 480). The Lingo term loc is short for location. The term locH is the location horizontally; locV is the location vertically. The loc of a sprite is a point() that is made up of the sprites locH and its locV. These values do not have to fall within the rectangle that makes up the Stage. A sprite can have negative coordinates or positive coordinates that are well outside the Stage’s width and height.
0
x-axis = locH (to the right is greater)
640 point(640, 0)
point(0, 0) 0
point(320, 240) = point(locH, locV)
y-axis = locV (further down is greater)
480 point(0, 480)
point(640, 480)
Figure 15-1: The coordinates of the Stage start at point(0, 0), in the upper-left corner. Note
In the EXERCISE:CH15 (EXERCISE\CH15) folder on the CD-ROM you can find a movie called coordinates.dir. If you are unfamiliar with this coordinate system, open this movie and move the sprite around the screen with the mouse. A field shows you the location of the sprite as you move it. This should help you understand the relationship between the sprite’s position on the screen and its loc.
3486-6 ch15.f.qc
7/24/00
5:51 PM
Page 575
Chapter 15 ✦ Controlling Sprites with Lingo
On the CD-ROM
In the EXERCISE:CH15 (EXERCISE\CH15) folder on the CD-ROM, open the movie mars landing 01.dir.
Changing the locH After you open up the movie mars landing 01.dir, note that it has two sprites on the Stage already. The background is the Martian terrain and a spaceship (see Figure 15-2).
Figure 15-2: The mars landing 01.dir movie
The only script in the movie is the frame script in frame 1. This script enables you to play the movie, and it will loop on the frame. For now, it does nothing other than loop on the frame. Ctrl+click (right-click) on the ship and choose Script from the pop-up menu. Delete the on mouseUp handler that is automatically placed in the window, and type what is shown in Figure 15-3. Name it B_Ship. The B stands for behavior.
575
3486-6 ch15.f.qc
576
7/24/00
5:51 PM
Page 576
Part IV ✦ Controlling Media with Lingo
Figure 15-3: The behavior for the ship sprite
In this behavior, you create the pSprite property, which is a reference to the sprite to which the behavior is attached. You also create a prepareFrame handler that is executed every time the playback head moves. Because we are looping on the frame, the playback head is moving at the tempo setting of the movie. Each time the prepareFrame executes, it checks whether the up arrow key or the down arrow key is pressed. If one is, then the sprite is moved 10 pixels up or down, respectively.
Changing the locV Now let’s add horizontal movement. Change the B_Ship behavior to include detecting right and left arrow presses, as shown in Figure 15-4. Play the movie and try the keys. You can press a left/right key and an up/down key at the same time to get diagonal movement. Before continuing, save the movie as mars landing 02.dir.
Add this code Figure 15-4: The behavior for the ship sprite expanded to support horizontal movement
Perhaps you want to have the ship wrap around when it reaches the other side of the screen. At each prepareFrame, you can check whether the sprite has moved beyond the width of the Stage. If it has, just move it over the width of the Stage.
3486-6 ch15.f.qc
7/24/00
5:51 PM
Page 577
Chapter 15 ✦ Controlling Sprites with Lingo
Instead of further cluttering up the prepareFrame handler, now would be a good time to create some custom handlers. The first custom handler you create is CheckForInput. This handler should contain the contents of the prepareFrame handler. The next custom handler, called CheckLocH, checks the horizontal location of the sprite to determine if it needs to be moved. The prepareFrame handler calls each of these (see Figure 15-5). When finished, save the movie as mars landing 03.dir.
Change this code
Move from prepareFrame
Add this code Figure 15-5: A cleaned-up prepareFrame handler and two new custom handlers
Persistence of Sprite Changes As you make changes to a sprite through Lingo, you might notice that each time you stop and rewind the movie, the sprites are restored to their original attributes (those specified in the Score). You also lose sprite changes if you go to a frame that is not within the span of the sprite, which is illustrated in the mars landing 04.dir movie (on the CD-ROM). Open the movie, play it, move the ship with the arrow keys. Then click anywhere on the Stage. Clicking will move you to frame 2; click again to return to frame 1. When you do, the ship is back in its original location.
577
3486-6 ch15.f.qc
578
7/24/00
5:51 PM
Page 578
Part IV ✦ Controlling Media with Lingo
Tip
When you go to a frame where the sprite with the behavior does not exist, and you then return, the sprite is back in its original position in the Score, and any properties the sprite had are reinitialized on return.
Jumping to different frames To further demonstrate the loss of property values, declare a property at the top of the B_Ship script. Call it pGreeting, as in Figure 15-6.
Add this code Figure 15-6: Greeting is declared, but it is not given a value anywhere in the script.
Play the movie, and while it is playing, in the Message window, type the following: put (sprite 2).pGreeting --
This is the expected result. pGreeting has not been given a value anywhere in the script (unlike pSprite). Give it a value in the Message window and test that value by using the put command: (sprite 2).pGreeting = “Hello” put (sprite 2).pGreeting -- “Hello”
Now, open the frame script, Frame_go to the frame and add the mouseUp handler shown in Figure 15-7. Play the movie and click anywhere in the frame. This script is on both frame 1 and 2; the simple case statement in the mouseUp handler enables us to toggle between frames. After clicking and going to frame 2, click again to return to frame 1. Type the following in the Message window: put (sprite 2).pGreeting --
3486-6 ch15.f.qc
7/24/00
5:51 PM
Page 579
Chapter 15 ✦ Controlling Sprites with Lingo
Add this code Figure 15-7: The case statement in the mouseUp handler enables us to toggle between frames 1 and 2.
The value of pGreeting was lost when we went to frame 2. Save the movie as mars landing 05.dir. pGreeting lost its value because the sprite spans only frame 1. If it were extended
to frame 2, it would retain its value. Do that now. Open the Score, click sprite 2, and Option+drag (Alt+drag) it to frame 2. Caution
Do not copy and paste the sprite in frame 2. If you do that, the sprite will not be continuous. It will be considered a new sprite and the values will be lost.
Try giving the pGreeting a value again and click the Stage to alternate between frames. It keeps its value as you navigate from one frame to the other. Save the movie as mars landing 06.dir.
Using markers Sometimes, giving explicit frame numbers, as in Figure 15-7, can lead to problems. What if you moved those frames? You’d have to go back into the script and change the frame numbers. On larger projects, this can be a real hassle, especially if you used those numbers in several places. As Figure 15-8 illustrates, the frames no longer need to be next to each other. In fact, sometimes it’s nice to have some space in the Score. Note that the ship sprite still needs to span both frames for it to retain its properties. Save the movie as mars landing 07.dir. After we’re sure the statements in the mouseUp handler are working, we can take them and use them in the B_Ship script. Create a new handler called SwitchLand, and copy and paste the code from the frame script into the SwitchLand handler. It is called from the CheckLocH handler. Every time the ship is moved to the other side of the screen, we jump to a different marker, as shown in Figure 15-9. Save the movie as mars landing 08.dir.
579
3486-6 ch15.f.qc
580
7/24/00
5:51 PM
Page 580
Part IV ✦ Controlling Media with Lingo
Sprite 2 is unbroken Moved from frame 2 to frame 5 Figure 15-8: The mouseUp handler altered to work with markers (frame labels)
Change this code
Add this code Figure 15-9: The code from the mouseUp handler in the frame script can be used in the B_ship script to make it appear to change landscapes.
Copied from mouseUp in frame script shown in figure 15-8
More Sprite Manipulations Moving a sprite a very common manipulation in Lingo, but there are many other manipulations that can be performed on sprites after you are comfortable with Lingo. In Chapter 14, you swapped cast members for a button sprite, but here you swap whole landscapes. You also use the distortion effects of rotation, skew, and scaling that were introduced in Director 7.
3486-6 ch15.f.qc
7/24/00
5:51 PM
Page 581
Chapter 15 ✦ Controlling Sprites with Lingo
Changing the member In Chapter 14, you learned how to swap sprites, changing states to make a button look like it was interacting with the cursor. Instead of putting different landscapes in different frames, why not do it all in one frame? This saves you the trouble of having to be scrolling all over the Score. On the CD-ROM
The movie mars landing 09.dir is in the EXERCISE:CH15 (EXERCISE\CH15) folder on the accompanying CD-ROM.
Open the movie mars landing 09.dir on the CD-ROM. Ctrl+click (right-click) sprite 1 (the landscape art) and choose Script to create a new behavior for that sprite. Name the behavior B_Land. Enter the code you see in Figure 15-10. Now the behavior on the sprite with the landscape takes care of switching its sprite’s member, as opposed to a behavior on a different sprite (such as the ship) altering this sprite’s member. For some, this logic may be more appealing. It seems natural that the behavior on sprite 1 is the only one that actually alters sprite 1. Figure 15-10: The SwitchLand handler is now in a behavior on the background sprite.
Next, open the B_Ship script and add a call to the SwitchLand handler in sprite 1, as shown in Figure 15-11. The B_Ship behavior no longer has any idea how the land changes: it just tells sprite 1 that it is time and sprite 1 takes care of the details.
Change this code Figure 15-11: The ship’s behavior tells the land when it needs to switch sprites.
581
3486-6 ch15.f.qc
582
7/24/00
5:51 PM
Page 582
Part IV ✦ Controlling Media with Lingo
Play the movie and try flying off the side of the screen. The background art changes as you do, and your ship appears on the opposite side of the screen. Save this movie as mars landing 10.dir. On the CD-ROM
The mars landing 11.dir movie is in the EXERCISE:CH15 (EXERCISE\CH15) folder on the CD-ROM.
Changing the visibility and locZ A handy and simple thing to do with Lingo is to change the visibility of a sprite. The ship in the Mars Landing movie needs a flame. Open the mars landing 11.dir on the CD-ROM. A flame has been added in sprite channel 3. We want the flame to appear only when the user is pressing the up arrow key, plus we want the flame to appear behind the ship. One way to make the flame appear behind the ship is to move it to a lower sprite channel. That is a valid option, but we would miss the opportunity to show you the locZ feature of Director 8. Tip
The locZ property of a sprite determines the order in which a sprite is drawn on the screen. The default value of the locZ is the sprite’s channel number.
A good example of using the locZ property is with the flame sprite. Ctrl+click (rightclick) the flame sprite and choose Script to create a new behavior. In it, type what is shown in Figure 15-12. Figure 15-12: The flame sprite follows the ship in sprite 2.
We have the flame in sprite 3, but we want it to appear below sprite 2. In the beginSprite handler for the B_Flame script, we set the locZ to 1. If we set it to 2, it would still appear above the ship. This is because when two locZ’s are equal, the higher sprite channel number is drawn above the other. If we set the locZ of the flame to 2, and the ship is in 2, then Director looks to see which is in
3486-6 ch15.f.qc
7/24/00
5:51 PM
Page 583
Chapter 15 ✦ Controlling Sprites with Lingo
the lesser channel. The ship is, so it is drawn first, below the flame. That is why we set the flame to have a locZ of 1. It still appears above the background in sprite 1 because the flame is actually in sprite 3. Another good reason to use the locZ in this situation is that the flame is following the ship sprite. With each exitFrame, the location of the ship is changed based on user input. Even though the locZ of the flame is set to be lower, the behaviors on the sprite still execute after the ship. Tip
Behaviors execute in the order of the sprite channels, starting with 1 and continuing through 1000. The behaviors in sprite 3 always execute after those in sprite 2, even when sprite 3 is being drawn below sprite 2.
The way it works in our movie now is that the ship sprite sets its locH and locV, and then the flame sets its loc based on the loc of the ship sprite. If the flame were in a lower sprite, it would set its loc based on the ship sprite before the ship sprite’s loc was changed for that exitFrame. One more change, just to enhance the spaceship flying experience. This planet needs gravity! Add a CheckLocV handler to the B_Ship script, as shown in Figure 15-13. Now, whenever the ship’s locV is less than 340 (higher on the screen), it will add 2 to the ship sprite’s locV. Save this movie as mars landing 12.dir.
Add this code Figure 15-13: Adding some gravity with CheckLocV
Rotating, skewing, flipping, and scaling sprites One of the most exciting features in Director 8 is the capability to rotate, skew, and flip sprites. Not just bitmap sprites, either — you apply these transformations to text, vector shape, animated .GIFs, and Flash members. This feature, however, is not available to fields, nor is it available to the ellipses and rectangles on the tool palette.
583
3486-6 ch15.f.qc
584
7/24/00
5:51 PM
Page 584
Part IV ✦ Controlling Media with Lingo
Setting these properties is very simple. To rotate sprite 1 to 30 degrees, for example, you can use dot notation or traditional Lingo syntax, as follows: sprite(1).rotation = 30 set the rotation of sprite 1 to 30
Skewing is also in degrees: sprite(1).skew = 10 set the skew of sprite 1 to 10
Flipping is set to TRUE or FALSE (1 or 0). You can flip horizontally with flipH or vertically with flipV: sprite(1).flipH = TRUE sprite(1).flipV = 1
You can scale a sprite up or down, rotate it, skew it, and still get great performance. The image quality is very good, too (especially when just scaling).
Scaling the ship and flame Continuing with our Mars landing, you can make the ship smaller as it gets higher, to give the illusion of it flying off into space (or coming down from space). You need to add a scaling routine to the flame as well. The routine is called CheckScale. It sets the width and height of the sprite, based on the width of the member, multiplied by a ratio based on the locV of the sprite. The ratio is based on the assumption that the highest the locV (lowest on the screen) the sprite will go is 340. When it is at 340/340, it will be at 100 percent (see Figure 15-14). While you’re in the B_Flame script, take this opportunity to create a CheckForInput handler, and move the keyPressed detection into it. This keeps the main event loop of this handler, the exitFrame, less cluttered, and it is more consistent with how we’ve coded the B_Ship script. Consistency can be a great help when you come back and look at your code in six months, trying to find out what you were thinking when you wrote it. Now would be a good time to save your movie as mars landing 13.dir.
Tweaking speed You might have noticed that the ship seems to zip into space faster as it gets higher. This may be partly due to the smaller screen area that Director has to redraw as the ship graphic is scaled down. But an even greater effect is the illusion of a much smaller ship moving 10 pixels versus a larger ship moving 10 pixels. The distance moved relative to its size is giving the perception of speed (or slowness). This effect can be improved by multiplying the distance to move the ship by the same ratio we are scaling the ship.
3486-6 ch15.f.qc
7/24/00
5:51 PM
Page 585
Chapter 15 ✦ Controlling Sprites with Lingo
Add this code
Code moved from prepareFrame
Figure 15-14: CheckScale is added to both scripts, and CheckForInput is added to B_Flame.
Create a new property called pLocRatio, named after the fact that it is a ratio based on the location of the ship. This value will be the locV of the sprite divided by 340.0. Make sure there is a “point zero” after the 340 so that Director uses a float. As mentioned in Chapter 11, if you use integers in your multiplication and division, the result is integers, which would introduce rounding errors (try it and see what happens). Your script should look like that in Figure 15-15. Don’t worry about not seeing the CheckLocH handler; it is still in the script. There were no changes to it, so we moved it below the CheckForInput handler. pLocRatio is initialized in the beginSprite handler and then needs to be updated each time through the exitFrame loop. Play
the movie and check out the difference this makes. Fly up high and note how much more time it takes to move across the black Martian sky. Save this movie as mars landing 14.dir.
585
3486-6 ch15.f.qc
586
7/24/00
5:51 PM
Page 586
Part IV ✦ Controlling Media with Lingo
Add this code
Change this value
Add this code
Figure 15-15: pLocRatio is added to all the handlers shown.
Tweaking movement Although there is much better movement, it still doesn’t seem like it flies up and down as smoothly as it could. It seems like it is moving in fits — subtle but noticeable. It also gets stuck near the top of the screen. What is happening? The ship sprite’s behavior has been using its own screen coordinates to modify its movements. This is a problem, because screen coordinates are integers. The smallest amount a graphic can move on the screen is 1 pixel. The float values from our calculations are being rounded. Suppose that the result of a calculation to determine the locV is 10.5; that will round to 11 on the screen. The next time through the loop, 11 is used in the calculation, because that is the value of the sprite’s locV. That five-tenths of a unit is lost. To be more accurate, the calculation should have used the result from the previous calculation. What is needed is a property for both the locH and locV that is a float value. This provides for the appearance of subpixel movement. If we slow how often it moves in a consistent manner, it appears to move in smaller increments.
3486-6 ch15.f.qc
7/24/00
5:51 PM
Page 587
Chapter 15 ✦ Controlling Sprites with Lingo
Add two more properties: pLocH and pLocv. We declared them on the same line (separated by a comma) to save space. Then replace wherever a sprite’s loc is set with the corresponding property. After those values have been set, they need to be applied to the sprite’s loc. Create a new handler called CheckLoc. In it, put CheckLocH, CheckLocV, and the statement to set the sprite’s loc (see Figure 15-16). Not shown are the other properties and handlers that do not have changes — they’re still there, above and below the code shown. Now fly the Mars Lander and check out how smoothly it goes up (until it is just a speck) and moves through the sky. Save this movie as mars landing 15.dir.
Add this code
Moved from prepareFrame Figure 15-16: To increase the precision of the sprite’s movement, properties are kept for the locH and locV of the sprite.
Change this code
Rotating the ship and diagonal movement You’re dying to turn that ship, aren’t you? Rotating a sprite is easy; it’s just a matter of setting the rotation to whatever increment in degrees you desire. There is a catch, of course: The ship needs to move in the direction that it is facing, and at the same
587
3486-6 ch15.f.qc
588
7/24/00
5:51 PM
Page 588
Part IV ✦ Controlling Media with Lingo
angle. This involves dusting off your trigonometry books. Don’t worry, it’s not much work, and we tell you the answers. Another benefit is a more realistic diagonal movement. Currently, if you hold down both a horizontal direction key and a vertical direction speed, you move at a faster rate (10 horizontally and 10 vertically). Fortunately, this involves the creation of only one handler and the altering of another. Because the ship is now rotated with the arrow keys instead of moving to the side, CheckForInput has to change. The new handler is called Thrust. We do away with checking for the down arrow key; gravity has been handling the downward movement for some time. Pressing the up arrow key calls the Thrust handler. Change CheckForInput and create the Thrust handler, as shown in Figure 15-17.
Change this code Figure 15-17: Rotating the sprite is easy, but moving it at the right angle takes some explaining.
Add this code
The rotation of the sprite is straightforward. When the left or right arrow key is pressed, the sprite is rotated left or right one degree. The only thing that might surprise you is that turning to the right is incrementing the angle — it goes clockwise. In trigonometry, a positive increase in the angle is counterclockwise. The angle of the sprite is converted to radians and put into the variable myAngle. Radians are another way of measuring angles. The sine and cosine functions use them. There are pi (3.14159. . .) radians in 180 degrees: myAngle = pSprite.rotation * pi()/180.0
3486-6 ch15.f.qc
7/24/00
5:51 PM
Page 589
Chapter 15 ✦ Controlling Sprites with Lingo
After we have the angle, the horizontal and vertical distances need to be determined. For that, we use the sin() and cos() functions, the Lingo version of sine and cosine. Because the zero position of an angle is usually horizontal, and our ship starts out vertical, we swapped the sin() and cos() functions. The number 10 is just the arbitrary number we’ve been using for acceleration, and pLocRatio adjusts the acceleration based on the locV of the ship: h = sin(myAngle) * 10 * pLocRatio v = -cos(myAngle) * 10 * pLocRatio
Last, we just increment pLocH and pLocV: pLocH = pLocH + h pLocV = pLocV + v
That wasn’t too bad, was it? You now have a routine for diagonal movement that you can use over and over. Fly this baby now! Oh, and save the movie as mars landing 16.dir.
Scrolling backgrounds An effect that is very popular in games is the scrolling background. The ship flies over the landscape as it moves beneath it in one continuous loop. The Mars Landing movie has almost everything it needs to implement a scrolling landscape. What happens is that the sprites holding the pictures of the landscape move instead of the ship. As the ship accelerates, the land moves faster. Because we have two background images, each the width of the Stage, we need to be checking their location constantly. If they get too far to one side or the other, they need to be moved so that no gaps appear in the landscape (see Figure 15-18). Open the movie mars landing 17.dir. It is the same as mars landing 16.dir, except that the handlers in the B_Ship script are reordered in the sequence in which they are called. If you want to continue with the movie that you have open, just be sure you make the changes to the correct handlers. The first thing you should do is to create four new properties we use in the movie, pSpeedH, pSpeedV, pMaxSpeed, and pAccel. Declare them at the top of the Script window as you’ve done with other properties, as shown in Figure 15-19.You can use the pSpeedH and pSpeedV properties to increment the location of the ship; you no longer have instant acceleration. The speed increases in increments until the maximum speed is reached. pMaxSpeed holds the value for the maximum speed. pAccel holds the amount you can increase the speed or accelerate each time through an exitFrame.
589
3486-6 ch15.f.qc
590
7/24/00
5:51 PM
Page 590
Part IV ✦ Controlling Media with Lingo
-640
0
640
1280
1) As landscape sprites are moved left to make ship appear to move right. Land 1 -640
0
Land 2 640
1280
640
1280
2) Sprite with Land 1 bitmap is about to move past -640. Land 1 -640
Land 2 0
3) When it does, its locH is incremented a positive 1280 (640 * 2) to give the impression of a continous landscape. Land 1
Land 2
Land 1
Figure 15-18: The mechanics of making the land appear continuous. The heavy black rectangle is what you see on the Stage.
Add this code
Figure 15-19: Four new properties are declared and initialized.
3486-6 ch15.f.qc
7/24/00
5:51 PM
Page 591
Chapter 15 ✦ Controlling Sprites with Lingo
The two speed variables are altered in the Thrust handler. Thrust altering speed seems logical. pAccel is also used here (see Figure 15-20).
Change this code
Figure 15-20: Thrust now affects speed, and the acceleration is no longer a literal, but the property variable pAccel.
In place of the literal 10, you can put the variable pAccel. Having a variable (property or otherwise) is better than having some arbitrary number appear more than once in the program. It is good practice to use variables instead of actual values in the code, especially when a value is used more than once. The number 10 is a good example of this. Seeing 10 doesn’t necessarily say “acceleration,” but the variable pAccel does. The 180.0 in the conversion of degrees to radians is all right, because it is only used once and it is a common value in a common equation. The handlers that deal with the ship’s location need to be changed as well, as shown in Figure 15-21. CheckLoc increments pLocV with pSpeed before setting the sprite’s locV. Then we need to move the land sprites (1 and 2) in relation to the speed. We call them MoveLand handlers (which we create shortly). CheckLocH needs to deal with the fact the ship is in a world 1280 pixels wide (640*2). If we had three 640-pixelwide landscapes, then we would change this number to 1920 (640*3), and so on. CheckLocV needs to increment pSpeedV instead of pLocV. This makes more sense too, because gravity is affecting the speed with which the ship is falling. The speed properties are zeroed out if the ship is at 340 pixels or lower and pSpeed is greater than 0. This keeps the ship from going below the bottom of the screen, and it enables it to lift off. Because the speed is being continually incremented, either by user input or by gravity, it needs to be checked against the maximum speed allowed, which is stored in pMaxSpeed. Create the CheckSpeed handler as shown in Figure 15-22. CheckSpeed is called from the exitFrame handler. It should be placed after CheckLoc in case CheckLoc exceeded the value in pMaxSpeed. Again, pLocRatio is used to make the speed relative to the position of the ship.
591
3486-6 ch15.f.qc
592
7/24/00
5:51 PM
Page 592
Part IV ✦ Controlling Media with Lingo
Add this code
Change this code
Figure 15-21: The handlers that deal with the ship’s location need to be modified.
Add this code Figure 15-22: The new speed properties pSpeedH and pSpeedV need to be checked against pMaxSpeed.
Currently, the movie has only one of the landscapes in the Score. Move the ship and flame sprites so that member Land 2 can be put in sprite 2. Then apply the B_Land script to sprite 2. After that, position sprite 2 at X:640 and Y:480, as shown in Figure 15-23. Having changed the sprite the ship is in, that change needs to be reflected in the B_Flame script. This script refers to sprite 2, assuming the ship is in it. It needs to be changed to sprite 3. The locZ also needs to change to 2, so that the flame does not appear behind the new landscape in sprite 2 (see Figure 15-24). You can now save this movie as mars landing 18.dir.
3486-6 ch15.f.qc
7/24/00
5:51 PM
Page 593
Chapter 15 ✦ Controlling Sprites with Lingo
Apply this behavior to sprite 2
Add this sprite Move these sprites down Figure 15-23: Member Land 2 in sprite 2 with the B_Land script applied
Change this code Figure 15-24: Changing the locZ for the B_flame sprite behavior
Using Parent Scripts with Sprites You might not be too surprised to learn that the Mars Landing movie can use a parent script. Director has many ways to create an animation in a single frame. You can use a film loop, a QuickTime movie, an animated .GIF, or even a Flash movie. A film loop can be convenient, because all the artwork is created in Director, but it is limited by a fixed regPoint, and the tempo runs at the tempo of the movie. QuickTime gives you some flexibility when it comes to tempo, but they are often created outside of Director; the performance goes down when it is not direct to Stage. Animated .GIFs have a moveable regPoint, but the format itself is limited to 8-bit. Last, Flash movies can be manipulated quite a bit, but they, too, are developed outside Director. This leads us to a custom solution, a parent script that plays a series of cast members, as if they were animation cels, at a frame rate you specify.
593
3486-6 ch15.f.qc
594
7/24/00
5:51 PM
Page 594
Part IV ✦ Controlling Media with Lingo
Creating the parent script Open the movie mars landing 19.dir. It has the same code as mars landing 18.dir, but added to it are 19 ship bitmaps to create an animation of the legs coming down (or going up). The ship in the Score is now called Ship 19, whereas before it was just Ship. Open a new Script window by choosing Window ➪ Script. If it opens an existing script, click the New Script button. Click the Cast Member Properties button to change this script to a parent script, and then name it animation. Type in the code that you see in Figure 15-25.
Figure 15-25: The beginning code of the animation script
The new function takes five parameters: ✦ me: the reference to the object. ✦ aSprite: a reference to the sprite this object will use. ✦ frRate: an integer of the rate the animation should play. ✦ animating: a Boolean value whether the animation is in the process of animating. ✦ doLoop: another Boolean value. This one indicates whether this is a looping animation. The nice thing about all these values is that they are easily changeable on the fly through Lingo. Inside the new handler, the properties that correspond to the parameters are given their values. pDir and pCels are also initialized. pDir is either 1 or –1, indicating forward or backward, respectively. pCels is a list that will be given a value later. That list will hold a series of member references that will be used like cels in an animation.
3486-6 ch15.f.qc
7/24/00
5:51 PM
Page 595
Chapter 15 ✦ Controlling Sprites with Lingo
The prepareFrame handler is quite simple. It tests whether the object is animating by testing the value of pAnimating in the if statement. If it is, then it increments the animation by calling the Increment handler. Below the prepareFrame handler, add the Increment handler shown in Figure 15-26. Figure 15-26: The Increment handler increments the animation in one direction or the other.
The Increment handler begins by checking the current time (in ticks) against the time in pLastTime. If the difference is greater than 60/pFrameRate, the animation increments one cel. 60 is the number of ticks in one second. pFrameRate was given the frRate value in the new handler. If pFrameRate is 15, then every 4 ticks the animation is updated. Inside the if statement, pCount is incremented; it keeps track of the cel it is on. pLastTime is also set to the current time in ticks. Based on the direction in pDir, the animation increments or decrements. After it has gone through all of the members in the pCels list, it stops, unless it is set to loop. The last handler we need is one to get the animation started. Figure 15-27 shows the StartAnimation handler. It takes a direction as a parameter. This handler does nothing if the object is already animating. If it is not, then pAnimating is set to TRUE, pDir is set, and pCount is set based on the direction in pDir. Figure 15-27: StartAnimation is the way to get this animation going (if it is not set to animate initially).
595
3486-6 ch15.f.qc
596
7/24/00
5:51 PM
Page 596
Part IV ✦ Controlling Media with Lingo
Instantiating the parent script The B_Ship script creates an instance (child object) of the animation script. Open the script B_Ship and declare a new property called pLegAnim right after pAccel. In the new handler, it is given a value. That value is a child object of the animation script. Passed along as arguments to the new function is the sprite reference for the ship (pSprite), the frame rate (30 fps), 0 for not animating, and 0 for not looping. After pLegAnim is initialized, a repeat loop adds 19 member references (Ship 1, Ship 2, and so on) to the pCels list within the child object in pLegAnim. Also shown is the prepareFrame handler. prepareFrame (pLegAnim) was added so that this child object gets a prepareFrame message every time the behavior that contains it gets one (see Figure 15-28). A new handler, ToggleLegs, needs to be added to the B_Ship script. This handler sets the direction of the animation based on the member that is currently in the sprite. It then starts the animation by calling the object’s StartAnimation handler.
Add this code Figure 15-28: Creating a child object of the animation parent script inside the B_Ship behavior.
CheckForInput needs an addition as well. It needs to check whether the user has pressed the L key. If so, ToggleLegs is called (see Figure 15-29).
Congratulations! You’ve come a long way since the beginning of the chapter when you moved a sprite 10 pixels up and 10 pixels down. You can save this movie as mars landing 20.dir.
3486-6 ch15.f.qc
7/24/00
5:51 PM
Page 597
Chapter 15 ✦ Controlling Sprites with Lingo
Add this code Figure 15-29: The ToggleLegs handler, called from CheckInput, sets the direction of the animation.
Sprite Rotation Revisited Sprite rotation is such a cool feature that it needs to be revisited now that the Mars Landing is complete. On the CD-ROM
The movie centipede.dir is in the EXERCISE:CH15 (EXERCISE\CH15) folder on the CD-ROM.
Open the movie centipede.dir on the CD-ROM. The next behavior you write is one to have a series of sprites follow the mouse, like a centipede. Figure 15-30 shows what the finished movie looks like.
Figure 15-30: The first sprite follows the mouse, and each subsequent sprite follows the one before it.
597
3486-6 ch15.f.qc
598
7/24/00
5:51 PM
Page 598
Part IV ✦ Controlling Media with Lingo
Ctrl+click (right-click) sprite 1 and choose Script to create a new behavior. In it, recreate what you see in Figure 15-31. For the sprite to follow something, it must have a target. What it really needs is a pair of coordinates for that target. In the prepareFrame, SetTarget is called. SetTarget will choose the mouse as the target if it is sprite 1. Otherwise, it chooses the sprite in the channel right below it and uses that sprite’s coordinates as the target.
Figure 15-31: First, the sprite gets the location of its target.
Next it needs to check its distance from the target. If it is too close, it will do nothing to prevent the sprites from ending up on top of each other. The angle of the sprite to the target needs to be calculated. CalcDegrees does just that. It checks for the special cases first; if it is not a special case, it gets the degrees by using atan(), the arctangent function. atan returns a value in radians, so it is converted to degrees by multiplying by 180 and then dividing by pi. Because atan returns a value between –pi radians and pi radians (–90 degrees and 90 degrees), the value needs to be adjusted based on what quadrant the target is in relative to the sprite, as shown in Figure 15-32. The last task is to move the sprite in the direction of the target; MoveSprite handles this. The amount the sprite moves is multiplied by 7. The value 7 is just an arbitrary number, so you can play around with different values to have it move at different speeds. The loc of the sprite is set and so is the rotation, as shown in Figure 15-33. Play your movie and watch the sprites snake around on the Stage like a centipede.
3486-6 ch15.f.qc
7/24/00
5:51 PM
Page 599
Chapter 15 ✦ Controlling Sprites with Lingo
Figure 15-32: CalcDegrees and CheckQuadrant calculate the angle between the sprite and its target.
Figure 15-33: MoveSprite sets the loc and rotation of the sprite.
Using Quads Whereas you can use the Score to take advantage of sprite rotation, skewing, and flipping, you can take advantage of quads only through Lingo. The quad of a sprite is a list of points defining the shape of the sprite. With quads, you can distort the perspective of a sprite referencing a bitmap or text cast member. Figure 15-34 shows two screen shots. The center points of spheres in the pictures are used to set the points in the quad of the sprites. The first picture is using a text cast member, and it is even editable! The second is using our Mars Lander, which (if you recall) has an alpha channel. A quad is a list of four points. Initially, the four points correspond to the corner points of a sprite’s rectangle. Using quads is as easy as 1, 2, 3, 4.
599
3486-6 ch15.f.qc
600
7/24/00
5:51 PM
Page 600
Part IV ✦ Controlling Media with Lingo
Figure 15-34: Using quads to create cool distortion effects
Modifying the Quad of a Sprite Property 1. Put the quad of a sprite into a variable. myQuad = sprite(2).quad
That variable now holds a list similar to the following: put the quad of sprite 2 -- [point(195.0, 93.0), point(422.0, 93.0), point(422.0, 419.0), point(195.0, 419.0)]
(The floatPrecision for the preceding code was set to 1). 2. You then can alter the points in that list. myQuad[1] = point(0,0)
3. After finishing, you set the quad of the sprite to your list. sprite(2).quad = myQuad updateStage
Figure 15-35 shows the code for the prepareFrame in the movies shown in Figure 15-34. The graphic to be distorted is in sprite 2. The four spheres are in sprites 11 through 14; they are set to be moveable. While the movie plays, you can drag them to distort the graphic.
3486-6 ch15.f.qc
7/24/00
5:51 PM
Page 601
Chapter 15 ✦ Controlling Sprites with Lingo
Figure 15-35: The quad of sprite 2 is changed from the frame script.
Score Recording Score recording is very useful for automating authoring tasks. It enables to you make permanent changes to sprites in the Score. Previously discussed was the persistence of changes made from Lingo. Those changes are only when the movie plays. After you stop, the original values in the Score are still there. To make them permanent, you can use Score recording. With Score recording, you can create tools to author Director by Director. It is a better tool for authoring because you take a performance hit when you start recording. On the CD-ROM
The movie score recording.dir is in the EXERCISE:CH15 (EXERCISE\CH15) folder on the CD-ROM that accompanies this book.
To illustrate the usefulness of Score recording, suppose that you have to create an animation that counts to 100, and for some reason it needs to be laid out in the Score (instead of just changing the contents of a field). Open the movie score recording.dir. Create a new movie script that looks like Figure 15-36. Figure 15-36: Laying out 100 frames with Score recording.
601
3486-6 ch15.f.qc
602
7/24/00
5:51 PM
Page 602
Part IV ✦ Controlling Media with Lingo
CreateCountdown starts recording with the beginrecording command. It then repeats 100 times. It creates a new text member and puts it into the variable m. It sets the text to i, which is the index of the iteration we are on. It sets the font to the compressed font in the movie, the fontSize, and the name of the member. Then it sets sprite properties of sprite 1. It sets the member, loc, foreColor, and ink properties. Last, it calls the updateFrame command. updateFrame updates the con-
tents of the frame and moves the playback head to the next frame. This handler is called from the Message window by typing: CreateCountdown
Rewind the movie and play it. Open the Score and Cast windows and take a look. The Score has 100 different members in the first 100 frames. The Cast has 100 new text members. You can save this movie as score recording 2.dir.
Puppeting Sprites Sometimes you want to make changes to a sprite and have those changes persist throughout the movie, but not stay fixed in the Score. One way to do this is to have a sprite span all the frames of the movie. Another way to do it is by using the puppetSprite command. When you use the puppetSprite or puppet command on a sprite channel, Director ignores any changes to the sprite that occur in the Score. It only displays changes to that sprite made from Lingo. When you puppet a sprite channel, if there is a member in the sprite, the puppeted sprite initially takes all the attributes of the current sprite. As shown in Chapter 13, you can also puppet empty score channels and place members into them. This is useful when you have no idea how many sprites you will be creating. On the CD-ROM
You can find the movie puppetsprites.dir in the EXERCISE:CH15 (EXERCISE\CH15) folder on the CD-ROM that came with this book.
Open the movie puppetsprites.dir (shown in Figure 15-37) on the CD-ROM. We don’t discuss this movie in depth, because many of the concepts were thoroughly examined in our discussion of the Mars Landing movie. If you open some of the scripts, many of the handlers should look familiar to you. They are just variations on what you did with the Mars Landing movie. Play the movie and fly around for a while. Besides the puppeting, there are some interesting aspects of this movie. It features an animated .GIF as one of its landscape images (land 3 with the volcano). The ship is a Flash movie. It uses flipH to flip the ship sprite. In addition, objects control all the sprites.
3486-6 ch15.f.qc
7/24/00
5:51 PM
Page 603
Chapter 15 ✦ Controlling Sprites with Lingo
Figure 15-37: The puppetSprites movie has a single item physically in the Score, and the rest is puppeted.
Open the script named movie scripts. In it, you see two handlers — both are functions (they return a value), as shown in Figure 15-38. Tip
If you want to open two script windows of the same script, as is done in Figure 15-38, Option+click (Alt+click) on the Next or Previous Cast member buttons (the arrows at the upper left), and then click back to the script you were in. Holding the Option (Alt) key while opening any script window opens another window, instead of changing the script that you see in the current script window. SetUpSprite is called from both the land and ship parent scripts. It has six parameters. The only one that is not optional is aMember, a reference to a member. If any of the other parameters have a void value, a default value is substituted. SetUpSprite calls GetSpriteRef to find an empty sprite channel. If all the channels are full, an alert pops up and the movie halts. Otherwise, SetUpSprite puppets the sprite and
sets the necessary properties. You need to set at least the six properties shown (including the puppet property) in order for it to appear on the Stage.
603
3486-6 ch15.f.qc
604
7/24/00
5:51 PM
Page 604
Part IV ✦ Controlling Media with Lingo
Figure 15-38: Functions that find an empty sprite channel and put a member in it.
Figure 15-39 shows our reason for choosing puppeting. When the world object generates the pLandList, it does not know how many members might make up that list. It keeps adding references to the list until no more can be found. In this case, when it looks for a member named land 11, the number of member will return a –1. It is assumed that the members are named in sequential order (land 1, land 2, and so on), with no gaps. This is a handy technique to keep your code flexible. If you were to add another landscape, all you need to do is give it the right name. On the other hand, you might decide you have too many landscapes and delete the last few. The code will still work without having to make any changes. Figure 15-39: The New( ) function for the world parent script
3486-6 ch15.f.qc
7/24/00
5:51 PM
Page 605
Chapter 15 ✦ Controlling Sprites with Lingo
The parent script P_Land is shown in Figure 15-40. The landscape moves in the prepareFrame handler. The event handler is initially called from the frame behavior Frame_main, shown in Figure 15-41. Then the gWorld object’s prepareFrame handler, shown in Figure 15-39, manually propagates the prepareFrame event. The prepareFrame handler in the P_Land parent script (and the ship’s, P_Ship) does not automatically get this event, as would a behavior; the event must be called from your code. gWorld propagates the message to the ship object pShip and to the land objects contained in pLandList. When it calls the prepareFrame for the land objects, it also passes along the pSpeedH property of the pShip object. Tip
The advantage of this technique is the capability to control when objects receive events and pass additional parameters.
The only behavior in our movie is the script Frame_main (see Figure 15-41). It also happens to be the only item in the Score. It creates the child object of the parent script P_World in the beginSprite handler and puts it into the global variable gWorld. Every time the behavior gets a prepareFrame event, it propagates the message to the world object contained in gWorld. Figure 15-40: The parent script used for the land objects
Tip
Another advantage of this technique is that the entire game could be paused simply by stopping gWorld from getting prepareFrame events. Because Director would still be looping on the frame, it would continue to be processor friendly, handling events. This is a much better way to pause a game than locking up the processor in a repeat loop.
605
3486-6 ch15.f.qc
606
7/24/00
5:51 PM
Page 606
Part IV ✦ Controlling Media with Lingo
Figure 15-41: The frame behavior on frame 1 is the only item in the Score. It creates the world in the beginSprite handler.
Summary By the end of this chapter, you should feel much more comfortable taking control of sprites via Lingo. You learned a few things in this chapter including: ✦ The screen coordinate system is similar to the Cartesian coordinate system, except that the y-axis is flipped so that y increments increase as you go down the axis. ✦ Sprites can be moved, rotated, skewed, flipped, and scaled from Lingo. ✦ Changes from Lingo only persist for the length of the sprite’s span in the Score, unless you puppet it or permanently change it through Score recording. ✦ Without Score recording, changes from Lingo revert to the Score after the movie stops. ✦ Using trigonometry functions to move the sprite at different angles can provide more realistic motion. ✦ Swapping a sprite’s member to create an animated effect should be second nature by now. ✦ Multiple scrolling background images can be implemented to give the illusion of a large world. In the next chapter, we look at how to manipulate all aspects of text members by means of Lingo.
✦
✦
✦
3486-6 ch16.f.qc
7/24/00
5:51 PM
Page 607
16 C H A P T E R
Text Manipulation with Lingo
E
ven in the world of multimedia, where pictures and sounds reign supreme, creating and manipulating strings of text is a large part of programming with Director. With a little bit of Lingo, you can control the properties of text in the Cast window or on your Stage. In this chapter, you learn to control every attribute of text through Lingo that you can set through the user interface, plus a few extras.
✦
✦
✦
✦
In This Chapter Setting font, font color, font style, and font size Working with chunk expressions Using hyperlinks Formatting paragraphs Selecting text
Understanding the Properties of Text Director 8 has two ways of implementing text in the user interface — through field cast members and text cast members. For brevity, we refer to text cast members as text members and field cast members as fields. Text in a variable or written in the code (between quotes) is referred to as a string. Support of fields is mainly for historical reasons, but they still have their advantages (see the “Text Cast Members versus Field Cast Members” sidebar).
Setting the foreground color The foreground color is the color of the text in the field. The default is black text on a white background.
HTML and RTF of text members Field-only properties
✦
✦
✦
✦
3486-6 ch16.f.qc
608
7/24/00
5:51 PM
Page 608
Part IV ✦ Controlling Media with Lingo
Text Cast Members versus Field Cast Members There are important differences and confusing similarities between fields and text members. We need to briefly review software history to shed some light on them for both old and new users. In Director 4 and earlier, fields were the only way to get text on the screen (other than using bitmaps, which aren’t really text but images). The type of member was #text. In Director 5 and 6, if you wanted text that was editable at run-time by Lingo or by the user, you needed to use fields. If you wanted antialiased text, you needed to use text members. The problem with text members was that during playback in Shockwave or a projector, you could not edit them, because they were converted to bitmaps. The type of this new member was #richText. The type of a field now returned was #field instead of #text. In Director 7, you could edit text members at run-time for the first time. You could also change their attributes, such as fontStyle, font, and alignment. Text members can now do everything fields can do (with minor exceptions) and more. If you need your text to rotate, skew, flip, or antialias, or if you need to have hyperlinks, change charSpacing or paragraph spacing, or get its picture, or have its quads manipulated, use text members. If you want to save around 500 bytes per cast member, then use fields. With all that you can do with text, we can’t think of a reasonable argument to use fields, except in situations in which you are dealing with pre-Director 7 movies or maybe storing information within a movie to be saved. Since Director 7, a test of the text member’s type now returns #text instead of #richText; fields still remain #field.
Getting and setting the foreColor You can change the foreground color of text in a member using the foreColor of member property. The syntax is: set the foreColor of member targetMember to colorNumber
In this statement, targetMember is replaced with either the cast member name or number. The colorNumber is replaced with an index number representing a color from the current color palette. The value should be set between 0 and 255 — a higher number wraps back around; for example, 256 displays color 0, 257 displays color 1, and so on. On the CD-ROM
The text1.dir movie is in the EXERCISE:CH16 (EXERCISE\CH16) folder on the CD-ROM.
Open a new movie and create a text cast member on the Stage, or open text1.dir on the CD-ROM. In the Message window, type the following: set the foreColor of member 1 to 35
3486-6 ch16.f.qc
7/24/00
5:51 PM
Page 609
Chapter 16 ✦ Text Manipulation with Lingo
This changes the text to red (35 happens to be red on both Macintosh and Windows platforms). You can also use dot notation, which has this syntax: member(targetMember) = colorNumber
To use it in our current movie, type the following in the Message window: member(1).foreColor = 255
It now changes to black.
Getting and setting the color Another way to set the foreground color of text is to use the new color data type (first discussed in Chapter 12). You can create rgb or paletteIndex color objects and assign the color to the text. In the Message window, type the following: myColor = color(#paletteIndex, 35) put myColor -- paletteIndex( 35 ) member(1).color = myColor
Make sure that you use the parentheses around the member number! Now, try testing the color of the member, as follows: put the color of member 1 -- rgb( 255, 0, 0 )
Even though you assigned a paletteIndex color, the color property always returns a color in the form rgb(red, green, blue). But the index can still be retrieved with the foreColor property: put the foreColor of member 1 -- 35 Caution
Getting the foreColor of the member, as just shown, will return the foreColor of the first character in the text member. Oddly, if you try to get the paletteIndex of this member, it will return 255, not 35, even if all of the text is set to red. put the paletteIndex of member 1 -- paletteIndex( 255 )
Setting the background color The background color is the color behind the type — the default is black type on a white background.
609
3486-6 ch16.f.qc
610
7/24/00
5:51 PM
Page 610
Part IV ✦ Controlling Media with Lingo
Getting and setting the backColor It probably comes as no surprise that you can set the background color of the text as well as the foreground color. The syntax for setting the background color is: set the backColor of member targetMember to colorNumber
To use it with the preceding example, change the type to white and the background to red by typing the following code: set the foreColor of member 1 to 0 set the backColor of member 1 to 35
Using dot notation, change the backColor to black, as follows: member(1).backColor = 255
Getting and setting the bgColor If you want to use the color data type, then you need to set the bgColor instead of the backColor: set the bgColor of member(1) to myColor member(1).bgColor = myColor
The background changes to red, assuming myColor still holds paletteIndex(35), as you specified earlier. You can set rgb colors as well.
Setting the fontSize To change the type size of the text stored in a field, use the fontSize of member property. The syntax for both standard and dot notation is the following: set the fontSize of member targetMember to size member(targetMember).fontSize = size
In this statement, targetMember is replaced with either the cast member name or number. The size parameter is replaced with the desired font size in points. On the CD-ROM
The text1.dir movie is in the EXERCISE:CH16 (EXERCISE\CH16) folder on the CD-ROM.
Open a new movie and create a text cast member on the Stage, or open text1.dir on the CD-ROM. In the Message window, type the following: member(1).fontSize = 24
3486-6 ch16.f.qc
7/24/00
5:51 PM
Page 611
Chapter 16 ✦ Text Manipulation with Lingo
The type changes to the smaller point size. Now, change it again, as follows: set the fontSize of member 1 to 36
As with the color properties, you can get this value as well as set it: put the fontSize of member 1 -- 36 put member(1).fontSize -- 36
Setting the font You can change the typeface of text by using the font of member property. The syntax for both standard and dot notation is the following: set the font of member targetMember to fontName member(targetMember ).font = fontName
In this statement, targetMember is replaced with either the cast member name or number. The fontName parameter is replaced with the name of a font. Open text1.dir on the CD-ROM. In the Message window, type the following: set the font of member 1 to “Times *”
This changes the typeface to the embedded font “Times *”, which is cast member 3, as shown in Figure 16-1.
Figure 16-1: Changing the font of member 1 to the embedded font “Times *”.
To change the typeface back, use dot notation: member(1).font = “Hanzel Condensed-Bold *”
611
3486-6 ch16.f.qc
612
7/24/00
5:51 PM
Page 612
Part IV ✦ Controlling Media with Lingo
Knowing that “Hanzel Condensed-Bold *” is in member 2, you could write the following code: member(1).font = the name of member 2 Tip
Referencing members by their position in the cast is not a good idea in your code; it is safer to reference them by name. (Otherwise, every time you move the member, you have to change your code!) When you are working in the Message window, experimenting can be fun, but sometimes it’s nice to do things the easy way.
Missing fonts The missingFonts text cast member property returns a list of font names that are referenced by a member but are not in the system. Set the font of member 1 to one that is not in your system: set the font of member 1 to “abc”
The text member remembers the font it should be, but because it is not there, it is displayed in Helvetica. If you put the missingFonts, you see it is there: put the missingFonts of member 1 -- [“abc”]
Substituting fonts The substituteFont text member command substitutes one font in a member for another. The syntax for both standard and dot notation is as follows: substituteFont(member targetMember, fontName1, fontName2) member(targetMember).substituteFont(fontName1, fontName2)
If you want to deal with the missing font from the earlier example, you should write the following: substituteFont(member 1, “abc”, “Hanzel Condensed-Bold *”)
Adding Shockfonts Shockfonts are fonts embedded into your movie. With the recordFont command, you can add fonts through Lingo. The syntax is the following: recordFont(fontMember, font, [style], [bitmapSizes], characterSubset)
The various parameters for the recordFont command are: ✦ fontMember is a font member. ✦ font is a string, the name of the font you want to record (embed).
3486-6 ch16.f.qc
7/24/00
5:51 PM
Page 613
Chapter 16 ✦ Text Manipulation with Lingo
✦ [style] is a list of symbols. They are the style of the font you want to include, such as #plain, #bold, and #italic. This is an optional parameter; if left off or set to an empty list, only #plain is used. ✦ [bitmapSizes] is a list of integers. They are the point sizes of bitmapped fonts that you want to include. For smaller text sizes, bitmapped fonts are supposed to be more readable. This is an optional parameter; if left off or set to an empty list, it does not include any bitmaps. Including bitmaps increases the file size. ✦ characterSubset is a string. It is the list of characters to include in the font. If you need only a few characters, this can save you space. This is an optional parameter; if left off, it includes all of the characters in the font. To use recordFont, you must use a font member. If you don’t have one, you can create one by using the new function, as shown here: myFont = new(#font) recordFont(myFont, “Times”, [#bold], [18, 24], “Mars Landing”)
If you don’t want to specify any optional parameters, you can write this code: recordFont(myFont, “Times”)
If you just want to use the last optional parameter, you need to remember to put empty lists in for the other optional parameters (because they take lists), as follows: recordFont(myFont, “Times”, [], [], “Mars Landing”)
Determining fonts available There are two undocumented commands for determining the fonts in your system. The first is the fontList function. The syntax for both standard and dot notation is: fontList(fontMember) fontMember.fontList()
You can use any font member to get this information. In the movie text1.dir, type the following command in the Message window and see these results: put fontList(member “Times *”).count -- [“Abadi MT Condensed Light”, “Arial”, “Arial Black”, “ASI_Mono”, “ASI_System”, “Book Antiqua”, “Calisto MT”, “Century Gothic”, “Comic Sans MS”, “Copperplate Gothic Bold”, “Copperplate Gothic Light”, “Courier”, “Courier New”, “Fixedsys”, “Hanzel Condensed-Bold *”, “Impact”, “Lucida Console”, “Lucida Handwriting”, “Lucida Sans”, “Lucida Sans Unicode”, “Marlett”, “Matisse ITC”, “MS Sans Serif”, “MS Serif”, “News Gothic MT”, “OCR A Extended”, “Small Fonts”,
613
3486-6 ch16.f.qc
614
7/24/00
5:51 PM
Page 614
Part IV ✦ Controlling Media with Lingo
“Symbol”, “System”, “Tahoma”, “Tempus Sans ITC”, “Terminal”, “Times *”, “Times New Roman”, “Verdana”, “Webdings”, “Westminster”, “Wingdings”]
The list returned is a list of all fonts installed. The next function is called the outLineFontList. This function returns all fonts in the system that can be used to create Shockfonts using recordFont. The syntax for both standard and dot notation is: outLineFontList(fontMember) fontMember.outLineFontList()
Just as you can use any font member as an argument for the fontList function, the outLineFontList also takes any font member. In the movie text1.dir, you type the following put command in the Message window and see results similar to those shown here: put outLineFontList(member “Times *”).count -- [“Abadi MT Condensed Light”, “Arial”, “Arial Black”, “Book Antiqua”, “Calisto MT”, “Century Gothic”, “Comic Sans MS”, “Copperplate Gothic Bold”, “Copperplate Gothic Light”, “Courier New”, “Hanzel Condensed-Bold *”, “Impact”, “Lucida Console”, “Lucida Handwriting”, “Lucida Sans”, “Lucida Sans Unicode”, “Marlett”, “Matisse ITC”, “News Gothic MT”, “OCR A Extended”, “Symbol”, “Tahoma”, “Tempus Sans ITC”, “Times *”, “Times New Roman”, “Verdana”, “Webdings”, “Westminster”, “Wingdings”]
Your results will differ from these, because they are based on the fonts in your system. Note that the fontList in this example has 38 items and the outLineFont List has only 29. Note
The preceding results for fontList and outLineFontList were done on a system running Windows 98.
Caution
The fontList and the outLineFontList are not documented functions. Use them at your own risk.
Setting the style To change the style of text, use the fontStyle of member property. The syntax for both standard and dot notation is: set the fontStyle of member targetMember to styleName member(targetMember ) = styleName
3486-6 ch16.f.qc
7/24/00
5:51 PM
Page 615
Chapter 16 ✦ Text Manipulation with Lingo
In this statement, targetMember is replaced with either the cast member name or number. The styleName parameter is replaced with a list of styles. On the CD-ROM
The text1.dir movie is in the EXERCISE:CH16 (EXERCISE\CH16) folder on the CD-ROM.
Open the text1.dir movie on the CD-ROM. In the Message window, type the following: set the fontStyle of member 1 to [#italic, #bold]
The styles are in the form of symbols, and you can specify more than one style in the list. In the preceding example, the text is changed at once to be bold and italic, as shown in Figure 16-2.
Figure 16-2: The fontStyle can be changed to italic and bold in one step.
There are four styles supported: #plain, #bold, #italic, and #underline. Setting a member to [#plain] removes all styles. But setting them one by one has an additive effect. Set the text to plain, and then, one statement at a time, set it to be bold, italic, and underline, and use dot notation, as shown here: member(1).fontStyle member(1).fontStyle member(1).fontStyle member(1).fontStyle and underlined
= = = =
[#plain] -- gets rid of all styles [#bold] -- now it is bold [#italic] -- now it is bold and italic [#underline] -- now it is bold, italic
615
3486-6 ch16.f.qc
616
7/24/00
5:51 PM
Page 616
Part IV ✦ Controlling Media with Lingo
Using the autoTab property The autoTab property determines whether the Tab key makes the next editable text active. This property works with both fields and text members. It can be set to TRUE or FALSE. The order in which the tabbing occurs is based on the sprite channel numbers, not position on the Stage. Following are examples of dot and standard notation for turning the autoTab property OFF and then ON again for member “myText”: member(“myText”).autoTab = FALSE set the autoTab of member “myText” to TRUE
Using the picture property You can create bitmapped images of text members with the picture property. This property works with both fields and text members. To create a picture and place it into a new bitmap member, type the following: (new(#bitmap)).picture = member(“myText”).picture
The bit depth of the bitmap created is that of the monitor. If you want to capture the reference of the member created with the new(#bitmap) function, you can do the preceding in several steps. The advantage of having the member reference in a variable is that it enables you to know where that bitmap was put, and to do things such as name the new member: set bm to new(#bitmap) bm.picture = member(1).picture -- member(1) is a text member bm.name = member(1).name && “bitmap” -- assumes member(1) has a name
Using the boxType property The boxType is the type of text box used for the field or text member. Options are #adjust, #scroll, #fixed, and #limit (#limit is for fields only).
Using the editable property This property enables you to change whether a field or text member is editable.
Using Chunk Expressions So far, you have used the properties of text to change the entire contents of a text member. By using Director’s chunk expressions, you can take a “bite” out of a text member and manipulate that chunk without changing the entire contents of the member. In word processing, you can change or modify a specific character, word,
3486-6 ch16.f.qc
7/24/00
5:51 PM
Page 617
Chapter 16 ✦ Text Manipulation with Lingo
line, or paragraph of text. In Director, you can also control a chunk of text, such as a specific character, word, item, or line.
Understanding strings Your computer looks at text as a string of characters. For instance, the following string of characters makes up a quotation: “They are ill discoverers that think there is no land, when they can see nothing but sea.” — Sir Francis Bacon (from Advancement of Learning). This sample string includes not only alphabetical characters (A, a, B, b, C, c, and so on), but also punctuation (quotation marks, period, and comma) and special characters (left and right parentheses), plus spaces that separate words. When you work with chunk expressions, don’t forget that spaces, punctuation, and special characters are all counted as part of a string.
Guidelines for working with strings This section provides some helpful rules to keep in mind when you’re working with strings in Director. To work effectively with strings, you must remember that: ✦ Strings are always surrounded by quotation marks. The quotation marks used in the Lingo language to denote a string are straight quotation marks, like those used for inches, not the “curly” quotes used in typesetting. ✦ You can insert a string into fields, text members, or into a variable by using the put command. On the CD-ROM
The text2.dir movie is in the EXERCISE:CH16 (EXERCISE\CH16) folder on the CD-ROM.
Open text2.dir on the CD-ROM. Type the following line in the Message window to add the text between the quotation marks to the field myField: put “Too soon old, too late smart” into field “myField”
Note that field myField here refers to cast member 1. You can use this command to put text into an empty field or text member or to replace existing text. However, if member 1 is something other than a field — such as a text, bitmap, sound, or script cast member — the instruction does not work and the contents of the cast member remain unchanged. The empty member is on the Stage, so when the command is executed, you see the text appear on the Stage and in the member. For more information on the effects of changing the content of a member, see the sidebar “When Is the Stage Updated?”
617
3486-6 ch16.f.qc
618
7/24/00
5:51 PM
Page 618
Part IV ✦ Controlling Media with Lingo
You can use a slightly different form of the put command to place text in a field cast member: put “Too soon old, too late smart” into member “myField”
This applies whether you use a cast member name or a number in the syntax of the command. You can use a similar syntax to place a string into either a local or global variable: put “You can’t tell how deep a puddle is until you step into it.” into proverbs
To initialize a variable (that is, to establish what the variable represents before any processing occurs), you can use an empty string. You do this by placing an empty string in a cast member with either of the following commands: put “” into field 1 put EMPTY into member 1 On the CD-ROM
The text3.dir movie is in the EXERCISE:CH16 (EXERCISE\CH16) folder on the CD-ROM.
When is the stage updated? Changes to sprite properties, such as the locH, locV, or the ink, take place when the playback head moves (to another frame or back to the same frame it is on) and when the updateStage command is used. A field is updated as soon as it changes, even in a repeat loop. Changed text members and vector shapes are updated when sprite properties are updated, unless a field is being updated. If a field has its contents changed (and it is on the Stage), text members and vector shapes also are updated if their content has been changed — instead of waiting for an updateStage! To see this in action, look at text3.dir on the CD-ROM. Play the movie text3.dir. You see the text change in both the field at the top and the text member at the bottom. You also see the four-sided vector shape change its shape when the text changes. After a few seconds, you see the vector shape change locations. If you look in the code, you see that the location should change every time the text changes, for a total of five times each exitFrame. It is only changing once, because the sprite’s properties are only updated upon entering the frame (unless you use the updateStage command). If you uncomment the updateStage command in the ChangeLoc handler, you will see the shape move whenever the text changes.
3486-6 ch16.f.qc
7/24/00
5:51 PM
Page 619
Chapter 16 ✦ Text Manipulation with Lingo
Caution
If you removed the updateStage and the field member from the Score (or just commented the line of code that alters the field’s contents), you will not see the text member or vector shape change in the repeat loop! This is an oddity of Director fields. Knowing this can save you a long and difficult bug hunt if you ever encounter text or vector shapes being updated mysteriously.
EMPTY is a character constant and always has the same value: an empty string. Character constants are not case sensitive, so the constant can be entered as EMPTY, Empty, or empty. When referring to a field, you can use its name or cast member number. If you use a field name, you must enclose it within quotation marks. If you use a number, Director assumes you are referring to a member in castLib 1, the internal castLib. For example, if you want to put text into a field myField that is in castLib 2 and not the field named myField in castLib 1, you could write it one of several ways: put “Easy come, easy go” into field “myField” of castLib 2 put “Easy come, easy go” into member “myField” of castLib 2 put “Easy come, easy go” into member(“myField”, 2)
In any of the preceding, you can reference the castLib by name, as follows: put “Easy come, easy go” into member(“myField”, “Fields”)
It is better to use a cast member’s name, rather than its number. When you reference a member by name, Director searches all of the castLibs until it finds one that matches. This enables you to move your cast members around without worrying about changing the code. Referencing them by name also makes the code more readable. Remember to surround the name in quotation marks; otherwise, Director thinks you are trying to use a variable. Lingo uses quotation marks to identify the beginning and end of a string. To include quotation marks within a string, you must use the QUOTE constant, as shown in the following example: put “T. S. Eliot once said,” && QUOTE & “Only those who risk going too far can possibly find out how far one can go.” & QUOTE into member “myText”
If the field or text member into which you place a string is not on the Stage, it is stored in the member, but it is not displayed on the Stage. This might seem obvious, but it is useful to point out because you can change a string before it is displayed in your movie.
619
3486-6 ch16.f.qc
620
7/24/00
5:51 PM
Page 620
Part IV ✦ Controlling Media with Lingo
Understanding chunk keywords You can use chunk expressions to select a portion of a string (a chunk of it). You can use chunk expressions with fields, text members, and variables containing strings. Table 16-1 shows the different levels of chunk expressions.
Table 16-1 Chunking Levels Level
Keyword
Example
Characters
char
put member(“field_or_text”).char[5] put char 5 of field “myField”
Words
word
put member(“field_or_text”).word[2] put word 2 of field “myField”
Items
item
put member(“field_or_text”).item[3] put item 3 of field “myField”
Lines
line
put member(“field_or_text”).line[2] put line 2 of field “myField”
Paragraphs
paragraph
put member(“field_or_text”). paragraph[1]
Using the char keyword You use the char keyword to get or set one or more characters in a text member, field, or string. On the CD-ROM
The text4.dir movie is in the EXERCISE:CH16 (EXERCISE\CH16) folder on the CD-ROM.
Getting a char Open the text4.dir movie on the CD-ROM. In the Message window, type the following: put field “myField” into aQuote put aQuote -- “One for the money, two for the show, three to get ready, and four to go.”
3486-6 ch16.f.qc
7/24/00
5:51 PM
Page 621
Chapter 16 ✦ Text Manipulation with Lingo
The variable aQuote now holds a copy of the text that is in the field myField. To get a single char from the string variable aQuote, type the following: put char 3 of aQuote -- “e”
To get a range of characters, type this: put char 1 to 10 of aQuote -- “One for th”
This same syntax works for fields. In the place of the string (or string variable), you use a field reference, as follows: put char 2 of field “myField” -- “n”
If you try to use a member reference instead, as in the following, you get an error: -- THIS SYNTAX DOESN’T WORK! put char 5 of member “myField”
Director considers the syntax field myField to be a string, so string operations work on it. You can test this by using the stringP function to test whether something is a string: put stringP(field “myField”) -- 1 put stringP(member “myField”) -- 0
Using the field keyword returns a string, so it tests true (1). Using the member keyword returns a reference to a member, so stringP returns false (0). To access text in a text member, you need to use a variation on the syntax or use the dot notation, as shown here: put char 10 of the text of member “myText” -- “h”
Note the addition of the text keyword. This syntax also works with fields. The problem with the syntax is that you cannot use a similar syntax for setting chars. This is because the text keyword returns the text of the member, so you are not manipulating the text in the member. It is better to use the new dot notation: put member(“myText”).char[10] -- “h”
621
3486-6 ch16.f.qc
622
7/24/00
5:51 PM
Page 622
Part IV ✦ Controlling Media with Lingo
You can use this method on fields by using the member keyword and on string variables, but not string literals: put member(“myField”).char[6] put field(“myField”).char[6] put aQuote.char[6]
Getting a range of chars To get range of chars, use this syntax: put char 1 to 3 of field(“myField”) -- “One” put char 21 to 23 of aQuote -- “two”
This syntax does not work with text members. To access a range of chars from a text member, it is necessary to use the dot notation, as shown here: put member(“myText”).char[40..44] -- “three”
This syntax works with strings and fields as well.
Setting a char To set a char, you use the put. . .into syntax for fields and strings: put “o” into char 1 of field “myField” put “o” into char 1 of member “myField” put “o” into char 1 of aQuote put “o” into char 1 of member “myText” -- DOES NOT WORK!
For text members, use the dot notation with the assignment operator (equals sign), as follows: member(“myText”).char[5] = “X”
Just because you are setting the value of one char, it doesn’t mean you cannot insert more: member(“myText”).char[5] = “XYZ”
Unfortunately, the dot notation does not work when assigning values to strings or fields: field(“myField”).char[1] = “X” -- DOES NOT WORK! aQuote.char[1]= “Y” -- DOES NOT WORK!
3486-6 ch16.f.qc
7/24/00
5:51 PM
Page 623
Chapter 16 ✦ Text Manipulation with Lingo
The assignment of chars with dot notation does work with fields if you use the member keyword, as shown here: member(“myField”) = “Z” -- WORKS!
Setting a range of chars Setting a range of characters is different depending on whether it is a string, field, or text member and the notation that you use — either standard or dot: put put put put
“1” into char 1 to 3 of aQuote “2” into char 21 to 23 of field “myField” “One” into char 1 to 3 of member “myField” “XXX” into char 1 to 3 of member “myText” -- DOES NOT WORK
You need to use dot notation to set text in a text member. But you’ll find it does not work for everything. The same restrictions for setting a single char exist for a range of chars: aQuote.char[1..3] = “1” -- DOES NOT WORK field (“myField”).char[5..8] = “Two” -- DOES NOT WORK! member(“myField”).word[9..12] = “Three” member(“myText”).word[13..16] = “Four”
Counting chars Counting chars is easy, but don’t use the count() function from lists! Chars use the number keyword, as shown here put the number of chars in aQuote -- 75 put the number of chars in field “myField” -- 75 put the number of chars in member “myText” -- DOES NOT WORK
To get the number of chars using the member keyword with either fields or text, you need to use the text of member syntax: put the number of chars in the text of member “myText” -- 75
For strings and fields, you can use the length() function: put length(aQuote) -- 75 put aQuote.length -- 75 put length(field “myField”) -- 75
623
3486-6 ch16.f.qc
624
7/24/00
5:51 PM
Page 624
Part IV ✦ Controlling Media with Lingo
Here is another odd exception: put aQuote.length() -- DOES NOT WORK put field(“myField”).length() -- DOES NOT WORK
The first one does not work because parentheses were added, which is an inconsistency in Lingo. Usually, if you are calling a function, you need parentheses. As in the count() function syntax for lists — myList.count(). If you were to forget to add the parentheses, you would get an error. Oddly, the dot notation does not work with parentheses after length. Hopefully, inconsistencies like these will change in a future update.
Using the word keyword The word chunk expression is used in a fashion similar the use of char. The way Director determines a word is based on the space, Return, and Tab characters. Any characters between those — and at the beginning and end of a string — is a word. The result does not include those characters. It can be said that the word command uses the space, Return, and Tab characters as a delimiter (a delimiter is a character that is used to separate chunks of text). Given the similarities between the syntax for chars and the remaining chunk expressions, the examples are shorter.
Getting words If you’ve made changes to text4.dir, just choose File ➪ Revert to start fresh. If you’ve changed the variable aQuote, reset it now by typing the following: put field (“myField”) into aQuote
Now, try putting some of the words to the Message window from the string, field, and text, as follows: put word -- “One” put word -- “for” put word put word -- “the”
1 of aQuote 2 of field “myField” 3 of member “myText” -- DOESN’T WORK! 3 of the text of member “myText”
Once again, the member keyword trips us up when using a chunk expression! Now try the dot notation: put aQuote.word[4] -- “money,” put field(“myField”).word[5] --DOESN’T WORK! put member(“myField”).word[5] -- “two” put member(“myText”).word[6] -- “for”
3486-6 ch16.f.qc
7/24/00
5:51 PM
Page 625
Chapter 16 ✦ Text Manipulation with Lingo
Arrrgghh! This time, the field keyword tripped us up. Given the subtle differences between using fields as opposed to text members, you can see why it might be easier to retain your sanity by sticking to just one or the other. One nice aspect of fields is that the syntax is similar to that of strings. Still, text member capabilities seem to outweigh that advantage. So, you are forced to remember both the string and text syntax.
Getting a range of words Getting a range of words is just like getting a range of chars, which you do as follows: put word 1 to 4 of aQuote -- “One for the money,” put word 5 to 8 of field (“myField”) -- “two for the show,” put word 9 to 12 of member (“myField”) -- “three to get ready,” put word 13 to 16 of the text of member (“myText”) -- “and four to go.”
Note that you can use the keywords field or member for fields. the text of member is added to get the words from “myText”. The following code example uses the dot notation. Note that to get the words from “myField”, you need to use the member keyword. If you use the field keyword with dot notation, you get unexpected results: put aQuote.word[1..4] -- “One for the money,” put member(“myField”).word[5..8] -- “two for the show,” put member(“myText”).word[9..12] -- “three to get ready,”
Setting a word Setting a word has its idiosyncrasies as well, as shown here: put put put put
“1” “2” “3” “4”
into into into into
word word word word
1 of aQuote 5 of field “myField” 9 of member “myField” 13 of member “myText” -- DOES NOT WORK!
The only way to set a word with a text member is with dot notation. Even the text of member does not work when setting a word in a text member: aQuote.word[1] = “One” -- DOES NOT WORK! field (“myField”).word[5] = “Two” -- DOES NOT WORK! member(“myField”).word[9] = “Three” member(“myText”).word[13] = “Four”
625
3486-6 ch16.f.qc
626
7/24/00
5:51 PM
Page 626
Part IV ✦ Controlling Media with Lingo
Setting a range of words Setting a range of words is like setting a range of chars: put “Testing” into word 1 to 3 of aQuote put “1,2,3” into word 21 to 23 of field “myField” put “One” into word 1 to 3 of member “myField” member(“myField”).word[9..12] = “Three” member(“myText”).word[13..16] = “Four”
Counting words Counting words works like counting chars, except you don’t have the option of using the length function, as in the following: put the number of words in aQuote -- 16 put the number of words in field “myField” -- 16 put the number of words in the text of member “myText” -- 16
Chars of words You can use smaller chunk expressions, such as char, with larger chunk expressions, such as word, as shown here: put char 1 of word 2 of the text of member(“myText”) -- “f”
The equivalent dot notation is a bit less verbose: put member(“myText”).word[2].char[1] -- “f”
Using the item keyword The item chunk expression retrieves one or more strings of characters that are delimited (separated) by commas in a text string. If you are familiar with database structures, you might have heard of comma-delimited fields. In Director, commadelimited fields are considered items. Note that the separator (in this case, the comma character) is not considered part of the item.
Getting items Getting items is just like getting words, except the delimiter is a comma by default: put item 1 of field “myField” -- “One for the money” put member(“myField”).item[2] -- “ two for the show”
3486-6 ch16.f.qc
7/24/00
5:51 PM
Page 627
Chapter 16 ✦ Text Manipulation with Lingo
As mentioned earlier for the other chunk expressions, you cannot use the dot notation with the field keyword, but you can use the standard notation or use the member keyword with a field. Note that the RETURN character was included when you got item 2. The RETURN came right after the first comma, so it is considered part of the second item. One nice aspect of getting items is that you can change the delimiter. The delimiter is kept in the system property, the itemDelimiter. By setting the delimiter to a RETURN, you can get items in a fashion similar to the line keyword: the itemDelimiter = RETURN put member(“myField”).item[1] -- “One for the money, “ put member(“myField”).item[2] -- “two for the show, “
By setting the delimiter to a SPACE, you can have it act in a fashion similar to the word keyword, as follows: the itemDelimiter = SPACE put member(“myField”).item[1] -- “One” Caution
When setting the itemDelimiter, it is a good practice to save the current value in a variable before changing it. When you are finished with getting items, you restore the itemDelimiter to its previous value (held in the variable), if necessary.
Setting items Setting an item has the same limitations as setting a word: put put put put
“1” “2” “3” “4”
into into into into
item item item item
1 of aQuote 5 of field “myField” 9 of member “myField” 13 of member “myText” -- DOES NOT WORK!
The only way to set a word with a text member is with dot notation. Even the text of member does not work when setting a word in a text member: aQuote.item[1] = “One” -- DOES NOT WORK! field (“myField”).item[5] = “Two” -- DOES NOT WORK! member(“myField”).item[9] = “Three” member(“myText”).item[13] = “Four”
Setting a range of words Setting a range of words is like setting a range of chars: put “Testing” into item 1 to 3 of aQuote put “1,2,3” into item 21 to 23 of field “myField”
627
3486-6 ch16.f.qc
628
7/24/00
5:51 PM
Page 628
Part IV ✦ Controlling Media with Lingo
put “One” into item 1 to 3 of member “myField” member(“myField”).item[9..12] = “Three” member(“myText”).item[13..16] = “Four”
Counting items Counting items works like counting words: put the number of items in aQuote -- 4 put the number of items in field “myField” -- 4 put the number of items in the text of member “myText” -- 4
Chars of words of items Just as you could use char with word, you can use both of those with item, as in the following example: put char 1 of word 1 of item 2 of the text of member(“myText”) -- “t”
The equivalent dot notation is a bit less verbose: put member(“myText”).item[2].word[1].char[1] -- “t”
When doing a range of chars or words, it is possible for the larger chunk expression to be a part of the range of the smaller, such as in this example: put member(“myText”).word[2..6].item[2].char[3] -- “t”
To understand what is happening, break it down into more manageable expressions. Here is the range of words: put member(“myText”).word[2..6] -- “for the money, two for”
Given that result, the second item is obvious (assuming the itemDelimiter is set to a comma): put member(“myText”).word[2..6].item[2] -- “ two for”
The third character is “t”; it is right after the SPACE and RETURN characters.
3486-6 ch16.f.qc
7/24/00
5:51 PM
Page 629
Chapter 16 ✦ Text Manipulation with Lingo
Using the line keyword The line chunk expression retrieves a string of characters that is preceded and followed by a RETURN character in a text string. Note that the separator (such as the RETURN character) is not considered part of the line. Because the line keyword uses a RETURN character to delimit between chunks, it really acts as if it is getting paragraphs. A line might appear on the screen as multiple lines because the line wraps.
Using the paragraph keyword The paragraph chunk expression works like the line chunk expression, but it only works with dot notation. The paragraph keyword was a new addition to version 7. It seems like a better-named version of the line keyword.
Using the ref keyword The ref keyword is a chunk expression that only works with text cast members. It enables you to create a shorthand way of referring to a chunk of text. Instead of writing the following: member(“myText”).line[2].word[2..3]
You can assign a reference to that chunk by doing the following: myRef = member(“myText”).line[2].word[2..3].ref
Note the addition of .ref at the end. myRef now contains a reference to that chunk of text: put myRef --
Now you can get and set properties of just that chunk of text, as shown in the following: put myRef.text -- “for the” put the fontStyle of myRef -- [#plain] put myRef.font -- “Hanzel Condensed-Bold *” myRef.fontStyle = [#italic] myRef.color = paletteIndex(5)
629
3486-6 ch16.f.qc
630
7/24/00
5:51 PM
Page 630
Part IV ✦ Controlling Media with Lingo
Hyperlinks in Text Cast Members Director has the capability to embed hyperlinks in text members. You can import these hyperlinks from an HTML document, or you can create them in Director. On the CD-ROM
The hyperlinks.dir movie is in the EXERCISE:CH16 (EXERCISE\CH16) folder on the CD-ROM.
Open the hyperlinks.dir movie on the CD-ROM. Use this movie for the code samples in this section.
hyperLink This property returns the hyperlink string for a chunk expression. You can get or set this property, but you must use dot notation. To clear a hyperlink, set it to EMPTY, or “”: put member(“myText”).word[2].hyperlink -- “http://www.marsproject.com/”
A hyperlink can contain any string, not just URLs: member(“myText”).word[21].hyperlink = “go to the frame + 1”
hyperlinks This text cast member property returns a list of hyperlink ranges. Each range is a list containing two integers. The first item in the range is the starting character, and the second item is the ending character. You cannot set this property: put the hyperlinks of member “myText” -- [[5, 25], [107, 116]] put member(“myText”).hyperLinks -- [[5, 25], [107, 116]]
hyperlinkRange This property returns the range of the hyperlink in the chunk expression. The first character in the chunk expression must be part of the hyperlink. You cannot set this property: put member(“myText”).word[21].hyperlinkrange -- [107, 116]
3486-6 ch16.f.qc
7/24/00
5:51 PM
Page 631
Chapter 16 ✦ Text Manipulation with Lingo
hyperlinkState This property contains the current state of the hyperlink. You can get or set this value. Possible values are #active, #normal, and #visited: put member(“myText”).word[2].hyperlinkState -- #normal member(“myText”).word[2].hyperlinkState = #visited
Other Chunk Expressions There are several other chunk expressions that are useful in Lingo.
last( ) This function retrieves the last chunk expression of the string. It can be used with char, word, item, and line: put the last item of “Easy come, easy go.” -- “ easy go.” put the last word of “Easy come, easy go.” -- “go.” put the last char of “Easy come, easy go.” -- “.”
contains You’ve seen this function used already if you’ve been reading sequentially. It tells you whether one string contains another. The result is either 1 or 0: put “All good things...” contains “good” -- 1
This is one of those times where the Lingo code reads nicely.
offset( ) This function returns an integer that is the position of the first occurrence of a substring in another string: put offset(“good”, “All good things...”) -- 5
631
3486-6 ch16.f.qc
632
7/24/00
5:51 PM
Page 632
Part IV ✦ Controlling Media with Lingo
“g” is the fifth character in the string “All good things. . .”. If the substring is not in the string, 0 is returned. To use this with a text member, remember to use the text keyword: put offset(“the”, member(“myText”).text) -- 9
Formatting Paragraphs in Text Members Director has many properties for formatting paragraphs. Only text members have these properties (with the exception of the alignment property), but because that is the text format you are most likely to use, it is not much of a limitation. Anyone familiar with page layout programs will find these properties familiar and welcome. With these commands, you can specify a different value for each paragraph. The syntax is as follows: member(“myText”).paragraph[n].propertyName = aValue n is the number of the paragraph you’re accessing. propertyName is the property you are setting. aValue is the value you are giving that property.
If you want to set the entire paragraph in a text member to the same value, use the same syntax, but leave off the paragraph keyword: member(“myText”).propertyName = aValue
fixedLineSpace This is analogous to the field command lineHeight. Technically, it can be used with chunk expressions other than just paragraphs, but it falls logically into this category. In typesetting, this would be called leading. The default is 0, which means it spaces relative to the point size. Any other value sets the spacing to that value regardless of point size. On the CD-ROM
You can find the text6.dir movie in the EXERCISE:CH16 (EXERCISE\CH16) folder on the CD-ROM.
Open the text6.dir movie on the CD-ROM. Change the fixedLineSpace of member myText, as shown in Figure 16-3, by typing the following in the Message window: member(“myText”).paragraph[1..2].fixedLineSpace = 18
The Watcher window is useful for seeing the results when you change values of an object. Enter the expression member(“myText”).paragraph[1..2].fixed LineSpace into the Watcher window.
3486-6 ch16.f.qc
7/24/00
5:51 PM
Page 633
Chapter 16 ✦ Text Manipulation with Lingo
Note
You do not enter the = 18 that appears automatically to show the value of the expression. The Watcher window shows you what an expression evaluates to. In the Message window, you are typing an executable line of Lingo. When you use the equals sign (=) in the Message window, it is acting as the assignment operator, assigning 18 to the fixedLineSpace property of paragraphs 1 through 2 of the member myText. In the Watcher window, it is just acting as an equals sign, showing you what the expression equals (evaluates to).
Figure 16-3: Setting the fixedLineSpace and viewing the results in the Watcher window
bottomSpacing and topSpacing A paragraph might wrap and form many lines. Sometimes you want the space between paragraphs to be different than the space between lines. You can use bottomSpacing or topSpacing, or both, to achieve this. It is probably best to pick the one that makes sense to you and stick with just that one, as opposed to sometimes using topSpacing and sometimes bottomSpacing. We might be inclined to prefer bottomSpacing with Director for an important reason: When you add topSpacing to the first paragraph in the member, it pushes the text away from the top of the member. While this is perfectly logical, programs such as QuarkXPress and Adobe Illustrator ignore the topSpacing when it is the first paragraph in a text box. Oddly enough, Director does not add space to the bottom of the text member, and it does not push the rect of the member farther down when you increase the bottomSpacing on the last paragraph. To get or set the topSpacing or bottomSpacing, you do it the same way you would with other member properties: member(“myText”).paragraph[1].bottomSpacing = 9
If paragraph 1 had a fixedLineSpace of 18, then the space between the baseline of the last line in paragraph 1 and the first line of paragraph 2 is 27 pixels (18 + 9). The result is shown in Figure 16-4. By using bottomSpacing (or topSpacing), you can space paragraphs to your liking, instead of using a hard return or separate text members.
633
3486-6 ch16.f.qc
634
7/24/00
5:51 PM
Page 634
Part IV ✦ Controlling Media with Lingo
Figure 16-4: The result of setting the bottomSpacing of paragraphs 1 to 9
leftIndent and rightIndent You change the left and right indents by setting the leftIndent and rightIndent properties. The leftIndent is how much the entire paragraph is indented on the left side of the text cast member. The rightIndent is how much the text is indented from the right side of the member, as in this example: member(“myText”).paragraph[1].leftIndent = 18
In the preceding example, the text for paragraph 1 would now be indented 18 pixels. Figure 16-5 shows the result; it also illustrates the rightIndent set to 18 in paragraph 2. To set paragraph 2, type the following code: member(“myText”).paragraph[2].rightIndent = 18
Figure 16-5: An example of setting the leftIndent in paragraph 1 and the rightIndent in paragraph 2
3486-6 ch16.f.qc
7/24/00
5:51 PM
Page 635
Chapter 16 ✦ Text Manipulation with Lingo
firstIndent To set the indent for the first line of a paragraph, you set the firstIndent property (Lingo names can be pretty intuitive sometimes, can’t they?), as in this example: member(“myText”).paragraph[2].firstIndent = 18
You can set the firstIndent to a negative value up to but not greater than the positive value of the leftIndent. In other words, if the leftIndent of a paragraph is 0, then a negative value for firstIndent has no effect — not even an error message — it’s just ignored. If the leftIndent is set to 18, then the firstIndent can be up to a –18. This provides for “outdent” or “hanging indent” paragraph formats. A useful application for firstIndent is bullet points. Typically, bullet points should be outdented from the paragraph’s left margin. The preceding indent would be 18 pixels in from whatever the left indent is. Figure 16-6 shows paragraph 2 with the firstIndent set to 18. This is another way to distinguish subsequent paragraphs, instead of increasing the bottomSpacing or topSpacing.
Figure 16-6: Paragraph 2 has its firstIndent set to 18. Paragraph 1’s firstIndent is set to 0.
charSpacing Like the fixedLineSpace property, this property is not exclusive to paragraphs, but it logically fits into this category. This property can be set to positive or negative values, and the default is 0. Figure 16-7 shows an example of charSpacing.
635
3486-6 ch16.f.qc
636
7/24/00
5:51 PM
Page 636
Part IV ✦ Controlling Media with Lingo
Figure 16-7: Paragraph 1 has a charSpacing of –1; paragraph 2 has a charSpacing of 1.
tabCount This property indicates the number of tab stops in a text member. It can be tested, but it cannot be set.
tabs This property is a list of all the tabs in a text member. It is a linear list of property lists. Each property list has the properties #type and #position. The values for #type can be #left, #right, #center, or #decimal. #position is an integer indicating the position of the tab. You can get and set this property.
alignment Of the paragraph commands, this is the only one that also works with fields, but not in the same way. With a text member, you can set the alignment of any paragraph in the member. The value you assign the alignment property must be a symbol: member(“myText”).paragraph[2..3].alignment = #right
Fields do not enable you to set individual formatting of paragraphs, so for fields you must use the preceding syntax, with one important change — the value assigned must be string, as in this example: member(“myField”).alignment = “left”
3486-6 ch16.f.qc
7/24/00
5:51 PM
Page 637
Chapter 16 ✦ Text Manipulation with Lingo
Scrolling Text Fields and text members that have been turned into scrolling text boxes have their own set of Lingo commands, which are described in the following sections.
scrollByLine This command takes two arguments, the member and an integer. It scrolls a member up or down by the number of lines specified by the integer. A positive amount scrolls down; a negative amount scrolls up: scrollByLine member “text_or_field”, 2
scrollByPage This command takes two arguments, the member and an integer. It scrolls a member up or down a page at a time. A page is the number of lines in the member that are visible. A positive amount scrolls down; a negative amount scrolls up. The syntax is: scrollByLine member “text_or_field”, -1
scrollTop The scrollTop is the amount of the cast member scrolled off the top of the member. By setting it to 0, you can make sure the first line of the member is at the top of the member: member(“text_or_field”).scrollTop = 10
Getting Line and Char Locations Lingo provides many terms for determining the location of the mouse in relation to the text on the screen. The first four terms use locations relative to the upper-left corner of the text box, and the remaining terms use locations relative to the Stage.
linePosToLocV This function returns a line of text’s distance from the top of the member; this value is relative to the member, not to the position of a sprite on the Stage: linePosToLocV(member “text_or_field”, 3)
If the preceding code evaluated to 24, and the sprite’s locV was 100, line 3 would be at 124 pixels from the top of the Stage.
637
3486-6 ch16.f.qc
638
7/24/00
5:51 PM
Page 638
Part IV ✦ Controlling Media with Lingo
locVToLinePos This is the complement of linePosToLocV; it returns a number that indicates which line is closest to the locV you pass in as an argument to the function. The locV is relative to the top of the member, not to the position of a sprite on the Stage: locVToLinePos(member “text_or_field”, 24)
If the preceding code evaluates to 3, then line 3 of the member is closest to 24 pixels down from the top of the member.
locToCharPos This function returns an integer, which is the number of the character in a field or text member that is closest to the point passed in: locToCharPos(member “text_or_field”, point(95, 150)
If the preceding code returned 10, then that would mean character 10 in the text of the field or text member was closest to point(95, 150). Caution
The point you pass as an argument in this function is relative to the location of the upper left corner of the sprite.
charPosToLoc This function is the complement of locToCharPos. It returns the position of the character relative to the upper-left corner of the member: charPosToLoc(member “text_or_field”, 10)
If the preceding code returns points (95, 150), you would need to add the left and top values of the rect of the sprite the text is in to get the location of the character on the Stage.
The pointTo functions The remaining terms are pointToChar, pointToWord, pointToItem, pointToLine, pointToParagraph, and pointToHyperLink. As you might have guessed from their names, all of the functions correspond to the chunk expressions: char, word, item, line, and paragraph. These functions are similar to locToCharPos, except the point you pass these functions is not relative to the upper-left corner of the member but to a screen coordinate. The return value is the number of the chunk expression the point is over: pointToChar(member “text”, the mouseLoc)
3486-6 ch16.f.qc
7/24/00
5:51 PM
Page 639
Chapter 16 ✦ Text Manipulation with Lingo
In the preceding code, if the mouse is over the member, it returns an integer indicating which character. If it is not over any character, it returns –1. Because you use Stage coordinates, these functions are easier to work with, but they work only with text members.
More Text Cast Member Properties The number of text member properties might seem overwhelming, but there are still several more properties that are important and worth discussing.
HTML and text members Not only can Director import HTML files (with some limitations), but every text member has an HTML property that you can get and set. On the CD-ROM
You can find the text7.dir movie in the EXERCISE:CH16 (EXERCISE\CH16) folder on the CD-ROM.
Open the text7.dir movie on the CD-ROM. In the Message window, type put member(“myText”).HTML, as shown in Figure 16-8, or put the HTML of member(“myText”).
Figure 16-8: Every text member has an HTML property that can be retrieved or changed.
Note how the font, the size, and the color are specified in the font tag. Within the text, the bold words Mars Multi-Use Rocket correctly have the tags.
639
3486-6 ch16.f.qc
640
7/24/00
5:52 PM
Page 640
Part IV ✦ Controlling Media with Lingo
RTF Besides having an HTML property, each text member has an RTF property as well. If you are familiar with the Rich Text Format (RTF), you can get and set this value as well. Figure 16-9 shows the result of getting the RTF of a member.
Figure 16-9: Every text member has an RTF property that can be retrieved or changed.
antiAlias and antiAliasThreshold Text members antialias text by default. By default, the threshold at which the antialiasing occurs is at 14-point and larger type. To turn off antialiasing for a particular member, just set the antiAlias property to FALSE. To turn antialiasing back on, set the antiAlias property to TRUE. Rendering speed of the sprites is slower with antialiasing turned on. Following are examples of dot and standard notation for turning the antialiasing off and then on again for member myText: member(“myText”).antiAlias = FALSE set the antiAlias of member “myText” to TRUE
If anti-aliasing is desired at a different size, change the antiAliasThreshold. Setting it to 0 makes all text sizes antialiased. Antialiasing small text can sometimes make readability worse; it varies from font to font. Following are examples of dot and standard notation for setting the antiAliasThreshold property: member(“myText”).antiAliasThreshold = 18 set the antiAliasThreshold of member “myText” to 18
3486-6 ch16.f.qc
7/24/00
5:52 PM
Page 641
Chapter 16 ✦ Text Manipulation with Lingo
kerning and kerningThreshold To have the text in a member automatically kerned, set the kerning property to TRUE. Setting it to FALSE turns kerning off. Following are examples of dot and standard notation for turning the kerning off and then on again for member myText: member(“myText”).kerning = FALSE set the kerning of member “myText” to TRUE
The kerningThreshold property determines the point size at which type is kerned in a member. The default is 14. Following are examples of dot and standard notation for setting the kerningThreshold property: member(“myText”).kerningThreshold = 21 set the kerningThreshold of member “myText” to 21
Selecting text Selecting text is done two different ways: one way for fields and one way for text members.
the selection This keyword might be a little confusing because of how different it is between fields and text members. the selection without a text member reference returns a string of the text selected in a field (see Figure 16-10).
Figure 16-10: “the selection” works with fields and returns a string.
641
3486-6 ch16.f.qc
642
7/24/00
5:52 PM
Page 642
Part IV ✦ Controlling Media with Lingo
The sprite at the top references a field; the bottom one references a text member. Two expressions have been entered into the Watcher window: the selection and the selection of member “myText”. the selection evaluates to a string of the text selected in the field myField. Even if there were multiple fields on the screen, text can only be selected in one field at a time. the selection of member “myText” evaluates to a list with two integers. If you use the selection with a text member, it returns a list of two integers, as shown in Figure 16-11. The first is the first char selected, and the second is the last char selected. If the first is greater than the last (as in Figure 16-10), then no char is selected, but it does give you an idea of the position of the insertion point. This value can be retrieved even when the member does not have the focus of the keyboard. When used with text members, you can set the selection.
Figure 16-11: “the selection of member” works with text members and returns a list.
selStart and selEnd The selStart keyword returns an integer that refers to the index of the first character selected in a field. Like the selection, it is not used with a member. The selEnd refers to the last character selected. Both work only with fields. If the selStart = the selEnd, then nothing is selected, but it does give you an idea of where the insertion point is (see Figure 16-12).
3486-6 ch16.f.qc
7/24/00
5:52 PM
Page 643
Chapter 16 ✦ Text Manipulation with Lingo
Figure 16-12: The selStart and the selEnd work with fields On the CD-ROM
You can find the text5.dir movie in the EXERCISE:CH16 (EXERCISE\CH16) folder on the CD-ROM.
To see a movie that has an example of the selStart, the selEnd, and the selection of member, open the text5.dir movie on the CD-ROM. In it, you see two scripts that are very similar, as shown in Figure 16-13.
Figure 16-13: These scripts for setting the selection in a text member and the selection in a field are very similar.
643
3486-6 ch16.f.qc
644
7/24/00
5:52 PM
Page 644
Part IV ✦ Controlling Media with Lingo
Both scripts get values from fields used for input and convert them to integers. Then they test to make sure the values are not void. I know it seems strange that a function used to convert something to an integer would return a value that is not an integer (such as void), but this is a way for you to test whether the input was valid and then act on it. All that is done here is to set it to zero in the case of void. Then the keyboardFocusSprite is set to the appropriate sprite. After that is where the differences occur. For a field, you need to set the selStart and the selEnd. For a text member, you need to specify which text member and then set its selection property to a two-item list. The other important difference is what happens when you set these values. If you set the text member to select chars 1 to 7, the first seven characters are selected. If you set the field to select chars 1 to 7, you get chars 2 through seven selected. This happens because the selStart starts counting with 0. Zero is the point of the selection to the left of the first character and 1 is the point right after it. So, in truth, it is counting based on the area between characters instead of the characters themselves (as in the case with the selection of member).
hilite The hilite command works with fields, but it does not work with text members. It enables you to highlight a chunk of text in a specific member, even if it is not an editable field. The syntax can be used with any of the other chunk expression, such as char, word, item, or line. To highlight word 2 of the field myField, just type the following in the Message window: hilite word 2 of member “myField”
selectedText The selectedText works only with text members. It does not return text; it returns a ref of the text selected in the text member. This is a handy way to get information on the selection of the user and to give feedback based on the selection.
Field-Only Properties Certain properties apply only to fields such as hilite, the selStart, and the selEnd, which have already been discussed. Perhaps one of the following properties will persuade you to forgo using text cast members. On the CD-ROM
You can find the fieldbox.dir movie in the EXERCISE:CH16 (EXERCISE\CH16) folder on the CD-ROM.
3486-6 ch16.f.qc
7/24/00
5:52 PM
Page 645
Chapter 16 ✦ Text Manipulation with Lingo
Setting box properties You will find fieldbox.dir (see Figure 16-14) on the CD-ROM. Open and play this movie. Click the sliders and slide them back and forth. Each slider corresponds to the check box next to it. Each check box is labeled according to the field property it affects. This is an easy way to see the effects of setting the various properties dynamically. If you deselect any of the boxes, it temporarily sets that value to zero on the MARS field until you select the box again. Even if the box is cleared, you can still move the slider; its effect won’t be shown until the check box is highlighted again. The field to the right of the sliders shows the amount to which the property is set. If you were to set these values by choosing Modify ➪ Borders, you would only be able to set the value to a maximum of 5; Lingo enables you to go much higher.
Figure 16-14: The fieldbox.dir movie enables you to play with different settings dynamically.
border You can create a black border around a field with this command. There is no way of changing the color of the border, so its uses are limited. You can, however, change the width of the border. Figure 16-14 shows a field with a border set to 1. An example of setting it through Lingo is the following: -- dot notation member(“mars”).border = 1 -- or standard set the border of member “mars” to 1
margin This property is the amount of space between the text and the rect of the field. To achieve a similar effect with text members, you would need to modify the topSpacing, leftIndent, and rightIndent properties. Figure 16-14 shows a field with a margin set to 9. An example of setting it through Lingo is as follows: -- dot notation member(“mars”).margin = 9 -- or standard set the margin of member “mars” to 9
645
3486-6 ch16.f.qc
646
7/24/00
5:52 PM
Page 646
Part IV ✦ Controlling Media with Lingo
dropShadow There is no similar property among text members. This property sets the drop shadow for the text of a field. The default is 0 (no drop shadow). Figure 16-14 shows a field with a dropShadow set to 2. An example of setting it through Lingo is as follows: -- dot notation member(“mars”).dropShadow = 2 -- or standard set the dropShadow of member “mars” to 2
boxDropShadow There is no similar property among text members. This property sets the drop shadow for a field. The default is 0 (no drop shadow). Figure 16-14 shows a field with a boxDropShadow set to 4. An example of setting it through Lingo is the following: -- dot notation member(“mars”).boxDropShadow = 4 -- or standard set the boxDropShadow of member “mars” to 4
Using the wordWrap property Turning this property off prevents lines from wrapping; only a hard return creates a new line in the field. Text members have nothing similar. An example of setting it through Lingo is this: -- dot notation member(“myField”).wordWrap = TRUE -- or standard set the wordWrap of member “myField” to TRUE
Using the lineCount property This function is an alternative to using the number of lines in the field “myField”. It returns the number of lines in a field. An example of setting it through Lingo is the following: -- dot notation put member(“myField”).lineCount -- or standard put the lineCount of member “myField”
3486-6 ch16.f.qc
7/24/00
5:52 PM
Page 647
Chapter 16 ✦ Text Manipulation with Lingo
Using the lineHeight property This is the line spacing for the field (the leading). This property is analogous to the fixedLineSpace for text members, except that you can only set the value for the entire field, not for individual paragraphs. An example of setting it through Lingo is this: -- dot notation put member(“myField”).lineHeight -- or standard put the lineHeight of member “myField”
Using the pageHeight property This property returns the height of the member that is visible on the Stage, as shown here: put the pageHeight of member “myField”
Summary Before moving on, recall what you learned in this chapter: ✦ Text properties, such as font, size, color, and style, can be controlled through Lingo. ✦ Each of these properties can be set for a chunk of text that includes one or more characters, words, lines, paragraphs, or items. ✦ There are many subtle differences between fields and text members. Text members give you more options. ✦ By using Lingo, you can reset a scrolling text field to the top of the text box, scroll through line by line, and make field text editable. ✦ You can create and modify hyperlinks through Lingo. ✦ Fields have a few properties that might make them desirable in certain instances. One of the great things about using text members is their capability to be scaled up or down, because they are resolution independent (unlike bitmaps). In the next chapter, we discuss how to manipulate Director’s resolution-independent graphics: vector shape and Flash members (and their associated sprites).
✦
✦
✦
647
3486-6 ch16.f.qc
7/24/00
5:52 PM
Page 648
3486-6 ch17.f.qc
7/24/00
5:52 PM
Page 649
17 C H A P T E R
Vector Shape and Flash Lingo
✦
✦
✦
✦
In This Chapter
D
irector can now take advantage of vector-based art. Bitmaps are described by pixels, but vectors are described mathematically. This enables vectors to scale up without becoming pixelated. In other words, vector-based art shows more detail as it gets larger, whereas pixels have a finite resolution. Programs such as Photoshop and Painter work with pixels; programs such as Freehand, Illustrator, Flash, and In-Motion mostly use vectors.
Creating vector shapes with Lingo Modifying vector shapes with Lingo Using Flash movies in Director
✦
Creating a Vector Shape with Lingo Creating a new vector shape is easy. You do it the same way you create a new member of other types, as follows: myVector = new(#vectorShape)
This creates a new member of the type #vectorShape, but it is empty. It is similar to creating a new text member on the fly — there is no text until you put it there. With a vector shape, you need to put in the vertices and handles. We’ll show you how to use Lingo to add vertices later on in the chapter. First, we’ll examine the vertexList of a shape created through the user interface. The vertexList is a list of lists, defining the points and handles of a vector shape member. A good way to understand the vertexList is to create a couple of simple vector shapes and to examine their vertexList properties.
✦
✦
✦
3486-6 ch17.f.qc
650
7/24/00
5:52 PM
Page 650
Part IV ✦ Controlling Media with Lingo Part # ✦ Part Title
Examining the vertexList 1. Choose Insert ➪ Media Element ➪ Vector Shape. A blank vector shape window opens. 2. Select the Rectangle tool and draw a square by holding down the Shift key as you draw. Draw the square from the upper-left down to the lower right. 3. Open the Message window by choosing Window ➪ Message. 4. Type the following in the Message window: put the vertexList of member 1
Figure 17-1 shows the result. Your vertexList might have different values, depending on the size of the square.
Figure 17-1: Examining the vertexList of a square vector shape
The vertexList is a linear list that holds a property list for each vertex. The first element in the list is the vertex in the upper-left corner. The next item in the list is the vertex at the upper right. The vertex at the lower right is the third item in the list, and the last item in the list is the vertex at the lower left. Pretty straightforward stuff. Now insert another vector shape, but this time draw a circle. In the Message window, put the vertexList for this member, and you should see something like Figure 17-2. Tip
To make all the handles visible at once in the Vector Shape Window, choose Select All from the Edit menu.
3486-6 ch17.f.qc
7/24/00
5:52 PM
Page 651
Chapter 17 ✦ Vector Shape and Flash Lingo
Figure 17-2: There’s more to a vertexList than just vertices — curves have handles.
At first glance, this list might look a little intimidating. Upon closer examination, you see it is very similar to the vertexList for the square. It has four vertices, each one in its own property list within the linear vertexList. The big difference is now there are two additional elements in each of those lists: #handle1 and #handle2. If you’ve worked with drawing programs, you’ve seen control handles on curves. #handle1 and #handle2 hold the location of the handle’s control point relative to the vertex, but they are not absolute coordinates, as the vertices are. As you examine the vertexList from this member, note that all the handles are similar coordinates. This is because they are all similarly offset from their respective vertices. This would be much less obvious on a more arbitrary shape, as in Figure 17-3.
Figure 17-3: Vector shapes do not have to be closed shapes, nor do their handles need to be continuous.
651
3486-6 ch17.f.qc
652
7/24/00
5:52 PM
Page 652
Part IV ✦ Controlling Media with Lingo
The shape in Figure 17-3 illustrates two more aspects of vector shapes — they do not need to be closed shapes, and handles do not need to be continuous (meaning it does not have to be a straight line from one handle to another). Save this movie as vector shapes.dir. Tip
The important thing to remember is that each property list in the vertexList has, at the most, three elements: #vertex, #handle1, and #handle2. A vertexList can contain any number of vertices. Each vertex can have 0, 1, or 2 handles.
Setting the vertexList A powerful feature of Director 8 is the capability to set the vertexList of any vector shape. In the Message window, type the following: myVector = new(#vectorShape) myVector.vertexList = member(2).vertexList myVector holds a reference to the member created with the new function. Because it was just created, the vectorList is empty. Next, the vectorList of member 2 (the circle) is assigned to it. If you’ve been following along, this new member should be in position 4 in the internal cast. It should look something like Figure 17-4. Figure 17-4: A new member is created and then the vertexList of one member is assigned to the other (what’s wrong with this picture?).
The new circle is broken. Why? Because the vertexList property does not contain information about whether a vector shape is to be drawn closed or open. Every vector shape member has a closed property. To make this complete, you need to type the following: myVector.closed = member(2).closed
3486-6 ch17.f.qc
7/24/00
5:52 PM
Page 653
Chapter 17 ✦ Vector Shape and Flash Lingo
The closed property is either 0 or 1. We don’t need to know what it is in this case; we just need to set it to the same value as member 2’s closed property. As you learned in Chapter 12, when you set a variable to another variable that contains a list, both variables reference the same list unless you use the duplicate function to make a copy of the list. When you get the vertexList of a member, you are automatically getting a copy of that list, not a reference to it. After you put the vertexList into a variable and change it, it will not affect the vector shape from which you got it. You must reassign the changed list to the vertexList of the member for it to take effect. Type the following in the Message window: set myVtList to the vertexList of myVector set anotherVtList to the vertexList of member 3 myVtList now has a copy of the vertexList of member 4 (the member that myVector references). anotherVtList has a copy of the vertexList of member 3. Because we are manipulating a copy of the vertexList, not the actual vertices, we
won’t see the effects yet. Now add the points from one list to the other: add add add add
myVtList, myVtList, myVtList, myVtList,
anotherVtList[1] anotherVtList[2] anotherVtList[3] anotherVtList[4]
myVtList now contains eight vertices. Now assign this list to the vertexList of myVector, as follows: set the vertexList of myVector to myVtList
You should see something similar to the shape in Figure 17-5. Figure 17-5: The circle in member 2 is joined with the curve in member 3.
653
3486-6 ch17.f.qc
654
7/24/00
5:52 PM
Page 654
Part IV ✦ Controlling Media with Lingo
Changing vertices So far, the methods for changing vertices have been indirect: Put the vertexList of a member into a variable, change the variable, and reassign it to the vertexList of the member. There are also methods for changing vertices directly. You can add vertices directly by using the addVertex command. Just pass in a vector shape member, an index, and a point. The index is where in the list you want to add the point. The point is the location of the new vertex you’re adding, as in this example: addVertex(member 1, 3, point(10, 10)) --or member(1).addVertex(3, point(10, 10)
If you add vertices, you might also want to delete them You can use the deleteVertex command to delete a particular vertex. This command is even simpler. It takes a vector shape member and the index of the vertex you want to delete, as shown here: deleteVertex(member 1, 3) --or member(1).deleteVertex(3)
Resizing vector shape data In Chapter 15, you learned how to resize sprites. Resizing a vector shape sprite works great on the Stage, because vector shapes are resolution independent. But what if you want to resize the actual vector shape data in the member? You can do it through the user interface by Command+Option+clicking (Ctrl+Alt+clicking) and dragging on the shape in the vector shape window. To do it at run-time, you need to do it using Lingo. This can be achieved quite easily by multiplying the vertexList of the member by your scaling factor and then setting the vertexList to the resulting value. The following line of code scales the vector shape by half: member(1).vertexList = member(1).vertexList * 0.5 There are a few caveats with this method. If you are scaling down and up frequently, your shape may change slightly from rounding errors. You can avoid this situation by keeping the original vertexList in a variable and using that for your calculations. Another problem is using vectors with multiple curves. This method will not work because your vertexList will contain a linear list that contains a symbol to delineate the different curves, [#newCurve]. The vertexList needs this information to know when a new curve begins. If you multiply a symbol by an integer, the result is an integer. Multiplying a multicurve vertexList by an integer corrupts the list.
3486-6 ch17.f.qc
7/24/00
5:52 PM
Page 655
Chapter 17 ✦ Vector Shape and Flash Lingo
To change the location of a vertex, you can use the moveVertex command. It takes a vector shape member, an index, and two integers. The index is the vertex you want to move. The integers are the horizontal and vertical amount you are moving the vertex, as in the following: moveVertex(member 1, 3, 25, -2) -- or member(1).moveVertex(3, 25, -2)
You can manipulate handles directly in a similar fashion. With the moveVertex Handle you need to specify the vector shape member, the index of the vertex, the index of the handle, and the horizontal and vertical amounts you are moving the handle, as follows: moveVertexHandle(member 1, 3, 2, 10, 5) --or member(1).moveVertexHandle(3, 2, 10, 5)
Setting the fill To fill a vector shape, you need to specify the color and the manner in which the shape is filled. The color should be of the type rgb. The fillMode of a vector shape can be set to #solid, #gradient, or #none. The shapes you’ve been drawing so far have been transparent. If you check their fillMode property, you see that they are set to #none. This code makes the first member a red square: member(1).fillMode = #solid member(1).fillColor = rgb(255, 0, 0)
Creating a gradient By setting the fillMode to #gradient, you can have a gradation in your vector shape: member(1).fillMode = #gradient
To set a gradient, you need to specify a fillColor and an endColor. You already have set the fillColor to red, so now set the endColor to white, as follows: member(1).endColor = rgb(255, 255, 255)
Your shape should now look like Figure 17-6.
655
3486-6 ch17.f.qc
656
7/24/00
5:52 PM
Page 656
Part IV ✦ Controlling Media with Lingo
Figure 17-6: Changing the fill of a vector shape
There are several more Lingo commands that compare with the settings you can apply in the user interface shown in Figure 17-7: ✦ In the pop-up menu, you can specify the gradient: Linear or Radial. In Lingo, you would specify the gradientType property, and set it to #linear or #radial. ✦ The Cycles field corresponds to the fillCycles property — you can specify an integer from 1 to 7. ✦ The Spread field corresponds to the fillScale property. ✦ The Angle field corresponds to the fillDirection property — set it to the degree of the angle. ✦ The X Offset and Y Offset fields correspond to the fillOffset property. The fillOffset property takes a point so you can set both values in one step.
Figure 17-7: The different attributes that you can apply to a vector shape with a gradient.
Setting a stroke As you might have noticed, there is still a stroke around the square vector shape in member 1. You can set the stroke by setting the strokeWidth property. A value of 0 is no stroke. You can set the thickness all the way to 100 through Lingo (as opposed to 12 in Director’s user interface). You can change the color by setting the strokeColor property.
3486-6 ch17.f.qc
7/24/00
5:52 PM
Page 657
Chapter 17 ✦ Vector Shape and Flash Lingo
Mulitple curves As you learned in Chapter 2, you can create vector shapes with multiple curves (Director 7 was limited to one path per member). This information is stored within the vertexList of the member. For Director to know a new path is beginning, an additional element is added to the vertexList, [#newCurve]. All subsequent vertices will belong to a new path. The following list contains two paths, forming a square within a square: [[#vertex: point(-50, -50)], [#vertex: point(50, -50)], [#vertex: point(50, 50)], [#vertex: point(-50, 50)], [#newCurve], [#vertex: point(-30, -30)], [#vertex: point(30, -30)], [#vertex: point(30, 30)], [#vertex: point(-30, 30)]]
Try creating this vector shape from the Message window by following these steps: 1. Create the new member and place it in the variable v for easy access: v = new(#vectorShape)
2. Set the vertexList of the member: v.vertexList = [[#vertex: point(-50, -50)], [#vertex: point(50, -50)], [#vertex: point(50, 50)], [#vertex: point (-50, 50)], [#newCurve], [#vertex: point(-30, -30)], [#vertex: point(30, -30)], [#vertex: point(30, 30)], [#vertex: point(-30, 30)]]
3. Remember to close the shape: v.closed = 1
4. Then make it a filled shape: v.fillMode = #solid
5. Last, fill it with red: v.fillColor = rgb(“#FF0000”)
One of the nice things about Director is that you can have the Vector Shape window open while you do the preceding steps in the Message window. You can watch the effects of each line of code. If you have the Property Inspector open as well, select the new member after step #1 and watch the values change for the vector shape member (make sure you have the Vector tab selected and are viewing the Property Inspector in List View mode).
657
3486-6 ch17.f.qc
658
7/24/00
5:52 PM
Page 658
Part IV ✦ Controlling Media with Lingo
Vector and Flash Properties There are many similarities between vector shapes and Flash members. Flash movies are made using vectors, just as the vector shapes. In fact, you use the Flash Xtra to draw the vector shapes. So, it is not surprising that quite a few Lingo commands work for sprites and members of each kind.
Antialias When this property is set to 1 or TRUE, the member is antialiased. Setting it to 0 or FALSE makes the member aliased. The default is 1. Figure 17-8 shows the difference on two circle members.
Figure 17-8: Antialiasing can make a big difference on static images.
Why would you ever want to turn it off? Images that do not have to be antialiased are rendered more quickly. You might have an option in your program that enables users to decide whether they prefer speed or quality. Static images benefit a great deal more from antialiasing than images that are moving quickly on the screen. The eye does not notice the flaws as much on a moving image as on one standing still just asking to be scrutinized.
defaultRect and defaultRectMode The defaultRect of a member is the size it appears when it is on the Stage. When changed, all sprites referencing that member will change, unless they have been stretched. The defaultRectMode is either #flash (default) or #fixed. After you change the defaultRect, the defaultRectMode changes to #fixed. To restore the member to its original size, set the defaultRectMode to #flash.
3486-6 ch17.f.qc
7/24/00
5:52 PM
Page 659
Chapter 17 ✦ Vector Shape and Flash Lingo
scale and scaleMode Flash and vector shapes scale within their rects. The rect itself does not change size, just the image of the art. When a member is scaled 50 percent, then twice as much of it shows (see Figure 17-9). This property can be set for members or sprites.
Figure 17-9: Scaling a Flash or vector shape member scales it within its bounding rectangle. On the CD-ROM
The scalemode.dir movie is in the EXERCISE:CH17 (EXERCISE\CH17) folder on the CD-ROM that accompanies this book.
The scaleMode is how the member or sprite scales. Autosize is the default. The scaleMode property is easier demonstrated than explained. For those of you not working through this at a computer, we’ll do our best. The movie scalemode.dir, shown in Figure 17-10, has a Flash sprite and a vector shape sprite.
Figure 17-10: A movie to illustrate dynamically the differences that the scaleMode property can make. The copy ink on the images is intentional to show the bounding box as they rotate.
659
3486-6 ch17.f.qc
660
7/24/00
5:52 PM
Page 660
Part IV ✦ Controlling Media with Lingo
Each of the sprites in scalemode.dir rotates as the movie plays. When set to #autoSize — the default for Director — they react as you might expect. Because the Flash asset Xtra was first introduced with Director 6.5, movies that used it have the Flash members defaulting to #showAll. ✦ #autoSize: Rotates the image as you might expect, maintaining the same scale for the artwork. ✦ #showAll: Maintains the aspect ratio of the original cast member. Thus, as a rectangular shape rotates, it appears to shrink and grow. ✦ #noBorder: Maintains the aspect ratio also, but it crops the member so that the member appears to grow within its sprite’s rect. ✦ #exactFit: Squeezes the shape into the rect, causing it to distort. ✦ #noScale: Looks the same as #autoSize, unless the sprite has been stretched. If the sprite is made smaller than the original member, then the artwork is cropped within that sprite’s rect. Figure 17-11 illustrates the different results based on the setting of the scaleMode property.
Figure 17-11: The scalemode.dir movie in action
3486-6 ch17.f.qc
7/24/00
5:52 PM
Page 661
Chapter 17 ✦ Vector Shape and Flash Lingo
Understanding view properties The viewScale is similar to the scale property. Where setting the scale to 50 percent shows twice as much of the image within the rectangle (making it look smaller), setting the viewScale to 50 percent shows you half as much of the image within the rectangle, making it look larger. It is like looking through a camera. If you are looking at something and then cut the distance between you and it by 50 percent, it will be much larger in the picture. Figure 17-12 shows the results. Compare the difference in results shown by this illustration with that of Figure 17-9. This property can be set for members or sprites.
Figure 17-12: Changing the viewScale property
Keeping with the camera analogy, you could also move sideways, up or down, or some combination of those directions when viewing something. To do this with a Flash or vector shape, you set the viewPoint, viewH, or viewV. Moving 10 pixels is like stepping to the right, so the image moves to the left (see Figure 17-13). To move both directions at once, set the viewPoint.
Figure 17-13: Changing the viewPoint property
661
3486-6 ch17.f.qc
662
7/24/00
5:52 PM
Page 662
Part IV ✦ Controlling Media with Lingo
Understanding origin properties The originPoint property determines the point around which the Flash or vector shape scales or rotates. Like the viewPoint, viewH, and viewV, you have the originPoint, originH, and originV. When you change the origin, you also change the originMode. You can set the originMode as follows: ✦ #center is the default. ✦ #topleft causes the member to scale from the top-left corner. ✦ #point is a point you set with the originPoint, originH, or originV. Note
The images in Figure 17-14 have their scaleMode set to #noScale.
If you change the originPoint, you can restore the default by setting the originMode to #center.
Figure 17-14: Changing the originMode property
Flash Only The capabilities of Flash movies far exceed those of vector shapes, and there are many commands that apply only to Flash movies. Flash movies can be static or animated, they can have buttons, and they can stream.
Embedding or linking? Director enables you to have Flash movies embedded in, rather than linked to the cast. There are advantages and disadvantages to both. It is convenient to have the media embedded, because you have fewer files to manage. Linking it enables you to update the Flash movie without having to modify the Director movie. Linking also enables you to take advantage of the commands regarding streaming. You can test
3486-6 ch17.f.qc
7/24/00
5:52 PM
Page 663
Chapter 17 ✦ Vector Shape and Flash Lingo
the linked property of a Flash member to determine whether it is linked or embedded. A nice aspect of the linked property is that you can both get it and set it. This enables you to create a new Flash member on the fly and a path to a Flash movie, such as a URL.
Controlling playback A Flash movie can be a single frame of artwork or it can be many frames of animation. Director gives you control over the playback of these members. These commands operate on the Flash sprite, as opposed to the member: ✦ play: Starts a Flash movie sprite playing from the current frame. ✦ the playing of sprite: This property indicates whether the movie is playing. It is either 1 or 0 — 1 if it is playing; 0 if it is stopped. You can get this property, but you cannot set it. ✦ the playBackMode: You have three choices for this property: #normal, #lockStep, and #fixed. #normal plays the movie at the original tempo. #lockStep plays a frame of the Flash movie every time a Director frame plays. #fixed plays the movie at the rate to which the fixedRate property is set. ✦ rewind: This command rewinds the sprite back to frame 1. ✦ hold: This command stops the Flash movie from playing, but it doesn’t stop the movie’s audio. ✦ stop: This command stops the Flash movie from playing, and the movie remains on the current frame. On the CD-ROM
The box1.dir movie is in the EXERCISE:CH17 (EXERCISE\CH17) folder on the CD-ROM.
Open the box1.dir movie on the CD-ROM and play it (see Figure 17-15). You see the little green man slowly pop out of the box, even though the tempo is set to 60fps (see Figure 17-16). This is because the playBackMode of the sprite is set at its default value: #normal.
Figure 17-15: The beginning of box1.dir
663
3486-6 ch17.f.qc
664
7/24/00
5:52 PM
Page 664
Part IV ✦ Controlling Media with Lingo
Figure 17-16: The end of box1.dir
To make it move at the same rate as the movie, you need to set the playBackMode to #lockStep. A good way to do this is with a behavior attached to the sprite. This way, you can move the sprite to different places in the Score, if necessary, without having to worry about changing the code. Create and apply the behavior shown in Figure 17-17.
Figure 17-17: Setting the playBackMode
Now you can change the tempo of the movie, and the tempo of the Flash sprite changes accordingly. Setting the fixedRate of a sprite does not automatically change the playBackMode to #fixed. If you want the frame rate of the Flash movie to move at a rate different from the Director tempo, you need to set the fixedRate to the frame rate at which you would like it to play, and then you need to set the playBackMode to #fixed, as shown in Figure 17-18.
Figure 17-18: Setting the playBackMode
There are no commands to make a Flash movie play backwards, so how would you do it? Given the frameCount of member and the frame of sprite commands, you can write a short behavior that does just that (see Figure 17-19).
3486-6 ch17.f.qc
7/24/00
5:52 PM
Page 665
Chapter 17 ✦ Vector Shape and Flash Lingo
Figure 17-19: A behavior to play a Flash sprite backwards
The first part of the behavior in Figure 17-19 is for convenience. We create properties to hold a reference to the sprite and a reference to the member of the sprite. This enables you to use simpler syntax in the exitFrame handler. The last statement in the beginSprite handler pSprite.gotoFrame(pMemb.frameCount) might be a little confusing. The first part that executes in that statement is the part in parentheses, pMemb.frameCount. This returns the number of frames in the Flash member, because frameCount is a member property, not a sprite property. The next part that executes is the gotoFrame command, which is a Flash sprite command. The gotoFrame command takes an integer or string as an argument (a string would be the label to go to) — in this case, an integer is returned from pMemb.frameCount. In the first statement of the exitFrame handler, the variable myFrame is created and given the value of the frame the Flash sprite currently is playing, using the frame of sprite property (the dot syntax form of it). If it is on the first frame, the sprite is told to go to the last frame; otherwise, it is told to go to the one just before the current one.
Streaming Flash As mentioned earlier, Flash movies can stream. Whereas the playback commands apply to sprites, the streaming commands apply to members: ✦ the bufferSize of member: This property controls how many bytes can be streamed into memory at one time. The default it 32,768 bytes. ✦ the bytesStreamed of member: This is the number of bytes that have loaded. ✦ clearError: Resets the error state of a Flash member being streamed. Use this in conjunction with the state of member property.
665
3486-6 ch17.f.qc
666
7/24/00
5:52 PM
Page 666
Part IV ✦ Controlling Media with Lingo
✦ state of member: This property is the current state of the member that is streaming. 0 means it is not in memory. 1 means the header is loading. 2 means the header has finished loading. 3 means the member’s media is loading. 4 means the member has finished loading. –1 is returned if there is an error. ✦ stream: This command/function enables you to stream a number of bytes of a Flash movie. It returns the number of bytes actually streamed, which might be fewer than the amount specified. ✦ the streamMode of member: This member property controls how a Flash movie is streamed. There are three options: #frame, #idle, and #manual. #frame is the default, it streams part of the member each time the playback head moves. #idle streams whenever there is an idle event, at least once per frame even if no idle event is generated. #manual streams a member only when the stream command is used. ✦ the streamSize of member: This property is the number of bytes in the stream for the member.
Controlling interaction Flash movies have limited interactivity. You can have buttons that perform some predefined commands. Interaction of Director and the Flash movie is controlled on the sprite and member level. ✦ the actionsEnabled of sprite or member: This setting enables you to turn on or off the action in a Flash sprite or member. ON is the default. Possible values are 1 for ON and 0 for OFF. ✦ the buttonsEnabled of sprite or member: This setting enables you to control whether buttons in a Flash movie are active or inactive. ON is the default. Possible values are 1 for ON and 0 for OFF. ✦ the clickMode of member: This property is how a Flash member or sprite detects mouseUp, mouseDown, mouseEnter, mouseWithin, and mouseLeave events. It has three possible values: #boundingBox, #opaque, and #object. #bounding box is the rect of the sprite. #opaque is the default: It affects only opaque areas of the sprite if the ink is set to background transparent; otherwise, it acts like #boundingBox. #object works like opaque, but the ink for the sprite does not have to be background transparent. ✦ the eventPassMode of sprite: A Flash sprite can deal with mouse events one of four different ways: #passAlways, #passButton, #passNotButton, and passNever. #passAlways is the default; it always passes mouse events. #passButton passes mouse events when a button in a Flash movie is clicked. #passNotButton passes mouse events only when something other than a button is clicked. #passNever never passes mouse events.
3486-6 ch17.f.qc
7/24/00
5:52 PM
Page 667
Chapter 17 ✦ Vector Shape and Flash Lingo
✦ hitTest: Enables you to determine which part of a Flash movie is over a specific location. There are three possible return values: #background, #normal, and #button. #background means the location is over the background area of a Flash sprite. #normal means the location is over a filled object. #button means it is over a Flash button. ✦ the mouseOverButton of sprite: This property indicates whether the mouse is over a button in a Flash sprite. Sometimes, the easiest way to understand something complex is to make a simple example that just illustrates what you are trying to figure out. Figure 17-20 shows a simple Flash movie. The rectangular shape is a button — the circle is just another Flash object. The white area is the bounds of the Flash member, and the gray around it is the color of the Stage. Figure 17-20: A simple Flash movie to demonstrate Lingo/Flash interaction
The button has an action applied to it in the Flash 3 application. Flash 3 is not included with Director 7, but this feature is important to mention, because the capability to interact with Director is not documented in the Flash manual. By selecting the button, choosing Modify ➪ Instance, clicking the Actions tab, and then choosing Get URL from the + pop-up menu, you are presented with the dialog box shown in Figure 17-21.
Figure 17-21: A Flash dialog box showing where you can enter Lingo to be executed in Director from a Flash button.
667
3486-6 ch17.f.qc
668
7/24/00
5:52 PM
Page 668
Part IV ✦ Controlling Media with Lingo
The URL text field is initially empty; in it, you can add the Lingo that you want to execute. You have three different options for what you put in the field. You can just put a string in there and then use an on getURL handler in Director. You can put a Lingo statement, as we did, but it must be prefaced with “lingo:”. Alternatively, you can put a call to a handler, such as event: MyHandler. The word “event:” must be there and “MyHandler” needs to be a handler you defined in your Director movie. When this button is clicked in Director, alert “hello from Flash” executes just as if it were written in a Director script. This occurs on a mouseUp. Flash enables you to have it happen on Release (mouseUp), Press (mouseDown), Release Outside (mouseUpOutside), Roll Over (mouseEnter), Roll Out (mouseLeave), Drag Over, and Drag Out, as shown in Figure 17-22. There aren’t any corresponding Lingo event handlers for those last two, but you could create them easily enough.
Figure 17-22: Flash enables you to select check boxes to determine when the GetURL statement is executed.
Now open the flash button 1.dir movie, which you can find in the EXERCISE:CH17 (EXERCISE\CH17) folder on the accompanying CD-ROM. It has the Flash movie already imported. Go ahead and play the movie and click the button. You get a “hello from Flash” alert dialog box. Now create a new behavior for the Flash sprite, as shown in Figure 17-23.
Figure 17-23: Create and then apply this behavior to your Flash sprite.
3486-6 ch17.f.qc
7/24/00
5:52 PM
Page 669
Chapter 17 ✦ Vector Shape and Flash Lingo
Play the movie and click the button and other parts of the Flash movie. When you click the Flash button, the “hello from Flash” dialog box pops up, and right after it comes the “Hello from Director” dialog box. If you click elsewhere on the Flash sprite, you still get the “Hello from Director” dialog box, because this script is applied to the sprite — button, background, and all. This is because the default eventPassMode for a sprite is #passAlways. This means that the sprite passes the mouseUp event to the sprite’s behaviors. While the movie is playing, type the following in the Message window: set the eventPassMode of sprite 1 to #passButton
Now when you click the Flash button, you still get both messages, but when you click elsewhere on the Flash sprite, you don’t get any alerts. This is because you have told the sprite only to pass events when a button is clicked. Of course, if you click the Stage, no message for any of these examples appears, because we don’t have a mouseUp in the Frame behavior. While the movie is still playing, type the following code in the Message window: set the eventPassMode of sprite 1 to #passNotButton
Click the button and other areas of the sprite. When you click the Flash button, you see the Message “hello from Flash.” When you click anywhere besides a button, you see “Hello from Director.” This setting only passes events to a sprite’s behaviors if the sprite was clicked, but not on one of its buttons. This is a good way to avoid having conflicting scripts execute, one from Flash and another from Director. Next, try this: set the eventPassMode of sprite 1 to #passNever
Now, you’ve told the sprite never to pass events. It just sucks them up and uses them when it needs to, such as when you click one of its buttons. Finally, we have the following: set the eventPassMode of sprite 1 to #passAlways
This sets it back to its default behavior. Next, try typing this code: set the actionsEnabled of sprite 1 to 0
This statement disables the actions in the Flash sprite. The button still goes up, down, and has a rollstate. You can use this in conjunction with #passButton for the eventPassMode to have your Director scripts replace ones embedded in the Flash movie. If you want to disable all the buttons in a Flash sprite, just set buttonsEnabled to 0, or FALSE, as follows: set the buttonsEnabled of sprite 1 to 0
669
3486-6 ch17.f.qc
670
7/24/00
5:52 PM
Page 670
Part IV ✦ Controlling Media with Lingo
You can use this movie to understand some of the other interaction-based events. Open the Watcher window and enter the statements shown in Figure 17-24. Remember that you don’t enter the equals sign or anything after it; that information is what the expression evaluates to. Play the movie and watch as you roll the mouse over different areas of the Flash sprite. You see the value of the hitTest (sprite 1, the mouseLoc) expression change from #background to #button and to #normal when it is over a nonbutton Flash element. The mouseOverButton is a quick way sto test whether the cursor is over a button in a Flash sprite.
Figure 17-24: Viewing results using the Watcher window
Summary Some of the things you learned in this chapter include the following: ✦ How to create and modify vector shapes. ✦ Vector shapes and Flash movies have many of the same commands. ✦ Flash movies can be embedded or linked. ✦ There are many Flash-only properties dealing with playback, streaming, and interactivity. ✦ Flash movies can have Lingo embedded in them. The next chapter explores using Lingo with sound.
✦
✦
✦
3486-6 ch18.f.qc
7/24/00
5:52 PM
Page 671
18 C H A P T E R
Sound Lingo
U
sing the sound-related Lingo commands frees you from the limitations of just two audio channels in the Score. In this chapter, you learn to play linked and embedded sound files, start and stop the playback of a sound, trigger an event upon the completion of an event, and control sound volume. Lastly, we cover the new sound channel objects and how they enable you to play back sounds much faster, play parts of sound members, and other controls.
Controlling Sound with Lingo You can use digital audio to add narration, special effects, and background music to an interactive media project. Sound in your movie can be triggered by a variety of events, including these: ✦ When the user clicks a button or other sprite ✦ When the mouse pointer rolls over a specific sprite ✦ When the playback head plays a specific series of frames ✦ While the playback head loops through a single frame There are three Lingo commands that you can use to play a sound file in your movie. You can use the puppetSound command to play an embedded sound cast member, or you can play an external (linked) sound file by using the sound playFile command. The third method is through using sound references. We look at puppet sounds in the first part of this chapter. A later section, “Playing Linked Files with Lingo,” discusses linked sound files. “Sound Channel Objects” the end of the chapter teaches you to use this new type of object.
✦
✦
✦
✦
In This Chapter Triggering and controlling sound with Lingo Setting the volume level of sound Preloading digital sounds Using the Beatnik Lite Xtra Sound channel objects
✦
✦
✦
✦
3486-6 ch18.f.qc
672
7/24/00
5:52 PM
Page 672
Part IV ✦ Controlling Media with Lingo
Using puppet sounds The most common method of adding sound to your movie is to use the puppetSound command. The command’s syntax is very simple: puppetSound castSound puppetSound channelNumber, castSound
The channelNumber parameter determines which channel the sound plays in. When you have only one parameter, it is assumed to be the name or number of a sound cast member. Although the Score window has only two sound channels, you can access additional sound channels by using Lingo. In the following statement, the sound “musicBed” is played in channel 4: puppetSound 4, “musicBed”
The puppetSound command can support a maximum of eight sound channels on a Macintosh system, or four on a Windows system. The castSound parameter is the cast member name or number of the sound cast member. If you use the cast member name, it must be enclosed within quotation marks. For instance, the following instruction plays a sound in the cast named siren.wav or siren.aiff, in channel 1: puppetSound 1, “Siren”
Note that you don’t need to include the sound file’s extension when using the puppetSound command. If the “Siren” cast member is in cast position 5, you can use the following command form: puppetSound 1, 5 Note
When you issue the puppetSound command, the sound takes precedence over any sounds in the Score’s two sound channels.
Mechanically speaking, sounds in Director play only at these times: ✦ When the playback head moves, as in a go to the frame handler, or when the playback head moves through a series of frames, each of which has the sound in the sound channel ✦ Whenever the updateStage command is issued Note
When a sound fails to play, the most common cause is the programmer’s failure to follow the puppetSound command with the updateStage command.
3486-6 ch18.f.qc
7/24/00
5:52 PM
Page 673
Chapter 18 ✦ Sound Lingo
Adding music and special effects to a multimedia presentation does not require that you create the sound files from scratch. A large body of clip media exists that you can purchase and use royalty-free in your productions. Always check the licensing agreement that accompanies any clip media you use. You can use some clips only for personal use or for internal use within your company. Others are royalty-free in all cases. Almost every publisher of clip media, however, prohibits the user from repackaging some or all of the media clips for resale as a clip media collection.
Triggering sound by using Lingo In the following steps, you modify the sound 1.dir movie to play sounds when the user clicks a sprite on the Stage (see Figure 18-1).
Figure 18-1: The sound 1.dir movie
To complete the movie, you add behaviors (using the puppetSound command) to play the appropriate sound file when the user clicks an object. All the sounds are internal to the movie; that is, they are embedded and not linked external files. On the CD-ROM
You can find sound 1.dir on the companion CD-ROM in the EXERCISE:CH18 (EXERCISE\CH18) folder.
Using Lingo to Add Sounds to noise.dir 1. Open the sound 1.dir movie in Director. 2. Select the Ambient Sound One button sprite. 3. Ctrl+click (right-click) on it and choose Script to create a new behavior for that sprite.
673
3486-6 ch18.f.qc
674
7/24/00
5:52 PM
Page 674
Part IV ✦ Controlling Media with Lingo
4. Modify the script to match Figure 18-2. Figure 18-2: This script plays “sound 1” in the first sound channel.
5. Name the script B_sound button. 6. Close the Script window and save the movie. 7. Play the movie and test it by clicking the Ambient Sound One button. The sound plays for a few seconds and then stops. 8. We have three buttons still without scripts. This would be a good opportunity to make the script a little more generic. Open the Script window B_sound button. 9. Create an on getPropertyDescriptionList handler, as shown in Figure 18-3. This script uses two properties: pChannel to hold the channel number the sound plays in, and pSound to hold the name of the sound member. Figure 18-3: Make a more generic script for playing sounds.
10. Drag the behavior onto one of the other sprites. When you do, a dialog box pops up (see Figure 18-4).
3486-6 ch18.f.qc
7/24/00
5:52 PM
Page 675
Chapter 18 ✦ Sound Lingo
Figure 18-4: The dialog box created from the getPropertyDescriptionList handler.
11. If you dragged it onto Ambient Sound Two, then choose sound 2 for Sound Name and move the Sound Channel slider to number 2. 12. Repeat Step 11 for the remaining buttons, applying the appropriate sound and channel for each. 13. Save the movie again and play it. Test each object to be sure that each sound plays. Because they are playing in different channels, the sounds can play at the same time. Note
Note that we gave the sound cast members different names from those of the bitmap cast members. If they had the same names, Director would play or use the lowest-numbered cast member when the cast member’s name is referenced in a Lingo command, with the result that the sound would not play when you click the button.
Attaching sound to sprites and buttons It is a good idea to give some visual feedback, to go along with the sound, when a user clicks the button. Create another behavior, as shown in Figure 18-5.
Figure 18-5: A simple behavior to handle up and down states
675
3486-6 ch18.f.qc
676
7/24/00
5:52 PM
Page 676
Part IV ✦ Controlling Media with Lingo
If you studied Chapter 14, then this handler looks basic to you. If you wanted, you could use the behavior created in Chapter 14 instead. This one is straightforward — it sets the button graphic to the down state that you specify when you apply the behavior. The dialog box is shown in Figure 18-6. Figure 18-6: Choosing the up and down states for the buttons
To make sound play continuously (or until another sound or action interrupts it), select the sound cast member in the Cast window (not the sprite that you click to play the sound). Then click the Cast Member Properties button, and be sure that the Loop check box is checked. You need to do this for each button. Finally, if you set a sound file to loop, be sure that the clip’s beginning and end blend well. Sometimes just adding a fade to a pause at the end and a fade-in does the trick. Fade-in and fade-out are discussed in the section “Controlling Fade-in/ Fade-out.” Save this movie as sound 2.dir.
Stopping sound After a sound has started, you might not always want it to finish playing. Lingo provides at least two methods for terminating the playback of a sound. First, you can issue the puppetSound command with the 0 (zero) parameter, as follows: puppetSound 0
This command causes Lingo to relinquish control of the sound channels and return that control to the Score. The syntax puppetSound 0 will kill sound in channel 1. To specify a specific channel, such as channel 2, write the following code: puppetSound 2, 0
Another method of stopping one sound is to begin playing another sound in the same sound channel. A Sound channel can play only one sound at a time. In the next series of steps, you provide a mechanism for the user to stop the audio. As the sound2.dir movie is currently constructed, every sound that is played continues to loop. By modifying the noise1.dir movie as outlined in the exercise, you enable the following actions: ✦ Clicking the Stop Sound button terminates all sounds. ✦ Clicking the Stop Sound button again just turns that sound off.
3486-6 ch18.f.qc
7/24/00
5:52 PM
Page 677
Chapter 18 ✦ Sound Lingo
Adding a Button to Stop the Sound 1. Open the sound 2.dir movie. 2. Select the gray plug in the lower-right corner, and then select cast member “stopSound up” (member 21) and choose Edit ➪ Exchange Cast Members. Your Stage looks like that in Figure 18-7.
Figure 18-7: The Stop Sound button replaces the gray plug.
3. Now, drag the B_button state change behavior onto it. When the dialog box opens, choose stopSound up for the up state and stopSound down for the down state. 4. Create a new behavior, as shown in Figure 18-8, and apply this behavior to the Stop Sound button. This behavior loops through all the sound channels and turns the puppeting off, killing the sound. Figure 18-8: The violently named KillSound handler
677
3486-6 ch18.f.qc
678
7/24/00
5:52 PM
Page 678
Part IV ✦ Controlling Media with Lingo
5. Play the movie and click several of the sound buttons, and then click the Stop Sound button to kill all the sounds at once. Save this movie as sound 3.dir. 6. Now open the B_sound button script and make the changes to the mouseUp handler, as shown in Figure 18-9. This makes the buttons toggle between playing and stopping the sound. It tests to see if the sound is playing. If it is, then it unpuppets the sound; otherwise it plays the sound. Save this movie as sound 4.dir. Figure 18-9: Turning the sound buttons into toggles
Additional Lingo controls for digital sound With Lingo, you can do far more than just play and stop sounds. You can determine whether a specific sound channel is busy, enable and disable sounds, control the sound’s volume, and cause a sound to fade in or fade out. Let’s take a look at how you accomplish each of these controls.
Determining whether a sound channel is busy The soundBusy function determines whether a sound channel is busy or not. We used it in the preceding exercise. If the sound channel specified is busy, the function returns 1. If the sound channel is not busy, the function returns the 0. Before you check whether a sound is playing, give Director sufficient time (a delay) to begin playing the sound, or else the soundBusy function might return 0. Practical uses of the soundBusy function include: ✦ Looping within a frame until a sound finishes and then enabling the playback head to move to the next frame. This works very effectively for a self-advancing linear slideshow of sounds and images within your movie. ✦ Using a single object to toggle on and off a sound that is playing.
3486-6 ch18.f.qc
7/24/00
5:52 PM
Page 679
Chapter 18 ✦ Sound Lingo
Using soundBusy to advance to the next frame You can use the silence that follows the completion of a sound as the trigger to advance the playback head to the next frame. Such an approach is useful when you create a linear slideshow of images that are synchronized to specific sounds or breaks in narration. You can effectively use this technique in the following situations: ✦ When sounds or narration correspond to specific frames of a Director movie — that is, when a specific frame has an image on the Stage that corresponds to a given segment of digital sound ✦ When you check for the completion of a sound by means of the soundBusy command ✦ For sounds that have natural breakpoints that you can edit into separate sound cast members, which then can play and complete (triggering the next frame and the next sound) You can also use a single sound track with cue points, and then have the playback head advance to the next frame as each cue point is encountered. We discuss cue points in a later section. The handler in Figure 18-10 demonstrates the soundBusy technique. It does not matter whether the sound was puppeted or is actually in the Score. Figure 18-10: Looping on a frame until the sound in channel 1 has stopped
The net effect is to loop the playback head within the current frame (showing the desired image and playing the desired sound or narration). When the sound finishes, the playback head moves to the next frame. If you repeat this script over a series of frames, you create a slideshow of images that advance whenever the narration for the current slide finishes.
Adding a film loop and playing sound In the next exercise, you add visual interest to the movie by switching a film loop for a stationary image. A film loop and sound together add a little more complexity to the project.
679
3486-6 ch18.f.qc
680
7/24/00
5:52 PM
Page 680
Part IV ✦ Controlling Media with Lingo
The best approach is to list what you want to occur in the movie and then convert the list into Lingo scripts. Here are the actions that we want to occur: ✦ Start a new sound as soon as the user clicks the Play Sound button. ✦ When the sound starts, the sprite for the levels indicator should switch members with the film loop. ✦ As long as the sound plays, the film loop is on the Stage. ✦ If the user clicks again, the film loop is swapped with the cast member named level indicators off. To accomplish all this, apply the behaviors that you created in an earlier exercise. The behaviors are already in the movie, so you don’t have to copy and paste them from the other movie. Then you need to create a new behavior that keeps track of the sound channel. On the CD-ROM
For the following exercise, use filmloop.dir in the EXERCISE:CH18 (EXERCISE\ CH18) folder on the CD-ROM that accompanies this book.
Adding a Film Loop and Playing Sound 1. Open filmloop.dir (see Figure 18-11).
Figure 18-11: The filmloop.dir movie
2. Apply the behaviors B_sound button and B_button state change to the Play Sound button. Have the sound play in channel 1, and choose the appropriate up and down states, as you did earlier. 3. Ctrl+click (right-click) the level indicators sprite and choose “Script” to create a new behavior for this sprite.
3486-6 ch18.f.qc
7/24/00
5:52 PM
Page 681
Chapter 18 ✦ Sound Lingo
4. Create the script shown in Figure 18-12. This script has three properties. The first property, pSprite, you are familiar with. The other two are references to the on and off states for the level indicators. The on state is a filmloop. In the exitFrame handler, sound channel 1 is checked with the soundBusy() function to see whether a sound is playing. If 1 is returned from the test (of sound channel 1), the filmloop is put into the member for its sprite; otherwise, the bitmap “level indicators off” is put in the member. Figure 18-12: A behavior for the level indicators
5. Play the movie and turn the sound on and off. The level indicators go on and off as you would expect if they were responding to the sound playing. Save this movie as filmloop 2.dir.
Playing sound while the mouse is down Using Lingo-related sound commands, the methods available to control sound playback are almost as endless as the digital sounds available. So far, you have learned to turn sound off and on by using a button or object. You can also cause a sound to play as soon as the mouse button is pressed or for as long as the mouse button is pressed down. To have a sound play as soon as the mouse button is pressed, you need to add an updateStage following the statement with the puppetSound command. In the handler in Figure 18-13, the sound cast member “LLOOP09” plays as long as the mouse button is pressed down. As soon as the user releases the mouse button, the puppetSound 1, 0 command is executed, which stops the music. If the update Stage were not there, the sound would never start; it would be turned off before it began. The repeat loop has one statement, the keyword nothing. nothing in Lingo does exactly that — nothing. It is not necessary, but it adds some clarity to the repeat loop: You know the intent is to do nothing while the mouse button is pressed down.
681
3486-6 ch18.f.qc
682
7/24/00
5:52 PM
Page 682
Part IV ✦ Controlling Media with Lingo
On the CD-ROM
You can see the script from Figure 18-13 in mousedown.dir.
Figure 18-13: This handler plays a sound until the mouse button is released.
Playing sound on a rollover Playing a sound when rolling the cursor over an element is often used. Having the element change in response to the mouse being over it is another common effect. In the next exercise, you do both. On the CD-ROM
You can find rollovers 1.dir on the companion CD-ROM, in the EXERCISE:CH18 (EXERCISE\CH18) folder.
Activating Sound When the Mouse Rolls Over a Sprite 1. Open the movie rollovers 1.dir. 2. Create a new behavior in member 7, as shown in Figure 18-14. This behavior is very similar to the behavior for clicking a button to hear a sound. In fact, the properties and the getPropertyDescriptionList are the same. The difference is the mouseEnter and mouseLeave handlers. The mouseEnter puppets the sound when the cursor enters the bounds of the sprite; when it goes outside the bounds, it turns the sound off. 3. Apply this behavior to each of the four buttons. Make the first button play sound 1 in channel 1, make the second button play sound 2 in channel 2, and so on. Play the movie to make sure it works. 4. A nice effect is to have the state of the button change as well as the audio feedback. Create a new behavior in member 8, as shown in Figure 18-15. This behavior should also look familiar to the one in Figure 18-5. Instead of swapping members on the mouseDown, it swaps them when the cursor enters the sprite.
3486-6 ch18.f.qc
7/24/00
5:52 PM
Page 683
Chapter 18 ✦ Sound Lingo
Figure 18-14: The behavior to activate the sound when the cursor rolls over a button.
Figure 18-15: This behavior changes the button sprite’s member when the cursor rolls over it.
5. Apply this behavior to each of the buttons. Make sure you specify the appropriate up and down states. 6. Play the movie to test the behaviors. When you’re finished, save the movie as rollovers 2.dir.
683
3486-6 ch18.f.qc
684
7/24/00
5:52 PM
Page 684
Part IV ✦ Controlling Media with Lingo
Playing random sounds Whenever possible, you should add variety and a little friendly unpredictability to your movies. Moreover, although you want navigational buttons to always behave in the way the user expects them to, it doesn’t hurt to add some surprises to the animation that occurs on the Stage or to the sounds generated by specific objects. You can use the random() function to randomly choose various sounds to play when the user clicks the sound button. The handler in Figure 18-16 has a list of sounds hard-coded in it. The list is assigned to the variable soundList. Then r is assigned a random number from 1 to the number of items in the soundList. We could have made the code simpler by writing r = random(3), but then each time you added or removed an item from the soundList you would also have to remember to change the number in the following line of code. Using the count function to count the number of items enables us not to have to worry about that. Additionally, it makes it more obvious in the code that r is related to the soundList. Lastly, the r-th item is retrieved from the list and that sound is puppeted. Figure 18-16: A simple behavior to play a random sound on a mouseUp.
The handler in Figure 18-16 is fine in most cases, but it never hurts to do some error checking, especially when you are working on large projects with others who might be modifying the movie elements or code. Figure 18-17 adds some error checking. The first two statements are the same. After that, you test to determine whether the member actually exists. The number of member returns a –1 when a member is not found. If the member is not found, an alert pops up. Figure 18-17: Before attempting to puppet a sound, add error checking.
3486-6 ch18.f.qc
7/24/00
5:52 PM
Page 685
Chapter 18 ✦ Sound Lingo
Note in the alert statements that we used &"E&. You can write it all squished together or you can write it && QUOTE &. The double ampersands, as you might recall, concatenate two strings with a space between them. QUOTE is a Lingo constant that enables you to put a double quotation mark into a string. The single ampersand just concatenates two strings. This is true of any constants that you use in a string (such as &RETURN&). Sometimes the code is more readable when you chunk items together in this way.
Playing a list of sounds in one frame Another way to use sound is to play a series of sound clips sequentially in a single frame. Conceivably, you could combine the multiple sound clips into a single clip and play it in one frame or over several consecutive frames. Because smaller sound clips load more quickly, however, it’s often a good plan to play several sounds sequentially in a single channel. The following exercise is one approach to the task. On the CD-ROM
You can use the movie soundlist 1.dir from the EXERCISE:CH18 (EXERCISE\CH18) folder on the accompanying CD-ROM for the following exercise.
Playing Three Sounds Sequentially in One Frame 1. Open a new movie by choosing File ➪ New ➪ Movie, or press Command+N (Ctrl+N), or open soundlist 1.dir on the CD-ROM. 2. If you created a new movie, import any four sound files. (It doesn’t have to be four, that’s just a suggestion; it can be more or less.) 3. Double-click the Script channel in frame 1, and type the script shown in Figure 18-18. If you imported your own sounds, then soundList should be assigned their names instead of the ones shown. You can put as many or as few items as you like in this list. This behavior checks to see whether sound channel pChannel is busy; if it is not, it calls the PlayNextSound handler. PlayNextSound plays the sound indicated by pTrack and then increments pTrack. If pTrack exceeds the number of items in soundList, it is set back to 1. 4. Save the movie as soundlist 2.dir, and then rewind and play it. Note that nothing appears on the Stage when you play the movie, but the three sound clips play sequentially repeatedly. (They won’t stop until you stop the movie.) 5. To make this behavior more flexible, you can add a getPropertyDescriptionList to it so that when you drag it into the Score, it asks you which channel you want to play the sound in (see Figure 18-19). This way, you won’t need to go back into the code to change pChannel’s value. Figure 18-20 shows the changes necessary to do this. 6. Save this movie as soundlist 3.dir.
685
3486-6 ch18.f.qc
686
7/24/00
5:52 PM
Page 686
Part IV ✦ Controlling Media with Lingo
Figure 18-18: A frame script behavior that plays one sound after another.
Figure 18-19: A slider is created so that the user can choose a sound channel from 1 to 8.
Figure 18-20: Adding a getPropertyDescriptionList handler
3486-6 ch18.f.qc
7/24/00
5:52 PM
Page 687
Chapter 18 ✦ Sound Lingo
Playing linked files with Lingo Director has several ways to incorporate sound into a movie. You can import, insert, or link sounds. Importing embeds the sound in the movie, and inserting links the sound. There is an important difference in the functionality of an imported/linked versus inserted sound. Director can only insert Shockwave Audio (SWA) files; when you do that, you have all of the Shockwave audio commands available to you, as shown in Figure 18-21. Director can now import Shockwave Audio (as well as other sound formats, such as WAV, AU, and AIFF). When a Shockwave Audio file is imported, it is treated just like other imported sounds: You can no longer use the Shockwave Audio Lingo on it. If you test the type of the member, it returns #sound (as opposed to #swa, for an inserted Shockwave Audio).
Figure 18-21: The Sound and Sound Members/Shockwave Audio Lingo menus
Another way to play an external (linked) sound file is by using the sound playFile Lingo command. Director can work with AIFF, SWA, AU, or WAV files on either a Macintosh or a Windows system. A nice aspect of using the sound playFile command is that the sound does not have to be in the movie. The syntax is: sound playFile channel, pathToSound
687
3486-6 ch18.f.qc
688
7/24/00
5:52 PM
Page 688
Part IV ✦ Controlling Media with Lingo
You replace the channel parameter with a channel number, and the path to the file to be played replaces the pathToSound parameter. If the path is a URL, it’s not a bad idea to use preloadNetThing or downloadNetThing to download the file before playing it. You cannot use the sound playFile command to play an embedded cast member. Note
Using the puppetSound command loads the sound file into RAM and then begins playing it, but the sound playFile command streams the audio from disk and begins playing it immediately. Remember that your computer cannot read two disk files simultaneously. If a Director movie is reading a sound file using the sound playFile command, the movie cannot concurrently play digital video, load cast members into memory, or conduct any other disk read/write activity.
For example, the following command plays the sound file “jazz” from an external sound file in channel 2: sound playFile 2, “jazz”
If you don’t place the external sound file in the same folder or directory as the movie, you must include the file’s path preceding its filename. For example, if the “jazz” sound file is in a folder called SOUNDS on your local hard drive, the sound playFile command requires one of the following pathname formats: ✦ On a Macintosh system, assuming the local hard drive is Macintosh HD, the pathname would be indicated like this: sound playFile 2, “Macintosh HD:sounds:jazz”
✦ On a Windows system (assuming the local hard drive is C:), the pathname would be indicated like this: sound playFile 2, “c:\sounds\jazz”
✦ If the sound is a linked file, you can use its fileName property to play it, as follows: sound playFile 2, the fileName of member “jazz”
Controlling the Sound Volume You can control the sound in a movie in one of three ways: ✦ By adjusting the sound level for all sounds playing (using the soundLevel property) ✦ By adjusting the volume of a specific sound in a specific channel (using the volume of sound property) ✦ By causing a sound to fade in or fade out over a specific time period (using the sound fadeIn and sound fadeOut commands)
3486-6 ch18.f.qc
7/24/00
5:52 PM
Page 689
Chapter 18 ✦ Sound Lingo
Using the soundLevel property The soundLevel property enables access to the sound hardware on your computer to adjust its overall volume. With the soundLevel property, you can set or determine the volume of the sound that is played through your computer’s speakers, from a value of 0 (muted) to 7 (maximum volume). The syntax for setting the sound level (volume) is as follows: set the soundLevel to n
You replace n with an integer value from 0 to 7 representing the sound volume. For example, to set the volume to the maximum level, you can use the following instruction: set the soundLevel to 7
In the following steps, you modify the soundlevel 1.dir movie to set the volume of a sound cast member played through your computer’s speakers. On the CD-ROM
The file soundlevel 1.dir is on the companion CD-ROM in the EXERCISE:CH18 (EXERCISE\CH18) folder.
Setting the Volume Level of Sound 1. Open the movie soundlevel 1.dir. Figure 18-22 shows soundlevel 1.dir. You need to add three scripts to the movie to make it functional. There are already three scripts in the movie that should be familiar to you in members 2 through 4. They are the behaviors for the sound button, the button state change, and a go to the frame. They have already been applied to the appropriate sprites. 2. The up and down buttons already have the “B_button state change” applied to them, so they highlight when you click them, but they do not do anything. Create a new behavior in member 5, as shown in Figure 18-23. This behavior increases the sound by one increment each time the button is clicked. If the soundLevel is already at 7, it has no effect. 3. Apply this behavior to the Increase button. 4. Create another behavior in member 6, as shown in Figure 18-24. This is the behavior for decreasing the sound. It is not as simple as the behavior to increase sound. When you try to set the soundLevel to a number less than zero, Director sets the soundLevel to 7, which is probably not a desirable effect — lowering the sound and it suddenly blares it. That’s why you need to test the soundLevel before setting it. If it is above 0, lower it; otherwise, do nothing.
689
3486-6 ch18.f.qc
690
7/24/00
5:52 PM
Page 690
Part IV ✦ Controlling Media with Lingo
Figure 18-22: The soundlevel 1.dir movie Figure 18-23: Increasing the soundLevel
Figure 18-24: Decreasing the soundLevel
3486-6 ch18.f.qc
7/24/00
5:52 PM
Page 691
Chapter 18 ✦ Sound Lingo
5. Apply the behavior to the Decrease button. 6. Now for the fun part! Create a new behavior in member 7, as shown in Figure 18-25. This behavior is for the volume bars. In the exitFrame, it checks to see what the soundLevel is. If it is over a certain amount, it switches the member of the sprite to which it is applied. The number of the sprite minus an offset determines the amount. We are taking advantage of the fact that all seven bars are laid out in a group in the Score (see Figure 18-22). Because the sprites begin in channel 11, if you subtract 10 from the first one in channel 12 you get 2. If the soundLevel is greater than or equal to 2, then this member is switched on. The sprite in channel 11 is also on because 2 > 11 – 10 (the soundLevel >= (me. spriteNum - pOffset)), but the sprites in channels 13 to 17 are not on. Figure 18-25: Creating a behavior for the volume bars
7. Save the movie as soundlevel 2.dir. Play it to test. The volume bars work whether or not a sound is playing, because they detect the soundLevel, not whether sounds are playing.
Using the volume of sound property Like the soundLevel property, the volume of sound property enables you to control volume — in this case, the volume of a specific sound channel. Further, you can control the volume with a greater degree of precision because you have a wider range of acceptable values for this property: from 0 (muted) to 255 (the maximum volume). The volume of sound is relative to the soundLevel, so if channel 1 gets set to maximum volume and the soundLevel is at 0, you won’t hear anything. In the following statement, the sound in channel 1 is set to the maximum volume: set the volume of sound 1 to 255
691
3486-6 ch18.f.qc
692
7/24/00
5:52 PM
Page 692
Part IV ✦ Controlling Media with Lingo
The following statement mutes the sound that is playing in channel 2: set the volume of sound 2 to 0
Because this property can be determined or set by the user, it is often adjusted by using a slider to control the volume of sound in a movie. In the following steps, you modify the volume of sound 1.dir movie so that the user can control the volume of sound played in a specific sound channel. In the completed slider movie, shown in Figure 18-26, you are able to click the Channel One button and manipulate the volume of that channel with the Volume Control slider. The text members below the Channel buttons give feedback as you move the slider. When you click the Play Sound button, it plays one of two sounds, one for sound channel 1, and another for sound channel 2. It requires the creation of four behaviors and one movie script. Because there is only one slider and two channels being modified in this movie, the slider needs to know which channel has the focus (which one is the target). For this we create a global variable called gTargetChannel, which is accessed by many of the behaviors.
Figure 18-26: The slider movie On the CD-ROM
The file slider 1.dir is on the companion CD-ROM in the EXERCISE:CH18 (EXERCISE\ CH18) folder.
Setting the Volume Level for a Sound Channel 1. Open slider 1.dir. 2. Create a new behavior in member 3, as shown in Figure 18-27.
3486-6 ch18.f.qc
7/24/00
5:52 PM
Page 693
Chapter 18 ✦ Sound Lingo
Figure 18-27: A behavior for the text members to monitor the sound channels
3. Apply the behavior to both text member sprites (6 and 7), which are below the Channel One and Channel Two buttons, respectively. This behavior monitors the volume of a sound channel. When you apply the behavior to a sprite, the Parameters dialog box pops up and you can choose between channel 1 or 2. If you wanted more options in the My Channel pop-up dialog box, then you would add those to the #range list in the getPropertyDescriptionList() function. Each time the exitFrame handler executes, it sets the text of the member in the sprite to the value of the volume of sound for the channel it monitors. The text of a member must be a string, so the string() function is used to convert the integer to a string. 4. Create a new behavior in member 3, as shown in Figure 18-28. Figure 18-28: The behavior of the Channel One and Channel Two buttons
693
3486-6 ch18.f.qc
694
7/24/00
5:52 PM
Page 694
Part IV ✦ Controlling Media with Lingo
5. Apply this script to the Channel One and Channel Two button sprites (sprites 3 and 4, respectively). This is the longest script in the movie, but several of the elements should be familiar to you by now. The purpose of this script is to set the global gTargetChannel when the button is clicked. It then sends a message to the slider sprite so that it can deal with the change of channels. The beginSprite handler initializes all of the properties except pChannel. pChannel is given a value when you apply the behavior to a sprite. pSprite is the reference to the sprite. pOnMember and pOffMember are references to members for on and off, respectively. pSliderSprNum is the number of the sprite channel that the slider is in. This behavior needs it so that it can communicate with it. You could put pSliderSprNum in the getPropertyDescriptionList() function and set the value when you apply the behavior. We chose to put it in the code so that if we need to change its value, we only have to make the change in one place. The mouseDown handler sets the global gTargetChannel to its channel (held in pChannel). Then the slider sprite is sent a message to let it know the target has changed. We’ll explain why this is necessary in the slider script. The exitFrame just tests the value of gTargetChannel. If pChannel is the same as gTargetChannel, the button lights up; otherwise, it stays dim. 6. Create a new behavior in member 5, as shown in Figure 18-29.
Figure 18-29: The behavior for the slider
7. Apply this behavior to the slider sprite (sprite 10). This behavior makes the sprite move like a sliding switch. It uses another invisible sprite to constrain its movement; the invisible sprite is just a rectangle shape with no stroke or fill. It assumes the constraining sprite is in the channel just below its sprite channel. Another way to constrain movement is to do it through code and not use another sprite. That way has advantages in not relying on two sprites, but it makes for code that is more complex.
3486-6 ch18.f.qc
7/24/00
5:52 PM
Page 695
Chapter 18 ✦ Sound Lingo
The beginSprite handler sets pSprite and then sets the moveableSprite property of pSprite to TRUE. This enables the user to click and move the sprite at will. You don’t want a user moving it all over the screen, so it is constrained to the bounds of the sprite right below it. The exitFrame handler has one long statement. It sets the volume of a sound channel based on gTargetChannel’s value. The level the sound is set to is based on the location of the sprite minus the constraining sprite’s location, multiplied by 255.0 (the maximum sound level) divided by the width of the constraining sprite. 255 is made a float (255.0); otherwise, the division would be integer division. So, every time the exitFrame is called, the volume of the current sound channel is changed. The ChangeTarget handler is also a single long statement. It takes the value of the current channel and sets the sprite’s locH. The calculation is the reverse of what is done in the exitFrame. ChangeTarget is called from “B_channel buttons” when the button is clicked. Why is this necessary when the exitFrame is always monitoring the value of gTargetChannel? When you clicked the other Channel button, the value of the field would be set to the value of the other button. Try commenting out the sendSprite(pSliderSprNum, #ChangeTarget) in the “B_channel buttons” behavior when the movie is finished for a clearer idea of what happens. 8. Create a new behavior in member 6, as shown in Figure 18-30.
Figure 18-30: An additional behavior for the Play Sound button
9. Apply this behavior to the Play Sound button (sprite 12). This behavior plays the sound based on the value of gTargetChannel. The sounds are named “sound 1” and “sound 2”. This enables you to simply concatenate “sound” with gTargetChannel. The double-ampersand is used to concatenate with a space in between the two strings. Sprite 12 already has one script, “B_button state change”, applied to it. 10. Last, but not least, create a movie script (not behavior) in member 7, as shown in Figure 18-31. All this script does is give the global gTargetChannel an initial value. 11. Save the movie as slider 2.dir and play it.
695
3486-6 ch18.f.qc
696
7/24/00
5:53 PM
Page 696
Part IV ✦ Controlling Media with Lingo
Figure 18-31: The global gTargetChannel is initialized in the startMovie handler.
Controlling fade-in/fade-out The third way to control sound volume is to cause the sounds to fade in and fade out as needed. This feature is useful when you want to smooth an otherwise abrupt beginning of a musical clip, or to fade out background music at a specific point in your movie. Fade-outs can also reduce the volume in one channel while the volume of narration or sound effects increases in another channel. You use two companion commands to handle the fade-in and fade-out of sound in a specific sound channel: sound fadeIn and sound fadeOut. The sound fadeIn command increases the volume of a sound until it reaches an optimum level over a specified period. The time specified is measured in ticks, with 60 ticks equal to a second. Any fade-in you specify continues at the predetermined rate until the specified time has elapsed, or until the sound in the specified channel changes or stops. To fade in a sound in channel 2 over a five-second period, for example, you use the following instruction: sound fadeIn 2, 300
Here’s another version of this instruction: sound fadeIn 2, 5*60
The advantage of the second method is that you can easily (without any mathematical effort) determine the number of seconds (in this case, 5) that the sound uses to fade in. When you specify the number of ticks, the fade-in occurs smoothly over the specified period. If you do not specify the number of ticks, however, Director calculates the default number of ticks as follows: 15 × 60 ticks / the Tempo setting in the first frame of the fade-in
3486-6 ch18.f.qc
7/24/00
5:53 PM
Page 697
Chapter 18 ✦ Sound Lingo
The sound fadeOut command decreases the volume of a sound in a specified channel over a specified number of ticks. Similar to the sound fadeIn command, sound fadeOut fades the sound smoothly over the period you specify. If you do not specify the number of ticks, Director calculates the default number of ticks as follows: 15 × 60 ticks / the Tempo setting in the first frame of the fade-out In the following example, the sound in channel 2 fades out over 3 seconds: sound fadeOut 2, 180
Note that the sound fadeIn command should precede the puppetSound command; otherwise, you hear the initial sound at the default volume, then hear it drop to a muted level, and then hear it fade in. On the other hand, the sound fadeOut command should follow the puppetSound command, so the initial sound is played at the current volume, which then drops (over the specified number of ticks) to a muted level.
Preloading and Unloading Cast Members Playing sound from large sound files can create delays. Director enables you to minimize (somewhat) these delays by doing the following: ✦ Preloading one or more specific cast members ✦ Preloading all cast members required in one or more frames Preloading cast members still takes time, and the amount of time required is contingent on the amount of RAM available, plus the size and number of the cast members that you want to preload. Nevertheless, there are advantages to using a preload of assets, because you can schedule the preload: ✦ While the system is normally idle ✦ When user interaction is not expected, such as while an instruction screen is displayed for the reader ✦ While a previously loaded animation is running You can also add a screen message that alerts the user that work is going on behind the scenes. Note
You never want to leave the user trying to figure out whether a mouse click worked or the program has locked up and gone into cyberspace.
697
3486-6 ch18.f.qc
698
7/24/00
5:53 PM
Page 698
Part IV ✦ Controlling Media with Lingo
Preloading specific cast members used in one or more frames You can use the preLoad command to load all the cast members required for one or more frames in your movie. For example: ✦ You can preload all cast members used in the current frame to the end of the movie by using the preLoad command without any parameters, as in the following: preLoad
✦ To load all cast members used in the current frame, through and including cast members used in frame 10, use the following command: preLoad 10
When you include a single parameter, the preLoad command preloads frames from the current frame through and including the frame designated by the parameter. ✦ To load all cast members used in frames 10 through 15, use the following command: preLoad 10, 15 Note
This command does not preload only the cast members in frames 10 and 15. It preloads all cast members in frames 10 through 15.
The preloading process terminates when your system’s RAM (working memory) is full or when the specified cast members are loaded. You can use label names (markers) with the preLoad command. If you use one label, Director preloads from the current frame through the frame indicated by the marker. If you use two label names, all cast members between the two label names are preloaded. In the following example, all cast members in the frames labeled “Start” (cast slot 1) and “Midway” (cast slot 40) are preloaded into memory: preLoad “Start”, “Midway”
Another variation is to have the preLoad command load all cast members from the current frame to the next frame with a marker. The command form is entered as follows: preLoad marker (1)
3486-6 ch18.f.qc
7/24/00
5:53 PM
Page 699
Chapter 18 ✦ Sound Lingo
Preloading specific cast members You use the preLoadMember command to load one or more cast members that you specify. Unlike the preLoad command, preLoadMember gives you greater control over selecting specific cast members that you want to place in RAM before they are normally loaded. Use this technique to load a cast member and then gain quicker display or playback of the member (sound, film loops, animation, and so on) at a specific point in the movie — without pausing to load the cast member. For example, you can do the following: ✦ You can preload all cast members in the entire movie by using the preLoadMember command without any parameters, as in the following: preLoadMember
✦ To load only cast member 20, use this command: preLoadMember 20
✦ To load all cast members (in the Cast window) beginning with cast member number 20 and up through 30, use this command: preLoadMember 20, 30
Note that this command form does not preload only the cast members 20 and 30. It preloads all cast members 20 through 30. The preloading process terminates when your system’s RAM (working memory) is full or when the specified cast members are loaded. You can use cast member names, as well, with the preLoadMember command. If you name a specific cast member, it alone is preloaded into memory. If you use two cast member names, all cast members between and including the first and last named cast members are preloaded. In the following example, all cast members between “Circus” and “Reg1” are preloaded into memory. preLoad “Circus” “Reg1”
Unloading cast members Preloading cast members can help eliminate loading delays and provide smoother playback of a movie, but eventually every computer system runs out of memory. To free up memory for different cast members, use the unLoad command. ✦ You can unload all cast members in all frames except the current one by executing the following instruction: unload
699
3486-6 ch18.f.qc
700
7/24/00
5:53 PM
Page 700
Part IV ✦ Controlling Media with Lingo
✦ You can also instruct Director to unload files from a specific frame (frame 25, in this example), by using the following instruction: unLoad 25
✦ Similar to the preLoad command, you can unload all cast members in a range of files (say, 25 to 35), by using this instruction: unLoad 25, 35
You can use cast member names, as well, with the unLoad command. If you name a specific cast member, it alone is unloaded from memory. If you use two cast member names, all cast members between the first and last named cast members are unloaded. In the following example, all cast members between and including “Circus” (cast slot 15) and “Reg1” (cast slot 18) are unloaded from memory: unLoad “Circus”, “Reg1” Note
You do not need to unload memory routinely, because Director automatically unloads the least recently used cast members based on the cast member’s Unload setting. The unLoad command is intended for special circumstances in which there is a lag in the startup of an animation, the redrawing of the Stage, the playback of a digital video, or the playback of a sound, due to the lack of sufficient working memory.
Director Does Beatnik Director now supports Beatnik via the Beatnik Lite Xtra (you can upgrade to the Beatnik Pro Xtra). Director 7 automatically installed it, but Director 8 requires you to install it manually from the Director 8 CD-ROM.
Creating a Beatnik object Creating a Beatnik object is just like creating an object with other Xtras. You can follow along in the Message window if you like. Make sure you first open the groovoid 1.dir movie, which you can find in the EXERCISE:CH18 (EXERCISE\CH18) folder on the CD. gMusic = new(xtra “Beatnik”)
That’s it. You’ve created an object. By default, the object plays direct-to-soundcard (DTC). DTC mode plays very fast and uses very little CPU time. If you need to play other sounds in Director simultaneously, then you need to use the Macromedia Open Architecture (MOA). This mode is not as responsive. You cannot have two instances of different types; all objects at any one time must be either DTC or MOA. To initialize the object to use MOA, write the following code: gMusic = new(xtra “Beatnik”, TRUE)
3486-6 ch18.f.qc
7/24/00
5:53 PM
Page 701
Chapter 18 ✦ Sound Lingo
After creating the instance (the object), you can set the slice size of the rendering buffers. If you do not, defaults are used based on the mode you are in. Larger setSliceSize values slow the response from the Beatnik Xtra, but they give you audio that does not break up. The default for the MOA mode is 12. It needs to be larger, because you are running two audio mixers (Beatnik’s and Director’s). If you are running in DTC mode, you get better performance and can set the slice to 1 or 2. Of course, you won’t be able to use other forms of sound in Director. For best performance, use Beatnik instances as you need them in DTC mode and then destroy them by setting the variable to VOID, before you use another type of sound: setSliceSize(gMusic, 1) --for DTC mode try values around 1 to 2 setSliceSize(gMusic, 12) --for MOA mode try values 11 to 13
Next, you need to tell the object the location of the sound bank it is going to use. In this case, use the one that comes with the Xtra, “patches.hsb” (which has a General Midi sound bank). setSampleLibrary(gMusic, the moviePath & “Patches.hsb”)
Now you need to initialize the Beatnik, which you do with the setReady command, as follows: setReady(gMusic)
At this point, you are ready to play some sounds. If you’re using a Mac, you might notice that this action takes a few seconds; this delay is reportedly being fixed for the Pro version and probably the next Lite version of the software.
Groovoids Groovoids are sound effects built into the sound bank. There are 72 available for Beatnik Lite, and even more in the Pro version. You can get a complete list from the documentation. Continuing with the instance created earlier (gMusic), here are a few Groovoids that you can try: playGroovoid(gMusic, playGroovoid(gMusic, playGroovoid(gMusic, playGroovoid(gMusic, playGroovoid(gMusic,
FALSE, FALSE, FALSE, FALSE, FALSE,
“UI-Chimes”) “UI-Click2”) “Background-InfoPulse”) “Fanfare-Sports”) “Misc-CashRegister”)
The first parameter is the object. The second is a Boolean value indicating whether the sound should loop. The third is the name of the Groovoid to play. Go ahead and play the groovoid 1.dir movie and try the different Groovoids. Click the Loop Sound? check box to have the Groovoid loop continuously (see Figure 18-32).
701
3486-6 ch18.f.qc
702
7/24/00
5:53 PM
Page 702
Part IV ✦ Controlling Media with Lingo
Figure 18-32: Give the Groovoids a try in the groovoid 1.dir movie.
Playing RMF Files You can also play Rich Music Format (RMF) files. To use the idunno.rmf in the same folder as the groove 1.dir, type the following: play(gMusic, FALSE, the moviePath & “idunno.rmf”)
Just as with the playGroovoid command, the second parameter is a Boolean value indicating whether the sound should loop. The third is a path to the file. There are quite a few methods available for manipulating Beatnik sounds in real time. We’ll touch upon some of the basics, and you can read more about them in the Beatnik Director Xtra — musicObject Lingo Handler Reference. To adjust the volume of the sound, just type the following: setVolume(gMusic, 50)
The volume can be set from 0 to 100. To add some reverb, you can type the following code: setReverbType(gMusic, 5)
Reverb can be set from 1 to 6. To change the tempo, use the following syntax: setTempo(gMusic, 60)
Tempo has a range of 0 to 499. With Beatnik, you can make MIDI Controller Changes on the fly. You can control certain synthesizer settings of an RMF or MIDI file as the file is playing back: setController(gMusic, 10, 7, 64)
3486-6 ch18.f.qc
7/24/00
5:53 PM
Page 703
Chapter 18 ✦ Sound Lingo
The preceding code sets the volume of the drums in channel 10 to 64 (possible values 0 to 127). The number 7 indicates the controller, which, in this case, is the volume. The movie beatnik 1.dir puts all of these elements together. Play the movie and try the different buttons (see Figure 18-33).
Figure 18-33: The beatnik 1.dir movie
Click the Play idunno.rmf button. After a few seconds, you hear drums in the music. Try the Fade Drums Out and then the Fade Drums In buttons. The speed at which the drums fade is based on the movie’s tempo (not the sound’s tempo). Try speeding up or slowing down the sound’s tempo. Clicking pause pauses the music. Clicking it again makes it resume from where it left off. Clicking Stop stops the music. Another fun thing to try, while the music is playing, is to change the program. While the music plays, type the following into the Message window: setProgram(gMusic, 0, 11) -- 11 is Vibraphone setProgram(gMusic, 0, 25) -- 25 is Steel Guitar setProgram(gMusic, 0, 14) -- 14 is Tubular Bell
Using this same command, you can also switch from the General Midi bank (0) of instruments to the Special Bank (1). You need to add another parameter to tell which bank to use. This additional parameter goes before the instrument parameter, as follows: setProgram(GetMusic(),0, 1, 24) -- 24 is Acoustic Bass Gtr in Special Bank
If we used the earlier setProgram commands, specifying the Special Bank would get the Special Bank instruments, as follows: setProgram(gMusic, 0, 1, 11) -- 11 is Vibraphone 2 setProgram(gMusic, 0, 1, 25) -- 25 is Mute Guitar 2 setProgram(gMusic, 0, 1, 14) -- 14 is Reverse Bell
To switch back to the General Midi bank, playing the Steel Guitar, you write the following code: setProgram(gMusic, 0, 0, 25)
703
3486-6 ch18.f.qc
704
7/24/00
5:53 PM
Page 704
Part IV ✦ Controlling Media with Lingo
Sound Channel Objects Director 8 adds a new sound channel object and a great deal of functionality. The only price to pay is a little bit of complexity. The sound channel object actually comes in the form of a reference object, very similar to the object returned when you get the “ref” of a chunk of text (for a discussion regarding using the “ref” keyword, see Chapter 16). Instead of a reference to a chunk of text in a text member, with the sound channel object you have a reference to a sound channel. Try the following in the Message window: put sound(1) --
The last chunk of data, b423878, will be different on your machine; in fact, it will be different for each movie. Fortunately, you don’t need to concern yourself with it! On the CD-ROM
Open the movie sound_channel.dir in the EXERCISE:CH18 (EXERCISE\CH18) folder on the CD-ROM so you can follow along, trying the new commands from the Message window.
You can place a sound channel object reference into a variable to shorten your code and make it more understandable, as follows: myChan = sound(1)
If you want to play a sound using the channel object, write the following code: sound(1).play(member(1))
You should hear the sound start playing. This command is analogous to typing the following: puppetSound 1, member 1
So, which seems friendlier? On one hand, you have a more intuitive sounding command, play(). On the other hand, you have much simpler syntax. You can use standard syntax to simplify things. Although this is a new command, it can still be constructed by using old syntax: play sound 1, member 1
Because play is not a function, the parentheses are not necessary. Many of the help examples do not use this syntax, so we’ll stick to dot syntax because it seems the way of the future. It is more likely that other folks will write code similar to the online help examples, not even aware of the old syntax. The new sound object has quite a few new commands and functions (see the table below). Of these, many should be familiar, such as fadeIn() and fadeOut(). These handlers have been in Director for years and now work with the sound channel object. Some, such as queue() and setPlayList(), are new and we’ll talk about those next.
3486-6 ch18.f.qc
7/24/00
5:53 PM
Page 705
Chapter 18 ✦ Sound Lingo
Sound Channel Object Handlers sound( chan ).breakLoop( ) sound( chan ).fadeIn( < milliseconds > ) sound( chan ).fadeOut( < milliseconds > ) sound( chan ).fadeTo( volume < , milliseconds > ) sound( chan ).getPlayList( ) sound( chan ).isBusy( ) sound( chan ).isPastCuePoint( inOrString ) sound( chan ).pause( ) sound( chan ).play( ) sound( chan ).playNext( ) sound( chan ).queue( memberOrPlayList ) sound( chan ).rewind( ) sound( chan ).setPlayList( playList ) sound( chan ).showProps( ) sound( chan ).stop( )
Queuing sounds If you’re an experienced Director developer, you’ll have experienced many times sounds not playing as promptly as you had expected, especially on Windows machines. To play sounds quickly, you can queue them. A queued sound responds much more quickly. To queue member 1 and then play it, type the following: sound(1).queue(member(1)) sound(1).play()
As the command name suggests, queue enables you to queue more than one sound. You can queue several sounds and when you tell the object to play, the sounds play consecutively: sound(1).queue(member(1)) sound(1).queue(member(2)) sound(1).queue(member(3)) sound(1).play()
Perhaps at this point the complexity is starting to seem worth the extra work.
705
3486-6 ch18.f.qc
706
7/24/00
5:53 PM
Page 706
Part IV ✦ Controlling Media with Lingo
Creating a playList As you may have noticed from the table, the queue() command also takes a list as a parameter. This list is a linear list of property lists (another reason we spent so much time on lists in Chapter 12!). The sound channel object has many properties. You can view them in the Message window by typing the following: put sound(1).showProps() currentTime: 0.0000 elapsedTime: 0.0000 startTime: 0.0000 loopStartTime: 0.0000 loopEndTime: 0.0000 endTime: 0.0000 loopCount: 1 loopsRemaining: 0 member: preLoadTime: 1500 pan: 0 volume: 255 currentChannel: 1 channelCount: 0 sampleCount: 0 sampleRate: 0 sampleSize: 0 mostRecentCuePoint: 0 status: 0
Of these properties, the following can be used in the playList: ✦ #member: This property is the only mandatory one. It is a reference to a member, such as member(1) or member(“memName”). ✦ #startTime: This is the time the sound will begin to play. The default is 0. ✦ #endTime: This is the time the sound will end. The default is the length of the sound. ✦ #loopCount: This is the number of times you want to play the sound. ✦ #loopStartTime: This is the time the sound will start when it loops. For example, if you specified that a sound should loop three times, and set the #loopStartTime to 1000, the first time the sound plays it will play all the way through, and the subsequent times it will start playing at 1000. The time is measured in milliseconds. If you want all iterations to begin at the same point, you need to set the #startTime to the same value.
3486-6 ch18.f.qc
7/24/00
5:53 PM
Page 707
Chapter 18 ✦ Sound Lingo
✦ #loopEndTime: This is the time within the sound at which a loop ends, in milliseconds. It works the same way as #loopStartTime, except that it specifies the time the sound ends. ✦ #preloadTime: This is the amount of the sound that you want buffered before playback. ✦ #rateShift: This property is not officially supported, but it seems to work well. By using a negative number, you can slow down a sound, lowering its pitch. Entering a positive number speeds up the sound, raising its pitch. These properties you can use in the playList. Before we get to setting the playList, take a look at another way to play a single sound by using a property list. The following sound will be looped three times: sound(1).queue([#member: member 1, #loopCount: 3]) sound(1).play()
The preceding example simplifies our code by not having to queue member 1 three times. If you want to queue multiple sounds in one line of code, you need to set the playList property. The playList property is a linear list composed of property lists like the preceding one. sound(1).setPlayList([[#member: member 1, #loopCount: 3], [#member: member 2]]) sound(1).play()
Using setPlayList() is the only way to set the playList property. There is a corresponding function called getPlayList(), which returns the value of the playList. The playList returned will not include the currently playing sound. The following code shows setting the playList from the Message window and then getting it: sound(1).setPlayList([[#member: member 2], [#member: member 3], [#member: member 4]]) put sound(1).getPlayList() -- [[#member: (member 2 of castLib 1)], [#member: (member 3 of castLib 1)], [#member: (member 4 of castLib 1)]]
Panning sounds Panning a sound is another of the cool new things you can do with a sound channel object. The pan property can be set with a value from –100 to 100 and changed while the sound is playing (unless the channel is doing a fade). A value of –100 plays the sound only from the left speaker, and a value of 100 plays the sound only from the right speaker. A value of 0 is a balance between the two.
707
3486-6 ch18.f.qc
708
7/24/00
5:53 PM
Page 708
Part IV ✦ Controlling Media with Lingo
Figure 18-34 shows a script that pans sound(1) based on the mouse location. For this example, we start sound(1) playing member 3 and loop it 3 times. The closer you move the mouse to the right side of the Stage, the more the sound only plays from the right speaker. As you move the mouse to the center, you hear it from both speakers. As you move the mouse toward the left of the Stage, the sound plays more and more from the left speaker. Figure 18-34: Panning a sound based on the mouse location
Summary Among the things you learned in this chapter are the following: ✦ You can embed sound files in a Director movie and control the sound’s playback by using the Score or the puppetSound Lingo command. ✦ You can also link an external sound file to a Director movie and play back the sound by using the sound playFile command. ✦ You can embed or link either AIFF (.AIF on the Windows platform) sound files or wave (.WAV) files. ✦ Lingo can control the fade-in and fade-out of a sound, adjust the volume, or preload and unload a sound. ✦ Director 8 comes with the Beatnik Lite Xtra, but you must install it manually. ✦ You can queue sounds for fast playback by using the new sound channel object. ✦ The sound channel object enables you to play all or part of sounds. ✦ You can pan a sound between speakers. Our next chapter discusses the control of digital video via Lingo. It includes discussion of QuickTime VR commands.
✦
✦
✦
3486-6 ch19.f.qc
7/24/00
5:53 PM
Page 709
19 C H A P T E R
Video Lingo
D
igital video is one of the many media types that you can import into Director. Unlike static media types, such as text and bitmaps, digital media have the dimension of time. Within Director, a digital video movie need not just play back from beginning to end. Using Lingo, you can make the movie speed up, slow down, go backward, and more. Toward the end of this chapter we’ll approach how the subject of integrating QuickTime VR (QTVR) movies into your Director movie. With Lingo, you can couple the interactivity of a QTVR with your own Director-based interactivity.
✦
Through Lingo, you can get and set the properties of a QuickTime cast member, just as you would in the QuickTime Xtra Properties (see Figure 19-1). If you want to try setting some of these properties, you can open the landingqt.dir movie in the EXERCISE:CH19 (EXERCISE\CH19) folder on the CD-ROM that accompanies this book. Many of the properties apply to the QuickTime member, but some apply to the actual sprite. As you work through this chapter, make sure that the Director movie is playing when you manipulate the settings from the Message window.
✦
✦
In This Chapter Using Lingo to control digital video Creating your own movie controls Using QTVR commands
✦
Using Lingo to Control Digital Video Properties
✦
✦
✦
✦
3486-6 ch19.f.qc
710
7/24/00
5:53 PM
Page 710
Part IV ✦ Controlling Media with Lingo
Figure 19-1: The properties of a QuickTime cast member
Setting the video of member property Remember that, even though you use a digital video clip, you don’t have to display the video portion of the file. Each digital video member has a video property that can be set to 1 or 0 (TRUE or FALSE). Setting the property to 0 disables the display of video for that member. This can be helpful when you want to use a sound-only QuickTime movie in your project. To disable the display of video, use a statement similar to this: set the video of member “landing” to 0 -- or dot notation member(“landing”).video = 0
To enable the display of video from a digital video cast member, use a statement similar to this: set the video of member “landing” to 1 -- or dot notation member(“landing”).video = 1
The 1 and 0 values in the preceding examples can be replaced with TRUE and FALSE, respectively. This convention is consistent throughout Lingo. Using numeric values requires less typing, but the TRUE and FALSE keywords are more English-like and clearer to the casual Lingo reader. In the next two examples, we’ll use the TRUE/ FALSE keywords. If you have a QuickTime movie sprite and you set the video to FALSE and the directToStage property is TRUE, it appears that the movie has stopped, but
3486-6 ch19.f.qc
7/24/00
5:53 PM
Page 711
Chapter 19 ✦ Video Lingo
in actuality, the screen just needs to be refreshed. To do this, use the following after setting the video to FALSE: set the stageColor to the stageColor -- or the stageColor = the stageColor Note
If directToStage is set to FALSE, this refreshing is not necessary.
Setting the sound of member property Just as you might want to play a digital video clip without the video, so might you want to skip the sound portion of the file and play only the video. Digital video has a sound property, which can be set to 1 or 0 (TRUE or FALSE). Setting the property to 0 will disable the sound for a video member. The following statement disables the sound in a digital video cast member: set the sound of member “landing” to FALSE -- or dot notation member(“landing”).sound = FALSE
This code enables the sound in a digital video cast member: set the sound of member “landing” to TRUE -- or dot notation member(“landing”).sound = TRUE
Pausing at the beginning of a video using Lingo You can pause a digital video cast member on its first frame (which means you must use Lingo to play, rewind, and stop the video clip). This has the same effect as selecting the Paused check box option in the Properties dialog box. The following statement sets this property: set the pausedAtStart of member “landing” = TRUE -- or dot notation member(“landing”).pausedAtStart = TRUE
This statement turns off the property: set the pausedAtStart of member “landing” = FALSE -- or dot notation member(“landing”).pausedAtStart = FALSE
711
3486-6 ch19.f.qc
712
7/24/00
5:53 PM
Page 712
Part IV ✦ Controlling Media with Lingo
Setting the loop of member property The following example statements show you how to cause a video clip to automatically loop and replay: set the loop of member “landing” to TRUE -- or dot notation member(“landing”).loop = TRUE
Here’s how to turn off the automatic looping of a video clip: set the loop of member “landing” to FALSE -- or dot notation member(“landing”).loop = FALSE
Cropping and centering video using Lingo Setting the crop of a member to TRUE means that if the rect of the sprite is smaller than the rect of the member, it does not scale it to fit. The movie only shows what fits within the rect. If the crop is set to FALSE, and the sprite’s rect is smaller than the movie, then the image is scaled to fit the rect of the sprite. The following statements show you how to enable a resized video clip to be cropped: set the crop of member “landing” to TRUE -- or dot notation member(“landing”).crop = TRUE
To disable the cropping of a resized video clip, use this code: set the crop of member “landing” to FALSE -- or dot notation member(“landing”).crop = FALSE
To center a cropped video clip within its resized bounding box, use a statement similar to the following: set the center of member “landing” to TRUE -- or dot notation member(“landing”).center = TRUE
To disable this centering for the cropped video clip, use this type of statement: set the center of member “landing” to FALSE -- or dot notation member(“landing”).center = FALSE
3486-6 ch19.f.qc
7/24/00
5:53 PM
Page 713
Chapter 19 ✦ Video Lingo
Playing a video direct to the Stage using Lingo When working with QuickTime video on a Macintosh computer system, you can cause the digital video to be displayed direct to the Stage. In the following statement, we do this with a QuickTime video named landing: set the directToStage of member “landing” to TRUE -- or dot notation member(“landing”).directToStage = TRUE
Here’s the statement to turn off this property: set the directToStage of member “landing” to FALSE -- or dot notation member(“landing”).directToStage = FALSE
Remember that directToStage being set to TRUE draws the movie over any other sprite, even ones in higher sprite channels. This gives the best performance for the movie. If you need sprites to appear over the movie, set directToStage to FALSE. This setting reduces the performance of the movie’s playback and may adversely affect how smoothly the movie plays, especially on slower computers.
Displaying a controller using Lingo You can use Lingo to display or hide a controller when using QuickTime movies on either the Windows or Macintosh operating system. To display the digital video controller, use the following code: set the controller of member “landing” to TRUE -- or dot notation member(“landing”).controller = TRUE
To hide the digital video controller, do the following: set the controller of member “landing” to FALSE -- or dot notation member(“landing”).controller = FALSE
Establishing the frame rate for digital video using Lingo The frameRate of member property establishes the frame rate at which a digital video cast member plays. The settings you establish with this property correspond to the settings in the Rate and fps boxes in the Properties dialog box. These settings are available only if you elect to play every frame, as opposed to selecting the Sync to SoundTrack option. When the Rate field is set to Fixed, Director uses the value in the fps field to establish the frame rate.
713
3486-6 ch19.f.qc
714
7/24/00
5:53 PM
Page 714
Part IV ✦ Controlling Media with Lingo
To set these values using Lingo, you can use a statement similar to this: set the frameRate of member “landing” to 30 -- or dot notation member(“landing”).frameRate = 30
When you set the frame rate to a value between 0 and 255, Director equates this with a Fixed setting in the Rate field and assumes that the numeric value is for frames per second. Although the frameRate of member property can range up to 255, in most cases, you only use values in the 10 to 30 fps range. You can also use the frameRate of member property to set the selection to the Normal rate setting in the Properties dialog box by using this statement: set the frameRate of member “landing” to -1 -- or dot notation member(“landing”).frameRate = -1
Another option is to use the frameRate of member property set to the Maximum rate setting in the Properties dialog box, which plays every frame as fast as possible, by using the following statement: set the frameRate of member “landing” to -2 -- or dot notation member(“landing”).frameRate = -2
Enabling the preload of video using Lingo The following statement enables a video clip to be preloaded into memory: set the preLoad of member “landing” to TRUE -- or dot notation member(“landing”).preLoad = TRUE
This statement disables the preload: set the preLoad of member “landing” to FALSE -- or dot notation member(“landing”).preload = FALSE
Using Lingo to Create Other Controls Although you can show the QuickTime controller, there may be times when you want to create your own controls. Creating your own controls enables you to decide what the interface looks like. It also enables you to decide what elements
3486-6 ch19.f.qc
7/24/00
5:53 PM
Page 715
Chapter 19 ✦ Video Lingo
you want in your interface. More importantly, you can add controls that are not in the QuickTime controller’s interface. If you didn’t open it earlier, open the movie landingqt.dir. You can add functionality to the movie’s buttons, which are shown in Figure 19-2. Before leaping into the code, let’s consider the problem. There are eight buttons. What should they do? ✦ Rewind: Rewinds the video ✦ Backward: Plays the video quickly in reverse ✦ Stop: Stops the video ✦ Play: Plays the video ✦ Forward: Plays the video quickly forward Figure 19-2: Creating your own interface for a QuickTime sprite
These first five buttons all work together. If one is activated, the others are deactivated. You need to consider this in your code. They should stay deactivated until one of the others is clicked. The next button is the Sound button. It should light up when the sound is on. It should also toggle the state of the sound when it is clicked. Finally, there are the Volume up and Volume down buttons. They need to increase and decrease the sound, respectively. They should check when they are within the 0 to 255 bounds of the volume, to prevent it from being distorted[GSL1]. These buttons only become highlighted when clicked.
715
3486-6 ch19.f.qc
716
7/24/00
5:53 PM
Page 716
Part IV ✦ Controlling Media with Lingo
Creating the toggle behavior Already included in the movie is a go to the frame behavior and the B_button state change behavior from Chapter 18. Toggling the button state is very similar, so it is easier to just duplicate the B_button state change behavior and modify it by following these steps: 1. Select member 2 (B_button state change) and choose Edit ➪ Duplicate. 2. Open the duplicated member (member 3 in the cast). 3. Delete the mouseUp and mouseUpOutside handlers. 4. Change the mouseDown handler and add the Toggle handler, as shown in Figure 19-3.
Figure 19-3: Making a toggle behavior
The Toggle message is sent when the sprite is clicked. It is sent to all sprites, along with the sprite number of the sprite clicked. The Toggle handler compares the who parameter with its spriteNum. If the sprite is clicked, it sets its member to the down state. If it is not, it sets its member to the up state. Apply this behavior to the first five buttons.
Rewinding the video To rewind a QuickTime sprite, you need to change two properties. The first is the movieRate; the movieRate is how fast the movie is going. Because we want the movie to stop after it is rewound, it needs to be set to 0. The movieTime of a QuickTime sprite is the time index of where it is in the movie. We want it to be at the beginning, so it needs to be set to 0 as well.
3486-6 ch19.f.qc
7/24/00
5:53 PM
Page 717
Chapter 19 ✦ Video Lingo
Create a new behavior, as shown in Figure 19-4. The QuickTime video is in sprite 10. Apply this behavior to the Rewind button. Tip
For the sake of clarity, we use the literal 10 in all of the behaviors that follow. If we were doing this in a real project, we’d probably use a movie script function to return the value instead of explicitly putting the number in ten different scripts. This would make changes easier. Using a global is another option, but then you also need to declare it wherever you use it.
Figure 19-4: The Rewind behavior
Fast Forward and Reverse Fast forward and reverse are essentially the same behavior; the only difference is whether you are setting the movieRate to a positive or a negative. Setting the movieRate to 3, as shown in Figure 19-5, makes the movie play at three times normal speed.
Figure 19-5: The Fast Forward and Reverse behaviors
Create the behaviors as shown in Figure 19-5. Apply B_fast forward to the Fast Forward button. Apply B_fast reverse to the reverse button.
717
3486-6 ch19.f.qc
718
7/24/00
5:53 PM
Page 718
Part IV ✦ Controlling Media with Lingo
Playing and stopping the video Playing and stopping a video sprite is a simple matter of setting the movieRate to 1 or 0. Create two behaviors as shown in Figure 19-6. Apply B_play to the Play button and B_stop to the Stop button.
Figure 19-6: The Play and Stop behaviors
Turning the sound on and off The green circle on the interface indicates whether the sound is ON or OFF. Create the behavior shown in Figure 19-7 and apply it to the Sound button. This script constantly polls the sound property of member “landing” and sets the member accordingly. The mouseDown simply toggles the value returned by the sound of member property by using the not keyword.
Figure 19-7: The Sound button behavior
3486-6 ch19.f.qc
7/24/00
5:53 PM
Page 719
Chapter 19 ✦ Video Lingo
Another way to achieve the same result is to change the member only once, on the mouseDown, as shown in Figure 19-8. This might seem more efficient than Figure 19-7, but you won’t notice any speed difference. Director is very smart in setting the member of a sprite; if the member is already there, you get no speed hit by trying to set it again. The other thing you need with this method is a beginSprite handler to set the initial value. A beneficial side effect of the version in Figure 19-7 is that if some other script changes the sound of the member, the button still lights up. The script in Figure 19-8 would not be aware of the change.
Figure 19-8: Changing the member of the sprite in the mouseDown handler
Changing the volume of a QuickTime sprite Digital video uses the volume of sprite property to control the sound level of the sound track. You can set the volume of sprite to any value between 0 and 255, but any value lower than 1 mutes the sound. The following statement sets the volume at its highest level (you can set the volume higher than 255, but doing so distorts the sound): Set the volume of sprite 10 to 255 -- or dot syntax sprite(10).volume = 255
Create the behaviors shown in Figure 19-9. Apply each behavior to the appropriate button. You also need to apply the B_button state change behavior to each of these buttons so that they are highlighted when clicked.
719
3486-6 ch19.f.qc
720
7/24/00
5:53 PM
Page 720
Part IV ✦ Controlling Media with Lingo
Figure 19-9: The volume-changing behaviors
That about does it! Now save the movie as landingqt2.dir and play it.
Track-related Lingo QuickTime movies are made up of different tracks. Those tracks could be #video, #sound, #sprite, #music, and #text. To count the number of tracks in a movie, use the trackCount() function, as follows: put trackCount (member “landing”) -- 3 -- or dot notation put member(“landing”).trackCount -- 3
After knowing the number of tracks, you can learn what type they are, as follows: put trackType(member “landing”, 1) -- #video put trackType(member “landing”, 3) -- #sound -- or dot notation put member(“landing”).trackType(1) -- #video put member(“landing”).trackType(3) -- #sound
The trackCount() and trackType() functions work for both members and sprites.
3486-6 ch19.f.qc
7/24/00
5:53 PM
Page 721
Chapter 19 ✦ Video Lingo
As shown earlier, you are able to turn the video and sound of a member ON and OFF. Having knowledge of the tracks gives you even more control. Using setTrackEnabled, you can turn individual tracks ON and OFF, as shown here: setTrackEnabled(sprite 10, 1, FALSE) -- or dot notation (sprite 10).setTrackEnabled(1, FALSE)
This code turns the video track off for the QuickTime movie in sprite 10. This property has the same effect as setting the video of a QuickTime member to FALSE, for that particular track. Tracks can be varying lengths of time. Using trackStartTime() and trackStopTime(), you can get this information from either sprites or members, as follows: put trackStopTime(member “landing”, 1) -- 1788 put trackStopTime(sprite 10, 2) -- 2072 -- or dot notation put member(“landing”).trackStopTime(1) -- 1788 put (sprite 10).trackStopTime(10, 2) -- 2072
The trackNextKeyTime() and trackPrevKeyTime() functions return a value indicating the next and previous keyframes for a sprite. The trackNextSample Time() and trackPrevSampleTime() functions return the next and previous samples of a track. The return values for all four of these functions are determined by the digitalVideoTimeScale — a system property used to measure digital video members. The value for this property is the number of units per second, the default being 60.
Masking a QuickTime sprite A QuickTime member can have a 1-bit mask applied to it. This enables you to have the speed benefit of running the movie direct-to-Stage, yet have a nonrectangular shape. When creating a mask bitmap, it is important to note that a QuickTime member has its registration point in the upper-left corner. Just as setting the video of member to FALSE can leave an artifact on the screen, setting the mask while a sprite of the member is on the screen can have a similar effect. The mask should be set before the sprite appears on the Stage or, if after it is on the Stage, setting the stageColor to the stageColor refreshes the Stage. To set the mask, type the following: set the mask of member “landing” to member “qtmask” set the stageColor to the stageColor
721
3486-6 ch19.f.qc
722
7/24/00
5:53 PM
Page 722
Part IV ✦ Controlling Media with Lingo
-- or dot notation member(“landing”).mask = member(“qtmask”) the stageColor = the stageColor
To clear it, just set it to 0, as shown here: set the mask of member “landing” to 0 -- or dot notation member(“landing”).mask = 0
You can invert the mask by setting the invertMask property to TRUE, as in the following: set the invertMask of member “landing” to TRUE -- or dot notation member(“landing”).invertMask = TRUE
QuickTime VR You can control QuickTime VRs through Lingo, just as you can control normal QuickTime videos. Open the movie qtvr.dir, shown in Figure 19-10, to experiment with the commands as you work through the chapter. It is in the EXERCISE:CH19 (EXERCISE\CH19) folder on the accompanying CD-ROM.
Figure 19-10: The qtvr.dir movie displaying a QuickTime VR sprite
The first thing to try is testing whether the member is a QTVR. A QuickTime member might or might not be a QTVR. You can use the isVRMovie property to test this, as follows: put the type of member 1 -- #quickTimeMedia
3486-6 ch19.f.qc
7/24/00
5:53 PM
Page 723
Chapter 19 ✦ Video Lingo
put the isVRMovie of member 1 -- 1 -- or dot notation put member(1).type -- #quickTimeMedia put member(1).isVRMovie -- 1
As was shown with the QuickTime movie earlier, an interface can be created for a QTVR as well. Unlike a QuickTime movie, a QTVR expects you to interact with it by using the mouse. QTVRs already have nicely designed cursor feedback, but if you want to override that control, you can set the mouseLevel property of the sprite. The mouseLevel has four possible values: ✦ #shared: The default. Passes all mouse clicks to QuickTime and Director (in that order). ✦ #all: All mouse clicks are passed to QuickTime. ✦ #none: None of the mouse clicks are passed to QuickTime. ✦ #controller: Only mouse clicks on the sprite’s controller are not passed to Director. If you want to take control of the interaction with Lingo, you probably would want to set the mouseLevel of the sprite to #none. Then you would need to write the code to enable interaction with the QTVR.
Viewing commands The pan, tilt, and fieldOfView properties enable you to change your view of the VR. ✦ Setting pan moves your view left or right. ✦ Setting tilt moves your view up and down. ✦ Setting fieldOfView moves your view in and out. The value of each is in degrees. In the Message window, put each of these properties: put the pan of sprite 1 -- 90.0000 put the tilt of sprite 1 -- 2.7000 put the fieldOfView of sprite 1 -- 64.2813 -- or dot notation put (sprite 1).pan
723
3486-6 ch19.f.qc
724
7/24/00
5:53 PM
Page 724
Part IV ✦ Controlling Media with Lingo
-- 90.0000 put (sprite 1).tilt -- 2.7000 put (sprite 1).fieldOfView -- 64.2813
These are the default values for this particular QTVR. Now try changing them as shown in Figure 19-11.
Figure 19-11: The view after the pan, tilt, and fieldOfView properties were changed.
Rewind the movie so that the sprite returns to its defaults. Play the movie, and in the Message window, type the following: swing(sprite 1, 180, 0, 40, 5) -- or dot notation (sprite 1).swing(180, 0, 40, 5)
Cool, huh? The view automatically “swings” to the position you specified. The first four arguments to the preceding swing() command you should recognize as the sprite, pan, tilt, and fieldOfView that you manually set moments ago in the Message window. The fifth argument is the speed it moves to the new position. Possible speed values are 1 to 10. If you need to just move the image slightly, you can use the nudge command. You can nudge in eight directions, as in the following example: nudge(sprite 1, #up) -- or dot notation (sprite 1).nudge(#up)
Values for nudging are #up, #down, #downLeft, #downRight, #left, #right, #upLeft, and #upRight.
3486-6 ch19.f.qc
7/24/00
5:53 PM
Page 725
Chapter 19 ✦ Video Lingo
Image quality You can change the quality of the sprite for the QTVR sprite while it is moving or while it is still. The motionQuality property can be set to #minQuality, #maxQuality, or #normalQuality. Lower qualities animate more quickly. You can change the quality of the image while it is not moving by using the static Quality property. It has the same values as motionQuality: #minQuality, #max Quality, and #normalQuality. Have you ever noticed how QTVRs antialias when you stop dragging them? It seems like that is a common default. You can force the QTVR to antialias as it is dragged by setting motionQuality to #maxQuality. Or you can have it not be antialiased when it is stopped by setting the staticQuality to #minQuality. You can change the amount of warping by setting the warpMode property. Possible values are #full, #partial, and #none.
Nodal VRs Several QTVRs can be put together into one QuickTime movie. These movies are linked together. Each one is referred to as a node. To get from one node to another, the author of the VR defines hotspots. Open the movie nodal.dir (shown in Figure 19-12). You can find it in the EXERCISE: CH19 (EXERCISE\CH19) folder on the accompanying CD-ROM. This movie is four QTVRs bundled together. By clicking one of the three screens, you enter one of three QTVRs.
Figure 19-12: A nodal QuickTimeVR movie
725
3486-6 ch19.f.qc
726
7/24/00
5:53 PM
Page 726
Part IV ✦ Controlling Media with Lingo
The sprite in nodal.dir movie has four nodes numbered 127, 128, 129, and 130. You can get the value of the node you are in with the node property, but you cannot set it: put the node of sprite 1 -- 127 -- or dot notation put (sprite 1).node -- 127
The numbers represent these nodes: 127 is the main node; 128 is Viking Lander; 129 is Terraforming; and 130 is Olympus Mons. You cannot get the names of nodes. We hope this will change in a future version of Director. You can determine the type of node with the nodeType property. Possible values are #panorama, #object, and #unknown. #unknown means that the sprite isn’t a QTVR. Use this property as follows: put the nodeType of sprite 1 -- #panorama -- or dot notation put (sprite 1).nodeType -- # panorama
You can have a handler execute when you enter or exit a node, enter or exit a hotspot, or when you click a hotspot. Look at the behavior in Figure 19-13. The behavior sets the properties: the triggerCallback, the nodeEnterCallback, the nodeExitCallback, the hotSpotEnterCallback, and the hotSpotExitCallback. The values for these properties are symbols that correspond to the names of handlers in the behavior. Through the use of callbacks, you can respond to the user’s interactions with the QTVR, or you can just track their movements through it. Here is the output for a short session we just did: ---------
“Entered hotspot 218” “Triggered by hotspot 218” “Exited node 127” “Entered node 130” “Exited hotspot 218” “Entered hotspot 183” “Triggered by hotspot 183” “Exited node 130”
3486-6 ch19.f.qc
7/24/00
5:53 PM
Page 727
Chapter 19 ✦ Video Lingo
Figure 19-13: A behavior to demonstrate QTVR callbacks
With this information, you know exactly which nodes we visited. If there were multiple paths to the nodes, you would know which path we used, based on the hotspots we triggered.
More hotSpot commands If you’ve created a game using QTVRs, you might want to selectively enable and disable hotspots. You can do this with the enableHotSpot command, as shown here: enableHotSpot(sprite 1, 59, FALSE) -- or dot notation (sprite 1).enableHotSpot(59, FALSE)
HotSpot 59 is the one that leads to the Viking Lander. When you roll over that monitor, your cursor no longer changes; you are not able to enter that node. You can also get the rect of a hotspot. The rect is the coordinates of where that hotspot is on the Stage at the moment in time when you check it. Rewind the movie and type the following: put getHotSpotRect(sprite 1, 59) -- rect(86, 77, 299, 234) -- or dot notation
727
3486-6 ch19.f.qc
728
7/24/00
5:53 PM
Page 728
Part IV ✦ Controlling Media with Lingo
-- (sprite 1).getHotSpotRect(59) -- rect(86, 77, 299, 234)
Move down and to the right and get the hotspot’s rect again, as follows: put getHotSpotRect(sprite 1, 59) -- rect(0, 28, 154, 184) -- or dot notation put (sprite 1).getHotSpotRect(59) -- rect(0, 28, 154, 184)
If you had a sprite interacting with the hotspot, you would know exactly where to put it with this command. A convenient function is ptToHotSpotID. With this function, you can find out whether a point is within a hotspot. Although you could easily write a function to do this, given the getHotSpotRect, it is nice that you don’t have to. Write the following code: put ptToHotSpotID(sprite 1, the mouseLoc) -- 59 -- or dot notation put (sprite 1).ptToHotSpotID(the mouseLoc) -- 59
If it returns 0, then the point (in this case, the mouseLoc) is not within a hotspot.
Summary In this chapter, you learned the following: ✦ You can import QuickTime movies into Director. ✦ Lingo can control the playback of a QuickTime movie. ✦ QTVRs are another type of QuickTime movie that can be manipulated through Lingo. ✦ You can assign functions that execute as the user interacts with a QTVR. In the next chapter, we discuss troubleshooting your code.
✦
✦
✦
3486-6 ch20.f.qc
7/24/00
5:53 PM
Page 731
20 C H A P T E R
Lingo Troubleshooting
✦
✦
✦
✦
In This Chapter
H
ave you ever had a really bad code day? If not, you will. When that happens, Director includes a variety of builtin troubleshooting tools. Paraphrasing two common themes, it’s important to realize that “bad things happen to good programmers” and “where your problem is (in the script) is where you can fix it.” Programming errors happen to everyone. Director helps by ✦ Alerting you to syntax errors when you close the Script window ✦ Providing troubleshooting tools — the Watcher window, breakpoints, and the Debugger window — to help you locate errors in logic
Tracing script actions in the Message window Executing instructions and handlers in the Message window Tracking variables in the Watcher window Checking handlers by using the Debugger window
✦
Troubleshooting Your Scripts When your Lingo script does not work the way you expect it to, the first thing to do is to identify the problem. What is it that is not working the way you expected? Is a button click not playing a sound? Is the movie not branching to the correct frame? Does the movie quit unexpectedly? If you are working on a team project, read and understand the comments inserted by the other team programmers. If you are writing Lingo script as part of a team effort, make sure you are adequately commenting your own scripts. Valuable time is wasted when you or someone else must decipher the scripts from scratch.
✦
✦
✦
3486-6 ch20.f.qc
732
7/24/00
5:53 PM
Page 732
Part V ✦ Further into Lingo
Troubleshooting involves three techniques that are useful when identifying and solving problems within your coding. Director provides tools to help you with each technique. The techniques are: ✦ Locating the problem ✦ Identifying syntax and spelling errors ✦ Correcting errors of logic Each technique, discussed in the following sections, brings you closer to creating bug-free, efficient code.
Locating the problem Sometimes finding the problem really means locating where the problem begins. The debugging tools provided by Director can assist you in locating the origin of the problem. For example, watching the frames as they are executed in the Message window can be helpful. You can also execute Lingo scripts from the Message window to learn whether the problem resides in a particular script. Asking the following questions will help: ✦ Does the problem occur only on specific computers or only on computers with certain display settings? ✦ Is the error occurring with a sprite and the way it displays? ✦ Is the error occurring only with certain keystrokes or combination of keystrokes?
Identifying syntax and spelling errors The most common Lingo error occurs when you mistype a command or use the wrong syntax for a command or property. Each time you close the Script window, Director automatically looks for syntax errors or errors resulting from misspelling a word. For example, if you type the following command in a script and close the Script window, you get the error message shown in Figure 20-1. set the visible of sprte 6 to TRUE
Figure 20-1: A script error message
3486-6 ch20.f.qc
7/24/00
5:53 PM
Page 733
Chapter 20 ✦ Lingo Troubleshooting
The error message offers Director’s view of the potential problem. In this case, Director assumes sprte is a variable holding a reference to something, a sprite reference such as (sprite 1), a child object, or perhaps a property list, which might have the visible property. That being the case, right after the variable, there should be the word to, but instead an integer is there. Director is confused and puts a question mark after the part that confuses it. Get rid of the 6, and try it again in the Message window, as follows: set the visible of sprte to TRUE
We get the error notification shown in Figure 20-2.
Figure 20-2: A slightly more helpful script error message
Now we can see why Director wanted the to instead of the 6. It thinks our misspelling of the word sprte was actually a variable. Note
Director’s capabilities do not include the intelligence to recognize that a simple misspelled word is the problem, as opposed to the error of a variable’s being used before it is assigned a value. When debugging a script, your job is to examine the error message and interpret it in the context of the remainder of the Lingo script.
Checking for spelling errors When checking for syntax errors (the most frequent type of error), you should always check the spelling of commands, functions, and properties. Be sure that variable names are used consistently and that spaces and punctuation marks are included when necessary. Director can only respond to your script as you typed it, not as you intended to type it.
Checking for missing quotation marks Another common syntax error results when you omit quotation marks. Make sure you’ve used the required quotation marks (“ “) around the names of cast members, markers, and strings.
733
3486-6 ch20.f.qc
734
7/24/00
5:53 PM
Page 734
Part V ✦ Further into Lingo
Checking for missing command parameters Lingo commands, properties, and other instructions might need required parameters in order for Lingo to know how to interpret the instruction. Always check for missing parameters or arguments that are required by a command or instruction.
Checking for the correct command syntax When you are not sure of a Lingo command’s syntax and required parameters, there are three tools available to assist you: the Alphabetical Lingo button, the Categorized Lingo button, and the Director Help command. Note
The Alphabetical Lingo and Categorized Lingo buttons are available on the Script window toolbar (see Figure 20-3) and in the Message window toolbar.
Alphabetical Lingo Categorized Lingo
Figure 20-3: Two tools in the Script window, the Alphabetical Lingo button and the Categorized Lingo button, help you with Lingo syntax.
Place the cursor at the location in your script where you want to use the command, and click the Alphabetical Lingo button. Search the list to locate the desired command. Select it and the command’s correct syntax and placeholders for required parameters are added to the Script. The command is added to the Script window at the current location of the insertion point. The Categorized Lingo pull-down list works the same way as the Alphabetical list. Search the groups of commands (for example, Navigation, Network, User Interaction) to locate the desired command. When you locate the command and select it, the command’s correct syntax and placeholders for required parameters are added to the Script. The command is added to the Script window at the current cursor location. The third tool for fixing your Lingo syntax is Director’s online help. The online help has many useful topics and the entire Lingo dictionary in electronic form.
3486-6 ch20.f.qc
7/24/00
5:53 PM
Page 735
Chapter 20 ✦ Lingo Troubleshooting
Correcting errors of logic Always remember the Script window’s closing without displaying an Alert window is no guarantee that your Lingo script is error free. It only indicates that the syntax checker did not locate or recognize errors in your script. As a parallel, consider that a word processor’s spelling checker classifies a word as misspelled if the word is not contained in the speller’s dictionary file. Proper names, even when they’re spelled correctly, are often flagged as misspelled. The spelling checker only highlights words it does not find in its dictionary file. Any word not found is flagged as possibly incorrect. The syntax checker in Director operates on a similar principle. It can only locate problems that appear to violate the patterns established in Lingo’s rules file. The syntax checker that works with the Script window can identify syntax errors, but it cannot identify errors of logic. Logic errors result when you assign incorrect values to variables or parameters. The Lingo command that uses or assigns values to a variable might be absolutely correct in its syntax, yet the value stored by the variable might still be the problem. To troubleshoot errors of logic requires that you step through each line of code, in the order they are executed, and look for unexpected results that in turn play havoc with your program. This process can be very complex, because variables might store different values (or strings) depending on which events and actions occur as the movie plays. To tackle errors of logic, you can use Director’s Message window (with its set of debugging buttons), the Debugger window, and the Watcher window.
Debugging in the Message Window The first line of defense against most script problems is to use the Message window. To open the Message window, choose Window ➪ Message, or press Command+M (Ctrl+M). You can use the Message window to observe the instructions contained in the handlers of a movie as it plays. The debugging buttons on the Message window’s toolbar, identified in Figure 20-4, provide access to debugging tools. Each button, along with its function, is listed in Table 20-1. Some of these buttons are also available in the Script window and the Debugger window. Each of these troubleshooting tools gives you access to fix-it features within Director. As you create scripts in Director, you’ll probably find that the most useful tools are the Alphabetical Lingo and Categorized Lingo buttons. With both, you can type an instruction in the Message window and observe Director’s reaction to the command in the Message window or on the Stage.
735
3486-6 ch20.f.qc
736
7/24/00
5:53 PM
Page 736
Part V ✦ Further into Lingo
Alphabetical Lingo Categorized Lingo Trace
Watch expression Go to handler Figure 20-4: Message window’s debugging buttons
Table 20-1 Lingo Troubleshooting Tools Button Name
Function and Purpose
Location
Alphabetical Lingo
Displays an alphabetical listing of all Lingo commands. Locate the desired command on the menu and select it to insert the command and placeholders for all required parameters.
Message window and Script window
Categorized Lingo
Displays a list of all Lingo commands, sorted by function. Locate the desired command on the menu and select it to insert the command and placeholders for all required parameters.
Message window and Script window
Trace
Toggles ON/OFF the display of currently executing Lingo scripts.
Message window
Go To Handler
Opens the Script window and displays the handler referenced in the current instruction. Places the insertion point at that location in the script.
Message window and Debugger window
Watch Expression
Adds the currently selected variable or expression to the “watch list” tracked by the Watcher window.
Debugger window, Message window, and Script window
3486-6 ch20.f.qc
7/24/00
5:54 PM
Page 737
Chapter 20 ✦ Lingo Troubleshooting
In the following steps, you use the Message window to trace the execution of commands in a movie and to locate a logic error. Using the Trace button, you can watch the execution of all instructions (in any script) as they are displayed in the Message window. In its current state, the movie includes a button (cast member 1), a field (cast member 2), two behaviors (cast members 3 and 4), and a movie script (cast member 5). The Count to 10 button has a behavior attached to it. The behavior is stored in cast member slot 4. On the CD-ROM
You can find the file counter.dir on your companion CD-ROM in the EXERCISE:CH20 (EXERCISE\CH20) folder.
Tracing Script Actions in the Message Window 1. Open the file counter.dir in Director. Open the Cast window and examine the cast members. Then open the Message window (press Command+M or Ctrl+M). 2. Click the Trace button in the Message window, identified in Figure 20-4. This turns on the Trace function. 3. Arrange the open Cast window and Message window so that you can see the field (cast member 2) and the Count to 10 button on the Stage. 4. Use the Play button on the toolbar to play the movie. The movie stops almost immediately and displays the error message shown in Figure 20-5. In addition to the error, the Message window shows the last instruction executed before the movie stopped. And the three buttons at the bottom are for opening the Debugger window (discussed later), opening the Script window so you can correct the error, and closing the Script Error message box.
Last instruction executed
Opens script window Opens debugger window Figure 20-5: The “Cast member not found” script error message
737
3486-6 ch20.f.qc
738
7/24/00
5:54 PM
Page 738
Part V ✦ Further into Lingo
5. Click the Script button. When the Script window opens, examine the script and try to identify any errors or problems. If you don’t see anything obvious, don’t worry. Just close the Script window. Director now closes the window without issuing a syntax-error warning; this indicates that the problem is not related to a syntax error in the script. The real problem is that the script refers to a cast member (“number”) that does not exist. 6. Select the field cast member (slot 2) in the Cast window, click in the Name field, and type number. Press Enter to apply the new cast member name to the field. 7. Save the movie as counter1.dir. 8. Leave the Message window open and play the movie. As soon as you start the movie, go to the frame instructions scroll down the Message window. 9. Click the Count to 10 button, and you should notice that each instruction from script cast member 4 is displayed in the Message window after you click the button and while the movie plays. 10. Stop the movie. 11. Use the Message window scroll bar to scroll back to the point where you clicked the Count to 10 button. Now let’s examine the results. At the point where you click the Count to 10 button, the Message window displays the following information. The Message window constantly updates the value of the variable gCounter. At each step, you can examine the program’s flow and see which handler and instructions are executed. Note the first few cycles (as the gCounter variable is incremented from 0 to 3): == Script: (member 4 of castLib 1) Handler: mouseUp --> gCounter = 0 == gCounter = 0 --> repeat while gCounter < 11 --> member(“number”).text = string(gCounter) --> gCounter = gCounter + 1 == gCounter = 1 --> end repeat --> repeat while gCounter < 11 --> member(“number”).text = string(gCounter) --> gCounter = gCounter + 1 == gCounter = 2 --> end repeat --> repeat while gCounter < 11 --> member(“number”).text = string(gCounter) --> gCounter = gCounter + 1 == gCounter = 3
3486-6 ch20.f.qc
7/24/00
5:54 PM
Page 739
Chapter 20 ✦ Lingo Troubleshooting
If you scroll back to the beginning of the Message window listings, you see text similar to this: == Movie: Mac HD:desktop stuff:CH20:COUNTER1.DIR Frame: 1 Script: (member 5 of castLib 1) Handler: startMovie --> gCounter = 0 == gCounter = 0 --> member(“number”).text = string(gCounter) --> end == Script: (member 3 of castLib 1) Handler: exitFrame --> go to the frame --> end
The Message window lists the path to the movie, the frame number, the location of the script that is executing [in the form of a member reference: (member 5 of castLib 1)], and then the name of the handler executing. After the on startMovie handler finishes (which establishes the initial value of the variable gCounter and places it in the number field), the cast member script 3 with an on exitFrame handler runs. It includes a go to the frame instruction.
Testing commands directly in the Message window You can also type and test scripts in the Message window (you have already done this in earlier chapters). The Message window enables you to prototype and test specific instructions to determine if the actual results match your anticipated results. ✦ To test a single line of code that you suspect might be causing a problem, type it directly into the Message window. If the command works in the Message window, some other part of your program must be causing the error. ✦ To test a handler in the Message window, type the name of the handler and press Enter. The handler is immediately executed, and if any errors occur, an Alert message displays. On the CD-ROM
You can find the file change.dir on your companion CD-ROM in the EXERCISE: CH20 (EXERCISE\CH20) folder.
Executing Instructions and Handlers in the Message Window 1. Open the change.dir movie. 2. In the Message window, click the Trace button to turn off the Trace feature. 3. In the Message window, type the following: set the visible of sprite 1 to FALSE
Press the Enter key. The button (sprite 1) disappears.
739
3486-6 ch20.f.qc
740
7/24/00
5:54 PM
Page 740
Part V ✦ Further into Lingo
4. Type the following: set the visible of sprite 1 to TRUE
Press the Enter key. The button reappears. 5. The movie also has another handler in cast member 50, named on change. In the Message window, type change and press Enter. The script error message shown in Figure 20-6 appears. Figure 20-6: The “Not a field cast member” script error message.
6. Click the Script button in the error box. Three lines in the script refer to field 3. Because there is a mismatch between the type of cast member in slot 3 and the type of cast member specified in the command (field), you must change the instruction. 7. Change all three references in the on change handler from field 1 to field 2. 8. Close the Script window, and save the movie as change1.dir. 9. Type change in the Message window again and press Enter. Director displays a script error indicating that an integer (whole number) is expected, as shown in Figure 20-7. The word “purple” in the script is listed as the culprit. The foreColor property must be set by using a numeric value (not a color name) that represents the color in the current palette. Figure 20-7: The “Integer expected” script error message
10. In the error box, click the Script button to open the Script window. 11. Delete the word purple and the double quotation marks that surround it. Change the instruction to read as follows: set the forecolor of field 2 to 54
3486-6 ch20.f.qc
7/24/00
5:54 PM
Page 741
Chapter 20 ✦ Lingo Troubleshooting
Note
The color 54 is purple when using either the System-Win or the System-Mac palette.
12. Close the Script window, and save the movie again as change1.dir. 13. In the Message window, execute the on change handler by typing change and pressing Enter. The number 0 increases in size, switches to purple, and changes to an italic font style.
Using the showGlobals command Another useful purpose for the Message window is to display variables that are currently available as globals. This can be helpful in your debugging efforts for two reasons: ✦ You might expect a variable to be global and it is not (that is, you did not declare it as a global variable). ✦ You want to know the value currently stored by a global variable. To determine which variables are currently declared as globals, you open the Message window and type showGlobals. You get a list of all current global variables, as in this example: gName = “John” gAge = 34 showGlobals -- Global Variables -gName = “John” gAge = 34 version = “8.0”
The version global is always there; it holds the version of Director you are using.
Using the globals property Director 7 introduced the globals property. This is a special property list of all current globals that have a value other than VOID. Where the showGlobals command is useful while authoring, the globals command can be used in your program. Every time you create a new global variable in your program (or the Message window), the global variable is added to the globals: put the globals -- (the globals) put (the globals).count() -- 3
741
3486-6 ch20.f.qc
742
7/24/00
5:54 PM
Page 742
Part V ✦ Further into Lingo
put (the globals).getPropAt(1) -- #gName put (the globals).getProp(1) -- “John”
Although the globals seems like a property list, it is more like a crippled property list. It only responds to these functions: count() getPropAt() getProp() getAProp() getProp() functions differently from normal property lists. If you use getProp() to try to get a property that does not exist in a property list, you will get a syntax error. If you do that with the globals, will be returned. (See the “VOID versus ” sidebar if you’re unclear on the difference.) So, when it comes to the globals, getProp() and getAProp() work identically.
Now try the following: put (the globals).count() -- 3 clearGlobals showGlobals -- Global Variables -version = “8.0” put (the globals).count() -- 3
You just cleared the globals, but version is still there because it’s always there. But what is going on with the globals property? There is a problem with the globals. If you use clearGlobals, it removes the values (they are set to VOID) from the globals, but not the properties. So, Director is still reporting three items in the globals, even though two of those have values of . This can be illustrated by creating a handler to show properties and their values, as shown in Figure 20-8.
Figure 20-8: Currently available global variables and their values
3486-6 ch20.f.qc
7/24/00
5:54 PM
Page 743
Chapter 20 ✦ Lingo Troubleshooting
Now run MyShowGlobals in the Message window: MyShowGlobals -- “gName: “ -- “gAge: “ -- “version: 8.0”
VOID versus You might have noticed that sometimes we write “the function returns ,” and other times “set the variable to VOID.” What’s the difference? VOID is a Lingo constant used to set a variable to an uninitialized state. is the way a VOID value is displayed in Director. The best way to illustrate this is in the Message window: put VOID -- If you have worked with the Message window, this might not convince you. Anytime an uninitialized variable is put to the Message window you will get a value: put aVar -- Assuming that aVar was never given a value, is the expected result. But VOID is a Lingo constant; you can try to set a constant to a value and not get an error, but a constant’s value will never change: set VOID to 1 put VOID -- The same holds true for the other constants, such as SPACE: set SPACE to 3 put SPACE -- “ “ Other constants are TRUE, FALSE, EMPTY, BACKSPACE, ENTER, QUOTE, RETURN, and TAB. Writing the constant in all capital letters is a stylistic convention; you can write it in any case you like (but you’ll find that most programmers follow the convention): put VOID -- put void -- put Void --
743
3486-6 ch20.f.qc
744
7/24/00
5:54 PM
Page 744
Part V ✦ Further into Lingo
Using the Watcher Window The Watcher window, shown in Figure 20-9, displays the values stored in selected variables and other Lingo expressions while a movie plays. Remember that an expression is something that evaluates to a single value. This means that you can have global variables in the Watcher window, as well as expressions such as (sprite2).loc - the mouseLoc. To open the Watcher window, choose Window ➪ Watcher or press Command+Shift+` (Ctrl+Shift+`).
List of "watched" expressions Add/Remove field
Set field Figure 20-9: The Watcher window
Designating variables to watch Before you can use the Watcher window, you must establish the expressions that you want watched. To do this, you identify the expressions by using the Debugger window, the Message window, the Script window, or the Watcher window. In each case except the last, you use the Watch Expression button to identify the expressions to watch. Figure 20-10 identifies the Watch Expression button in the Script
3486-6 ch20.f.qc
7/24/00
5:54 PM
Page 745
Chapter 20 ✦ Lingo Troubleshooting
window. If you do not see a Script Toolbar in your Script window, choose View ➪ Script Toolbar. Figure 20-10: The Watch Expression button looks the same in the Debugger and Message windows as it does here in the Script window’s toolbar.
Variable to watch
Watch expression button
Adding variables to and removing variables from the watch list To add a variable to the watch list using the Debugger window, the Message window, or the Script window, do the following: 1. Select the variable in the window. 2. Click the Watch Expression button or press Shift+F9. You can tell Director to watch more than one expression at a time. As the data stored in a variable changes, the Watcher window displays the current value. It’s easy to add variables to and remove variables from the watch list in the Watcher window by doing the following: 1. Type the variable’s name in the Add/Remove field (identified in Figure 20-9). 2. Click the Add button to add the variable, or click the Remove button to remove it.
Establishing values for variables on the watch list When debugging a script, you might want to establish an initial value for a variable. This can be helpful when determining whether a specific value generates an error. To set the value of a variable, you type the value or string in the Set field of the Watcher window (identified earlier in Figure 20-9), and click the Set button. In this next exercise, you use the Watcher window to track a variable. If you examine Score script 4 in the counter1.dir movie, you find that the gCounter variable increments until its value is greater than 10. By watching the value stored by the gCounter variable, you can see this occur.
745
3486-6 ch20.f.qc
746
7/24/00
5:54 PM
Page 746
Part V ✦ Further into Lingo
On the CD-ROM
You can find the file counter1.dir on the companion CD-ROM in the EXERCISE:CH20 (EXERCISE\CH20) folder.
Tracking the gCounter Variable in the Watcher Window 1. Open the counter1.dir movie. You need either the movie that you modified earlier in this chapter or the file counter1.dir on the companion CD-ROM. 2. Open the Message window and click the Trace button. 3. To open the Watcher window, choose Window ➪ Watcher, or press Command+Shift+` (Ctrl+Shift+`). 4. Select the Add/Remove field (top-left corner of the Watcher window) and type gCounter. 5. Click the Add button. The gCounter variable is listed in the Variable List field located in the middle of the Watcher window. The variable’s initial value might be or zero (0). It doesn’t matter until you play the movie. 6. In the Director toolbar, click the Rewind button, and then click the Play button to start the movie. Leave the windows open. 7. The gCounter value in the Watcher window first appears as follows: count=0
This is based on the initial value set in the on startMovie handler. As the movie plays, the Watcher window displays the current value of the variable gCounter. 8. Click the Count to 10 button. After the script finishes running, the field on the Stage displays the value 10, and the line in the Watcher window Variable List field reads as follows: gCounter = 11
9. Now you reset the value of the gCounter variable by using the Watcher window. With the movie still playing, select the variable gCounter in the Variable List field. 10. Select the Set field, type 33, and click the Set button. The new value for the variable appears in the Watcher window. 11. While the movie is playing, click the Count to 10 button. This causes the handler to execute, and the value for the variable changes again to 11. 12. Stop the movie. 13. Now let’s add another variable to the watch list, but this time by using the Message window. Click the Message window to activate it. 14. Scroll up in the Message window until you locate the following expression: member(“number”).text = string(gCounter)
3486-6 ch20.f.qc
7/24/00
5:54 PM
Page 747
Chapter 20 ✦ Lingo Troubleshooting
15. Drag across the following portion of the expression: member(“number”).text
16. Click the Watch Expression button on the Message window toolbar. The Watcher window now lists a second entry that displays the text stored in the field named number. 17. Run the movie, and click the Count to 10 button. When the script finishes running, the Watcher window updates the values for gCounter and the text of field number. 18. Now you will remove a variable from the watch list. Select the text of field number entry in the Variable List field of the Watcher window. 19. Click the Remove button on the Watcher window. The Watcher window no longer displays a value for the number field. 20. Stop the movie.
Using the Debugger Window You can manually open the Debugger window, shown in Figure 20-11, by choosing Window ➪ Debugger, or you can press Command+` (Ctrl+`). This window also opens automatically when the playback head encounters a breakpoint. (A breakpoint stops the execution of the code at that point and opens the Debugger window. Breakpoints are usually set in the Script window and are discussed shortly.)
Step script
Watcher window
Step into script Run script
Go to handler Figure 20-11: The Debugger window
Watch expression Ignore breakpoint Toggle breakpoint
747
3486-6 ch20.f.qc
748
7/24/00
5:54 PM
Page 748
Part V ✦ Further into Lingo
From the Debugger window toolbar, you can open the Watcher window (using the Watcher window button), add an expression or variable to the Watcher window (using the Watch Expression button), and open the Script window and jump to a specific handler (using the Go to Handler button). Each of these features is also available from the Message window or the Script window, as discussed earlier in this chapter. The Debugger window contains several controls for debugging complex scripts. In the Debugger window, you can do the following: ✦ Examine the current line of Lingo as it executes. ✦ Play the current handler line by line. ✦ Walk through the sequence of handlers as the current handler calls them. ✦ Debug errant code by examining the values stored in local variables, global variables, and properties as the movie executes. ✦ Access the Watcher and Script windows, for additional troubleshooting. Note
To actually edit or correct an error in a script, you must open the Script window. You cannot edit in the Debugger window.
Setting breakpoints within your scripts To use the full capabilities of the Debugger window, you need to set breakpoints in your handlers. Then you can use the Debugger window to watch the breakpoints within your scripts. Setting breakpoints is a good way to determine the state of variables within scripts and handlers at specific points during the execution of a movie. One way to set breakpoints in a Script window is to click a Lingo command and then click on the Toggle Breakpoint button, as identified in Figure 20-12. You can also add a breakpoint by choosing Control ➪ Toggle Breakpoint (or by pressing F9). When you set a breakpoint in the Script window, a red dot appears in the left column of the window (see Figure 20-12).
Breakpoint
Toggle breakpoint button Figure 20-12: The Script window with a breakpoint
3486-6 ch20.f.qc
7/24/00
5:54 PM
Page 749
Chapter 20 ✦ Lingo Troubleshooting
Tip
The fastest method of setting a breakpoint in the Script window, however, is to click in the left column adjacent to the line of code where you want the breakpoint to occur. To remove the breakpoint, click on the red breakpoint symbol.
Ignoring all breakpoints When necessary, you can tell Director to temporarily ignore breakpoints during your troubleshooting activities. Simply click the Ignore Breakpoints button, identified in Figure 20-11, or choose Control ➪ Ignore Breakpoints (Alt+F9). When the Ignore Breakpoints button is selected (or you choose Control ➪ Ignore Breakpoints), the breakpoint symbol still appears in the left column of the Script window, but it is grayed out. This indicates that the breakpoint is ignored in the Debugger window. Tip
After successfully finding the problem in a script and fixing it, you should run the script again to verify that it is error-free. The easiest way to test a corrected script is to temporarily disable the breakpoints.
Removing a single breakpoint To remove a single breakpoint, click anywhere in the line containing the breakpoint and then press F9. You can also click the Toggle Breakpoint button or choose Control ➪ Toggle Breakpoint to remove a single breakpoint. This method retains all other breakpoints whether they are in the same handler or in another handler within the movie. Tip
The fastest way to remove a breakpoint is to click on the breakpoint symbol in the left column of the Script window. The breakpoint is erased when the red breakpoint symbol disappears.
Removing all breakpoints After you troubleshoot and fix your scripts, you can quickly and painlessly remove all breakpoints that have been set. There’s no need to open each script and toggle the breakpoints off individually. All you do is choose Control ➪ Remove All Breakpoints. All breakpoints in all scripts are removed (not just disabled, as they are when you use the Ignore Breakpoints button). Tip
If you want to reuse a previous breakpoint after removing all breakpoints, you must reset it in the appropriate script or handler.
Running through your script in the Debugger window The Debugger window has three additional buttons that are used to run your movie while troubleshooting each handler.
749
3486-6 ch20.f.qc
750
7/24/00
5:54 PM
Page 750
Part V ✦ Further into Lingo
Stepping through the script The Step Script button runs the current line of Lingo and any handlers it calls. In essence, this lets you walk through your script, executing it line by line. You can also choose Control ➪ Step Script to execute one line of code at a time, or click the Step Script button in the Debugger window’s toolbar, or use the keyboard shortcut Command+Option+Shift+down arrow (press F10 for Windows users).
Running the script through the next breakpoint The Run Script button exits debugging mode and continues execution of the handlers in your movie. In the case of the counter1.dir movie, clicking the Run Script button continues the repeat loop until the breakpoint in the repeat loop is encountered again. The basic difference between the Run Script button and the Step Script button is that the Run Script button executes all lines of code until the line with the breakpoint is encountered again, whereas the Step Script button executes one line of code at a time. Using the Run Script button is useful when you are confident that certain parts of the script are performing accurately, and you only want to pause at specific lines of code with breakpoints. This saves you time and effort, because it eliminates the need to repeatedly click the Step Script button to move forward one line of code at a time. Instead of using the Run Script button, you can choose Control ➪ Run Script or press F5.
Running the whole script The Step into Script button follows Lingo’s normal execution flow. It executes each line of code and follows, line by line, each nested handler that the line calls. Step into Script is handy when you’re debugging errors in nested logic. For example, if you have a Lingo command that plays another Director movie, using the Step into Script button executes the current line of Lingo that calls the other movie and then jumps to that movie and executes it line by line. The Step into Script button also works effectively for troubleshooting nested repeat loops or other control structures that use nesting. The equivalent command for the Step into Script button is to choose Control ➪ Step Into Script or press F8.
An exercise with the Debugger window In the following steps, you use the counterup.dir movie from the CD-ROM to set breakpoints in the Script window, and then you debug the script by using the Debugger window.
3486-6 ch20.f.qc
7/24/00
5:54 PM
Page 751
Chapter 20 ✦ Lingo Troubleshooting
As you troubleshoot the counterup.dir movie, the problem appears to be on the line that reads as follows: repeat while gCounter >=10
The greater-than symbol ( > ) rather than the less-than symbol ( < ) has been used. The lines that increment the gCounter variable are never executed because 0 (the initial value) is never greater than or equal to 10. Repeating an action until a value is less than or equal to a specific value (such as 10) is more efficiently accomplished by stipulating that the loop continue while the count is less than one number larger than your target value. The proper method of repeating actions until the gCounter variable is equal to or less than 10 is to use this instruction: repeat while gCounter < 11
While you run the practice movie, watch the position of the green arrow at the left margin. The green arrow shows the line of the Lingo script that is to be executed next. This is a helpful method of testing the logic of your control structures, such as a loop. By monitoring the state of the loop and the value of the conditional variables in the loop, you can thoroughly test the logic of the loop. On the CD-ROM
You can find the file counterup.dir on the companion CD-ROM in the EXERCISE: CH20 (EXERCISE\CH20) folder.
Checking Handlers by Using the Debugger Window 1. Open the counterup.dir movie and play it. 2. After the movie starts playing, click the Count to 10 button. The value in the field on the Stage remains set to zero (0). 3. Stop the movie. 4. Open the script cast member stored in cast slot 4. This is the behavior attached to the Count to 10 button. 5. Click in the left column of the Script window parallel to the line of code that reads gCounter = 0. A red breakpoint symbol appears in the left column, identifying the location of the new breakpoint within the handler. 6. Close the Script window (and the Behavior Inspector, too, if it’s open). This should catch any syntax or spelling errors, if they exist. 7. Play the movie and click the Count to 10 button. As soon as the line of code with the breakpoint is reached, the Debugger window automatically opens, as shown in Figure 20-13.
751
3486-6 ch20.f.qc
752
7/24/00
5:54 PM
Page 752
Part V ✦ Further into Lingo
Note that the top-left pane of the Debugger window displays the name of the current handler (mouseUp). The top-right pane displays all variables and their values. Only the count variable is listed with a value set to zero. The bottom pane displays the script for the current handler. The green arrow in the left column of the bottom pane sits on top of the breakpoint symbol and identifies the point within the script where the movie has temporarily stopped. You might not be able to see the green in the screenshot of Figure 20-13. Figure 20-13: The Debugger window opens when breakpoint is reached.
8. Click the Step Script button (or press F10) to move the Lingo script to the next command, which is repeat while count >=10. 9. Click the Step Script button again, and the green arrow jumps to the end keyword at the end of the on mouseUp handler. It skips the next two lines, which increment the value of the variable gCounter. 10. Click the Step Script button one more time. The Debugger window goes blank, because the playback head is no longer in the handler that contains the breakpoint. 11. Click the Count to 10 button on the Stage again. The Debugger window becomes active again, because the playback head hits the line of code that includes the breakpoint. 12. To open the Script window and make the necessary change, click the Go to Handler button on the Debugger window (the far-left button on the Debugger’s toolbar). 13. In the Script window, change the handler to match the following: global gCounter on mouseUp gCounter = 0 repeat while gCounter < 11
3486-6 ch20.f.qc
7/24/00
5:54 PM
Page 753
Chapter 20 ✦ Lingo Troubleshooting
member(“number”).text = string(gCounter) gCounter = gCounter + 1 end repeat end
14. Leave the breakpoint on the gCounter = 0 instruction so that you can watch the values increment in the Debugger window. 15. Close the Script window. 16. Play the movie and then click the Count to 10 button. 17. Save the movie as counterup1.dir by choosing File ➪ Save and Compact, or recompile all scripts in the movie by choosing Control ➪ Recompile All Scripts. 18. Play the movie and click the Count to 10 button. 19. Click the Step Script button to step through the handler, and watch the repeat while loop execute. To completely step through the handler will require four clicks of the Step Script button (before the gCounter variable increases to 1). You can watch the variable gCounter change values in the top-right pane of the Debugger window. 20. Continue to step through the script until the repeat while loop finishes and the value of gCounter reaches 11. At that point, if you keep clicking the Step Script button, the Debugger window will go blank because the playback head exits the on mouseUp handler. 21. Now you test the corrected script but cause the playback head to stop only at the breakpoint and not at each line of code. With the counterup1.dir movie still open, click the Rewind button on the main Director toolbar. 22. Click the Play button and then click the Count to 10 button. The Debugger window displays the script with the breakpoint as before. 23. This time, when the playback head pauses at the breakpoint, click the Run Script button. Instead of stopping on each line of Lingo script, the script runs until the breakpoint is encountered again. The gCounter variable is still updated, as you can see by examining the field on the Stage that displays the value 10 when the handler finishes. 24. Stop the movie. On the CD-ROM
If you want to practice troubleshooting files, you can use the following three practice files: matchit.dir, orient.dir, and virgil.dir on the companion CD-ROM in the EXERCISE:CH20 (EXERCISE\CH20) folder.
753
3486-6 ch20.f.qc
754
7/24/00
5:54 PM
Page 754
Part V ✦ Further into Lingo
Summary You learned the following things in this chapter: ✦ Director has several tools to locate syntax, spelling, and logic errors in scripts. ✦ Syntax and spelling errors are the most common problems that you will encounter as you write Lingo scripts. You can always use the Alphabetical Lingo and Categorized Lingo buttons (in the Script window and the Message window) to assist in typing the correct syntax and spelling for a command, property, or function. ✦ In the Message window, you can test a single instruction or a single line of code. You can also run any handler within the current movie just by typing the handler’s name into the Message window. ✦ To help you identify errant code, use the Watcher window to track variables and their values. You can track one variable or many by adding the variable’s name to the variable list pane in the Watcher window. You can also specify a value for a variable while the movie is running, and you can watch the results as the movie plays. ✦ Identifying errors of logic is more difficult than locating syntax and spelling errors. You do have a powerful tool in the Debugger window — breakpoints that help you step through the execution of a handler. The next chapter deals with memory management in Director.
✦
✦
✦
3486-6 ch21.f.qc
7/24/00
5:54 PM
Page 755
21 C H A P T E R
Memory Management
✦
✦
✦
✦
In This Chapter
D
irector is an enormously flexible authoring tool. It enables you to create movies for a broad variety of uses. With Director, you can design movies for playback on a variety of computers or other output devices capable of digital display. Certainly, you need a powerful computer to produce professional-quality Director movies. Remember, however, that there may be a vast difference between the computer that you use to create Director movies and the one that the end-user uses to view them. A critical element in designing a movie is a clear assessment of your audience and the capabilities of their computers. In most cases, it is a serious mistake to presume that the enduser’s computer is equal to the machine that you use to author your Director movies. Because of those potential differences, memory management is more than just good sense; it’s essential for the success of your movies. For a movie to be successful, you need to design it for the viewer. In this chapter, you explore memory considerations both for authoring and for the end-user.
Understanding Memory Casual computer users frequently confuse memory with hard disk space. Part of this misunderstanding arises from the fact that many computer programs use virtual memory created from hard disk space to supplement physical memory, or RAM. Adding the concept of video memory can increase the confusion. All three of these types of memory are considered part of a computer’s resources and are interrelated.
Understanding and controlling memory usage Preloading cast members Setting purge priorities Designing movies with memory usage in mind Outputting to CD-ROM
✦
✦
✦
✦
3486-6 ch21.f.qc
756
7/24/00
5:54 PM
Page 756
Part V ✦ Further into Lingo
For any discussion of resources to be helpful, you must have an understanding of the different types of memory and, in the case of Director, their combined impact when authoring or playing a movie: ✦ RAM: RAM (random-access memory) is hardware installed on your computer. Depending on the computer you use, these memory chipsets can be hardsocketed (permanently soldered) to your motherboard, or installable (plugged into special slots) on your motherboard. Some computers have a base amount of RAM hard-socketed on the board, plus sockets for expanding the amount of physical memory. How fast your computer operates and its power are determined by the speed of the CPU (central processing unit) and the amount of physical memory, or RAM. ✦ Virtual Memory: Virtual memory is pseudomemory. You create virtual memory by allotting a portion of your hard disk to serve as temporary auxiliary memory for software. Unlike RAM, virtual memory does not affect the base speed of your computer. Rather, programs use virtual memory to increase the amount of memory available. Virtual memory is slower than RAM because your computer’s CPU must read and write to use the virtual memory. ✦ Video Memory: Video memory is also hardware-related memory. This memory is installed on your video display adapter, and its configuration can vary from one video board to another. Most video boards today have a minimum of 1MB of memory on the board. Some video cards are expandable, enabling you to add more memory as your needs increase. The more video memory, the more color depth is displayed on your monitor. In addition to controlling the color depth, video memory also affects the screen refresh rate. Performance and faster screen refresh rates increase proportionately with the amount of video memory. Director works with your computer to use a combination of these resources when you create and play back a movie.
Determining memory requirements Like most powerful programs, Director requires substantial resources for authoring. The program’s basic needs, plus the needs of the movie that you’re creating, determine the amount of resources required. Obviously, movies that are more complex require more resources. Director provides the tools to check the requirements of your movie, the available system resources, and information about the various cast members in your movies. In the following exercise, you learn to use the Message window to check system resources, a movie’s memory requirements, and the amount of contiguous memory available. Contiguous memory is memory all in one chunk, the opposite of fragmented memory. For some tasks, a contiguous chunk of memory is needed.
3486-6 ch21.f.qc
7/24/00
5:54 PM
Page 757
Chapter 21 ✦ Memory Management
Preventing auto-syncing It’s logical to presume that the more virtual memory you have, the better off you are. In other words, if you have a large hard disk and you enable the software to use as much of that space as needed for virtual memory, you might think that your software and computer would perform better. This is not true, however. Allowing large amounts of virtual memory creates a situation known as auto-syncing to disk, which can actually reduce the performance of your computer. When a program uses virtual memory, it stores information temporarily on the hard disk for use by swapping chunks of data to the disk. This disk swapping is also known as auto-syncing. As virtual memory increases, the amount of data being swapped to the hard disk increases, and more chunks are stored to the disk before they are purged from the virtual memory. Your computer uses RAM to manage virtual memory. The increased amount of disk swapping (auto-syncing) uses more RAM strictly to manage the virtual memory rather than to run software. Consequently, performance decreases as more RAM is dedicated to this use. In some cases, you can actually see and hear the problem. If your hard disk sounds unusually busy or you see that light blinking on more and more often, there is an unusually high amount of activity going on, and an auto-syncing problem probably exists. This is not to say that you shouldn’t use virtual memory — but for best results, you should minimize virtual memory usage. As the amount of RAM in your computer increases, your needs for virtual memory decrease. RAM is inexpensive as of this writing, and it will pay off to load up on it.
On the CD-ROM
You can find the kiosk1.dir file on the companion CD-ROM in the EXERCISE:CH21 (EXERCISE\CH21) folder.
Checking System Resources and Requirements 1. Open kiosk1.dir in Director. 2. Choose Window ➪ Message to display the Message window. 3. In the Message window, type put the memorySize and press Enter. The amount of memory (RAM) installed on your computer is displayed in the window (see Figure 21-1). 4. In the Message window, type put ramNeeded (1, 2) and press Enter. The amount of memory required for kiosk1.dir is displayed in the window. 5. In the Message window, type put the freeBlock and press Enter. The amount of contiguous free memory is displayed in the window.
757
3486-6 ch21.f.qc
758
7/24/00
5:54 PM
Page 758
Part V ✦ Further into Lingo
Figure 21-1: The Message window enables you to view memory information.
The memory values are shown in bytes, kilobytes (K), and megabytes (MB). To convert bytes to kilobytes, or to convert kilobytes to megabytes, divide by 1024. Figure 21-1 shows that the computer used for this example has 192MB of RAM. The floatPrecision was set to 1 just to make the numbers easier to read (the default is 4). The kiosk1.dir file requires 4,109,595 bytes of RAM, or a little under 4MB. To load a cast member, you need a freeblock at least as large as the cast member. (As mentioned in step 5 of the preceding exercise, a freeblock is a contiguous chunk of available memory in bytes.) For example, you could add a Lingo statement to a movie script that identified a freeblock large enough to load your largest cast member. If your cast member required 500K, the statement shown in Figure 21-2 would alert the user that memory needed to be freed up to run your movie.
Figure 21-2: You can add statements to a movie script that enable you to check memory and warn users of potential memory problems.
3486-6 ch21.f.qc
7/24/00
5:54 PM
Page 759
Chapter 21 ✦ Memory Management
Testing to avoid memory problems To avoid memory problems, testing is crucial. Most multimedia designers don’t have the luxury of knowing the precise hardware configuration of the end-user’s computer. The amount of resources, type of video adapters, and speed of the computer vary widely among users. It is critical that you test your movie during development on a variety of systems. This wise practice prevents unpleasant surprises later. If you are creating a movie for cross-platform use, testing is even more critical. The movie that looks and plays wonderfully on the Macintosh may crash in Windows, or vice versa. Although you can build a lot of safeguards into a movie, nothing replaces testing to ensure the success of your project.
Preloading Cast Members Preloading large cast members, such as sound and digital video cast members, smoothes the performance of a movie. By default, Director loads cast members as needed. Loading a number of large cast members at the same time can create memory problems. In addition to smoothing the performance of your movie, preloading some of the larger cast members enables you to balance the memory load. Note
Take care when preloading cast members if you have memory constraints. Preloading too many cast members at one time can cause memory problems.
Lingo can play a significant role in preloading. It can be used to preload cast members, markers, and frames of a movie. Shockwave Audio files (SWA) can be preloaded either in the SWA Cast Member Properties dialog box or by using Lingo. When you use Lingo to preload cast members, you can specify different preload times for each instance of the cast member. This is particularly useful if you need to swap between large cast members that appear more than once in a movie.
Specifying SWA preload values In the following exercise, you add a Shockwave Audio file (SWA) to kiosk1.dir and you specify the preload time for the file. SWA files offer advantages that are not available with WAV, AIFF, and other sound files. The SWA files are much smaller, and they provide for streaming, which means that they can start playing while they are loading. You can use SWA files in your movies whether they are being produced for the Internet or for running from a local disk. These sound files are linked rather than embedded, so you need to make sure that the SWA file is included when you transport your movies.
759
3486-6 ch21.f.qc
760
7/24/00
5:54 PM
Page 760
Part V ✦ Further into Lingo
It’s a good idea to link sound files, regardless of their format, rather than embedding them into your Director movies. Linking sound files enables you to specify preloads and purge properties to conserve memory. Director enables you to convert sound files to SWA format for inclusion in your movies.
Tip
On the CD-ROM
For the next exercise, use the kiosk1.dir movie from the companion CD-ROM located in the EXERCISE:CH21 (EXERCISE\CH21) folder. You also use the kiosk1.swa file, which is in the same folder.
Specifying a Preload Setting in the SWA Cast Member Properties Dialog Box 1. Open kiosk1.dir in Director, if it’s not already open. 2. Choose Insert ➪ Media Element ➪ Shockwave Audio to display the SWA Cast Member Properties dialog box (see Figure 21-3).
Figure 21-3: Specifying the preload setting
3. Click the Browse button, and select kiosk1.swa from the EXERCISE:CH21 (EXERCISE\CH21) folder. 4. The Preload Time value specifies the number of seconds ahead of the cast member’s appearance in the movie that you want the file to start loading. Choose 5 from the list; this is the default setting. 5. Click the Play button to hear the audio. When you’re finished, click Stop. 6. Click OK to complete the operation and return to Director’s main window. The SWA file appears in the first empty slot of the Cast window. Name the new member background1. 7. Save your movie as kiosk2.dir. Tip
You can specify SWA file paths by using either a URL or local disk location.
Unlike other sound files, you place SWA files in the sprite channels of the Score rather than in a sound channel. Because Lingo controls SWA files, they can use any of the sound channels during playback, including those not visible in the
3486-6 ch21.f.qc
7/24/00
5:54 PM
Page 761
Chapter 21 ✦ Memory Management
Score window. You can specify a sound channel when you insert the SWA file into your movie, or you can let Director use any available channel during playback. Tip
SWA files can be imported as well as inserted. Imported members have the standard capabilities of normal sound members, but they do not have the same capabilities as an SWA that has been inserted. Inserted members act as they have in previous versions of Director. SWA-specific Lingo works only on inserted members. Imported SWA requires MIX Services, SWA Import Export Xtra, and the Sound Import Export Xtra for playback. Using imported SWA members in a Shockwave movie causes all three Xtras to download.
Placing the SWA File in the Score 1. From the Cast window, drag the cast member to frame 1 of channel 22 in the Score. 2. Select the tail frame of the sprite; then click the frame bar at frame 77. 3. Press Command+B (Ctrl+B) to extend the sprite to frame 77 (see Figure 21-4).
Figure 21-4: The SWA sprite is extended through frame 77 of channel 22.
4. Save the movie again as kiosk2.dir. 5. Rewind the movie and click the Play button to test the movie. SWA files play on both the Macintosh and in Windows. Using this format offers you the capability to play a movie containing sound on both platforms, even if you don’t have utilities to convert the sounds from the native format of one platform to the other. In addition, the small file size of SWAs helps you control the amount of RAM and hard disk space required for the storage of your movie.
761
3486-6 ch21.f.qc
762
7/24/00
5:54 PM
Page 762
Part V ✦ Further into Lingo
Using Lingo to specify preload values You can use Lingo to specify the preloading of individual cast members, a cast library, your movie, a marker, or a range of frames. This is especially useful if you are working with a movie in a window (MIAW), digital video, or sound cast members. Table 21-1 lists Lingo preload commands and their uses. It also shows an example of the command usage.
Table 21-1 Lingo Preload Commands Command
Application
Usage Example
PreLoad
Preloads cast members from a range of frames into memory. This is useful for loading cast members that animate. Note that if no parameter is specified, Director continues to load the entire movie, stopping only when memory is full.
PreLoad marker (“finance”) Loads the marker named finance into memory.
PreLoad 20, 32
Preloads frames 20 through 32 into memory.
PreLoadBuffer
Preloads an SWA file or portion of an SWA file into memory. Only works if the SWA is stopped.
PreLoadBuffer (member member ”kiosk1”) Preloads the SWA file KIOSK1 into memory.
PreLoadMember
Preloads a specific cast member or range of cast members from the cast library into memory.
PreLoadMember “seq01”, “seq38” Preloads the cast members from seq01 through seq38 into memory.
PreLoadMode of Castlib
Specifies when to preload a cast library. Options include the values 0 (when needed), 1 (before frame 1), 2 (after frame 1).
set the preLoadMode of castLib “sounds” = 1 Preloads the Cast Library named “sounds” into memory before frame 1 of your movie.
3486-6 ch21.f.qc
7/24/00
5:54 PM
Page 763
Chapter 21 ✦ Memory Management
Command
Application
Usage Example
preLoadMovie
Preloads the specified movie by preloading its cast members. Prevents delays when the current movie opens another movie or an MIAW.
PreLoadMovie “menu” Preloads the movie named menu into memory.
preLoadNetThing
Preloads a file from the Internet. This is useful if you have multiple movies on a Web site, by preloading the next movie while the current movie is playing.
PreLoadNetThing (“http://www. mymovie.com/ playit”) Preloads the movie named PLAYIT into memory while the current movie is playing.
preLoadRAM
Allocates limited memory for digital video, while enabling other cast members to load normally.
set the preLoadRAM to 2 (the size of member “cycling”) Specifies that the amount of RAM available for preloading equals twice the size of the digital video cast member named cycling. If preLoadRAM=False, all memory available can be used to preload digital video.
preLoadTime of member
Specifies the amount of an SWA file to download before it starts playing. The amount is limited by seconds, rather than a number of bytes. Note that the SWA file must be stopped for this command to work.
set the preLoadTime of member”kiosk1” = 6 Preloads the sound cast member named kiosk1 6 seconds before it starts playing.
Setting Purge Priorities You can set the purge priorities of the cast members in your movies. By default, Director purges cast members at random, as needed to free up memory when it’s full. Often it is best to leave it at the default setting and allow Director to handle the memory. If the size of the movie exceeds the available memory, setting purge priorities enables you to control which cast members are purged from memory and which are retained. When Director needs to reload a cast member frequently, it puts a strain on the resources of the user’s computer. For example, a bitmap used as a
763
3486-6 ch21.f.qc
764
7/24/00
5:54 PM
Page 764
Part V ✦ Further into Lingo
background throughout a movie should be retained in memory for the entire movie, to prevent repeated pauses for reloading the image. To specify purge priorities, you specify a value that indicates when a cast member should be removed. The higher the priority value, the more likely it is that a cast member will be purged if memory runs low. The following values are available for purge priority settings: 0 = Never Purge 1 = Purge Last 2 = Purge Next 3 = Purge Normal On the CD-ROM
For the next exercise, use the kiosk2.dir movie from the CD-ROM, located in the EXERCISE:CH21 (EXERCISE\CH21) folder.
Specifying Purge Properties in a Movie Script 1. Open kiosk2.dir in Director, if it’s not already open. 2. In the Cast window, double-click the cast member with the startMovie handler (if you are using the CD-ROM’s version of kiosk2.dir, it is in cast member 4) to open it in the Script window. 3. At the top of the script, enter the prepareMovie handler, as shown in Figure 21-5. 4. Close the Script window, and save your movie.
Figure 21-5: Adding purge priorities in a movie script
Director doesn’t purge cast members from memory unless it needs the memory to run a movie. On computers with substantial resources, purging cast members is rarely a problem. If you’re designing an application for use on a broad range of computers, you should pay close attention to specifying the way cast members are purged from memory, to ensure the success of your movie.
3486-6 ch21.f.qc
7/24/00
5:54 PM
Page 765
Chapter 21 ✦ Memory Management
Designing Movies for Memory Considerations When designing Director movies, it’s important to remember your audience. Where memory is concerned, designing for the least common denominator is necessary if you want to reach the broadest audience. Clearly, if you are designing a project for the World Wide Web, you can anticipate an enormous variety of users and hardware. Because it’s impossible to design for every variable, it’s a good idea to pick a target platform. A target platform is the lowest system your software will run on acceptably.
Guidelines for Saving Memory Director helps you to control memory usage. In addition, you can cultivate success and improve the performance of your movies by keeping the following considerations in mind when you are designing your movies: ✦ Use the lowest possible color depth for bitmapped cast members that have only a few colors. The higher the color depth, the more resources that are needed to render the cast member and refresh the screen. ✦ Create composite images of bitmap cast members that appear as static images on the Stage. This reduces the number of cells and channels that Director has to read and process, enabling your movie to run more smoothly. ✦ Use the floating Tool Palette to draw and fill simple geometric shapes, instead of employing bitmap images. Objects drawn with tools from the Tool Palette are vector images and require less time and fewer resources to render to the screen. Don’t use vector graphics for animation, however, because they will slow your movie enormously.
Bitmap memory considerations It’s a good idea to keep memory requirements in mind when you create bitmap images for your movies. Bitmaps can account for a rather large chunk of your final movie size. And if you add sounds and other effects in addition to large bitmaps, your movie may exceed the resources of the end-user’s computer. You can use the following formula to predict the amount of memory required to display a bitmap: (the width of the bitmap in pixels) × (the height of the bitmap in pixels) × (the color depth in bits) / 8 = the number of bytes of memory required For example: a 200-pixel × 200-pixel, 8-bit bitmap would require 40,000 bytes of memory, or (200 × 200 × 8) / 8 = 40,000.
765
3486-6 ch21.f.qc
766
7/24/00
5:54 PM
Page 766
Part V ✦ Further into Lingo
✦ Keep the use of gradient fills to a minimum. Gradients require more resources to render to the screen. ✦ Try not to use memory-intensive inks with complex or large bitmaps, which can bring a movie to almost a dead stop on most computers, even if they possess significant resources. ✦ Use film loops for repetitive animation sequences. A film loop will play as a single cast member in a frame while Director is processing other cast members in the frame. ✦ Reduce the sampling rate of sound files, or consider using Shockwave Audio (SWA) files to improve performance. ✦ Get the most from small sound bites, such as knocks, beeps, and clicks, by setting them to loop. ✦ Link rather than embed your sound files, so that Director doesn’t have to load the files until they’re needed in your movie. When linking files, be sure that the file is included when you transport your movie from one location to another. ✦ Use Lingo preload and purge commands to control the memory usage of your movies. This prevents bottlenecks that slow or halt a movie if too many cast members are loading at the same time. ✦ Consider using movies in a window (MIAWs) when your movie contains multiple branches of movies that could be designed to run independently. Just remember that you can’t use MIAWs on the Internet. Observing good memory-conservation practices can increase the performance of your movies and make troubleshooting easier. Frequently, as in the case of using film loops, memory conservation produces a tighter, more compact Score. And that makes it easier for you to find elements within your movies and edit them.
Optimizing for CD-ROM Director movies are large. It’s not uncommon for a single movie to be well over 4MB. If you are creating a project in which multiple movies play in succession and have MIAWs, sounds, and perhaps digital video, the amount of space required for storage can mushroom almost geometrically. CD-ROMs have become the distribution media of choice for most Director projects that aren’t being published on the Internet. CD-ROM disks have a number of advantages over floppy disks. They are inexpensive and durable, they can’t be damaged by magnetic fields, they hold large amounts of data, and they can be built to play on multiple platforms. The transfer rate of a CD-ROM drive can have an impact on the performance of a movie. As a general rule of thumb, the transfer rate of a CD-ROM drive is 150KB per second times the speed of the CD-ROM. Thus, a 4X CD-ROM would have a 600KB-per-second
3486-6 ch21.f.qc
7/24/00
5:54 PM
Page 767
Chapter 21 ✦ Memory Management
transfer rate. Slower drives (below 4X) may cause a performance problem with your movies. Be sure to test your movie thoroughly before distributing it.
Building a virtual image The first step in recording a CD-ROM is to build a virtual image. A virtual image is a database of pointers telling the mastering software where to find the files that you want to include. When you create the virtual image, you are not actually moving any files. You are telling the mastering software how you want the CD-ROM organized, by setting up directories and allocating files to those directories. Before recording your CD-ROM, it’s a good idea to do a little housekeeping to organize your files. By organizing your files into folders and keeping related files together, you improve the performance of your movies by reducing the amount of time the computer has to spend looking for files. In addition, you also reap the benefits of simplifying the task of creating a virtual image and improving your chances of a successful recording session. When you put the files in order on your hard disk prior to starting, you’ll be prompted to remove files that will not be included on the CD-ROM, and will more easily recognize a logical order for your files. Remember: You are dealing with almost 650MB of information. When it’s time to move linked files, such as digital movies, sound files, and external casts, you should open and resave your Director movies to update the location of those linked files. Tip
Although most mastering software permits a directory tree of folders and subfolders eight deep, it’s a good idea to limit the folder depth to three or four levels. This reduces the seek and transfer times from your CD-ROM to your computer — yet another way to improve the performance of your movies.
CD-ROM basics There are two basic recording standards for CD-ROMs: ISO 9660 and Hierarchical File System (HFS). Macintoshes can read both formats, but they prefer the HFS standard; Windows-based machines can read only files that have been encoded by means of the ISO (International Standards Organization) 9660 standard. It is possible to record both formats on a single CD-ROM. You should be aware, however, that recording your movies in both formats on a single compact disc cuts in half the amount of available storage space. This is the result of including two copies of a movie or projector (one for each platform). If you find that you need to record more than 300MB of data for each format, you’ll either have to use some form of data compression or reevaluate your decision to put both formats on the same disk. Not all files need to be duplicated for cross-platform presentations. It is possible to share many of the external files, such as QuickTime movies, via aliases. In fact, QTVR files do not play well from an ISO 9660 volume. In that case, it is better
767
3486-6 ch21.f.qc
768
7/24/00
5:54 PM
Page 768
Part V ✦ Further into Lingo
to store them in a Macintosh HFS volume and reference them through shortcuts on the PC ISO 9660 side of a multiplatform CD-ROM. Because of its audio origin, the CD-ROM blank medium is measured in minutes:seconds:sectors. It comes in two sizes: 63 minutes or 74 minutes. This works out to be 553MB and 650MB, respectively. The 650MB discs are the most common. It’s not a good idea to run too close to the maximum storage amount on a disk. Both the ISO 9660 and HFS standards require approximately 1MB of overhead space for root files, resource forks, and other data required by the operating systems of both platforms. Note
If you are including data from multiple sources, be certain that you observe copyright laws and restrictions. You must obtain licenses to include any files, including sound and digital movie files. If you are using clip-media sounds, digital movies, text, or artwork, be sure the license rights provide for redistribution of the files.
Single- or multisession recording? When you record a CD-ROM, you can choose between two modes: single-session or multisession. Single-session only enables you to burn the content onto the CD-ROM one time as a single volume. Multisession CD-ROMs can contain multiple volumes that can be added at any time. When you mount a multisession CD-ROM, it appears on your computer as several different volumes. Single-session CD-ROMs are more useful for mastering a CD-ROM that will be widely distributed. Multisession CD-ROMs, on the other hand, are better for backing up and archiving, because you can add more volumes as the project grows. Your choice depends on the media you choose, the CD-R (CD-ROM recorder), and the recording software.
Understanding logical blocks Data is stored on a CD-ROM in logical blocks, rather than as the total number of bytes of all the files. A logical block is the smallest recordable unit on a CD-ROM. This means that files occupy more space than their original size. Logical blocks can be 512, 1024, 2048, or 4096 bytes in size. MSCDEX (Microsoft CD Extensions) and HFS can only read a 2048-byte block. Consequently, each file occupies a space equal to the nearest multiple of the next higher block. For example, if a file contains 16,000 bytes, it will require 8 blocks (16,000 / 2048 = 7.812 blocks). Simply totaling the number of bytes for all the files that you want to record won’t yield an accurate estimate of the space required. Most CD-ROM mastering software calculates the amount of space required for your files, but you should already have an estimate of your space requirements before you start recording a CD-ROM. Remember that directories, like files, require space on the CD-ROM. Generally, you can record up to 600MB of raw data on a CD-ROM. Under most circumstances, this amount leaves ample space for overhead while taking logical locks into consideration.
3486-6 ch21.f.qc
7/24/00
5:54 PM
Page 769
Chapter 21 ✦ Memory Management
Two types of CD-ROM media are available today: CD-ROM (Mode 1) and CD-ROM XA (Mode 2). The difference between the two types is frequently misunderstood — due in part to the history of compact disc media. Early CD-ROMs were recorded in a single session, even though the standard made provisions for recording in multiple sessions. Kodak’s Photo CD medium was one of the first to make use of multisession recording, but it did not use the standard CD-ROM format. These early multisession disks used the CD-ROM XA format, so the manufacturers of CD-ROM drives assumed that all multisession CD-ROM media would also be CD-ROM XA format. The reality is that both formats can be used for multisession recording. Because of the misconceptions arising from the two CD-ROM media formats, you cannot assume that a CD-ROM recorded in multiple sessions will be read correctly. If you anticipate recording in more than one session, you would do well to either premaster the CD-ROM on a hard drive, or make sure that data is recorded in the CD-ROM XA format. The choice of whether to record in a single or multisession format requires taking a close look at your needs. Each recording format offers distinct advantages and disadvantages. To begin, remember that when multiple people are involved in the production of a single movie project, sometimes it’s difficult to gather all the data into a single location simultaneously. If you want to record a single-session CD-ROM, it’s essential that the virtual image contains all of the files, organized precisely as they will be placed on the CD-ROM. If you are working on a network, or are including data from remote sources, a single recording session might not be practical. Multisession recording offers you the advantage of being able to add data at a later time, from a variety of sources or locations. If you are creating a CD-ROM for multiple platforms, it’s necessary to create a multisession CD-ROM to accommodate the differences in the operating systems of the two platforms. On the other hand, multisession recording requires more headroom on the CD-ROM, which means it cannot hold as much data.
Summary Employing memory management techniques helps trim the size of your movies while maintaining a high quality of performance for your projects. As your movies become larger and more complex, good memory management makes a noticeable difference in movie performance. In this chapter, you learned how to: ✦ Use SWA files in your movies and to specify the preload times to ensure that they play smoothly. ✦ Calculate the amount of memory required for bitmap images. ✦ Set purge priorities. ✦ Use the Message window to obtain information about memory and your movie.
769
3486-6 ch21.f.qc
770
7/24/00
5:54 PM
Page 770
Part V ✦ Further into Lingo
✦ Design movies with memory considerations in mind. ✦ Organize your projects for CD-ROM output. In the next chapter, we discuss Lingo related to user-interface elements, such as dialog boxes and menus.
✦
✦
✦
3486-6 ch22.f.qc
7/24/00
5:54 PM
Page 771
22 C H A P T E R
Menus and Dialog Boxes
✦
✦
✦
✦
In This Chapter
B
y nature, Director encourages a free-form interface design: buttons that come alive when the mouse rolls over them, animations that dance across the screen, whole toolbars that appear and disappear effortlessly. However, even in the most dynamic environment, there is a place for menu bars and dialog boxes — the staples of more traditional programs on any platform. This chapter explores the creation of menus and dialog boxes by means of Lingo.
Making Menus In the history of computing, the menu bar was a major step forward. It presented options to the user that previously had been available only by using terse (and frequently poorly documented) command-line arguments. The menu bar evolved into powerful and intuitive graphical user interfaces such as those of the Macintosh operating system (OS) and Microsoft Windows. Today’s menu interface is vastly more complex than the first menus — some say too complex — but there is no denying the importance of the fundamental principles that make menus useful. Those principles are: ✦ Menus group commands by functionality, providing a quick and logical path to performing a specific action. ✦ Similar common menus make it easier to work with several programs running on the same operating system. The beginning user doesn’t have to learn a completely different paradigm when exploring every new application. An application’s interface is typically more similar to than dissimilar from those of other applications using the same operating system.
Learn to create and manipulate menus Build simple dialog boxes with the MUI Xtra Build not-so-simple dialog boxes with the MUI Xtra
✦
✦
✦
✦
3486-6 ch22.f.qc
772
7/24/00
5:54 PM
Page 772
Part V ✦ Further into Lingo
✦ Menus act as reminders for common keyboard equivalents. When the shortcut operation to save a file is to press Command+S (or Ctrl+S in Windows), that shortcut is usually displayed when you choose File ➪ Save. Until a user becomes familiar with the keyboard shortcuts, menus provide easy access to all features and list the shortcuts while remaining unobtrusive. ✦ Menus frequently serve as a gateway to dialog boxes in a manner that would be difficult to implement with buttons and other graphical elements. That’s because each entry in a menu portrays an instant explanation of the action it is to perform (at least it should, although in poorly designed menus, this isn’t always true). ✦ Menus are easy to localize, unlike bitmap graphics that need to be recreated every time the language changes. By switching a cast member, you can make a Director menu change the language it displays. Tip
Menus are most useful to beginners — people who aren’t familiar with the product. As users become more proficient, they tend to rely more on shortcut keys or, if they’re available, button bar icons. Remember this as you work on your own design. When you’re putting together a menu, if you aim it toward the novice, you can’t go wrong.
Creating Your Own Pull-Down Menu System You might not yet have given much thought to including a pull-down or drop-down menu in your Director movie, but you won’t want to neglect this feature. Most off-theshelf applications include some sort of pull-down menu system. In fact, menus are so commonplace that nobody even thinks about them — until they’re not available. Fortunately, menu systems are easy to implement in Director. You can build a menu system to handle tasks such as these: ✦ Executing commands and access features ✦ Navigating within the application ✦ Controlling system settings (such as audio volume) Building a pull-down menu requires a few easy steps: 1. Create a field cast member that includes specific keywords that construct the menu and its options. 2. Install the menu in the movie by using the installMenu command. 3. Create a movie projector. 4. Play and test the projector.
3486-6 ch22.f.qc
7/24/00
5:54 PM
Page 773
Chapter 22 ✦ Menus and Dialog Boxes
Creating a menu by using a field cast member Menus are created by using a field cast member that begins with the menu keyword followed by the name of the menu. To create a File menu like the one found in nearly every application, for example, you type the following text as the first line in a field: menu: File
On subsequent lines in the field, you type the options that you want to appear on the menu. You add options to the menu by using the following syntax: menuItem | LingoInstruction
The vertical bar (|) character (known as a pipe in most programming languages) separates the text of the menu option from the Lingo instruction that is executed when the option is selected by the user. On most keyboards, the pipe or vertical bar character is generated by pressing Shift+\. Director does not support a direct method of executing multiple commands from a single menu item on a user-defined menu. However, you can create a workaround. To implement this arrangement on the user-defined menu, create a menu option to call a user-defined handler that you construct with the desired instructions. On the CD-ROM
The movie mars scanner 1.dir is in the EXERCISE:CH22 (EXERCISE\CH22) folder on this book’s companion CD-ROM.
A typical File menu (on a Windows or Macintosh system) includes a Save option and a Quit (or Exit) option. Let’s see how to add these options to the File menu. Open the movie mars scanner 1.dir on the CD-ROM. Create a new field member and the text shown in Figure 22-1. Figure 22-1: Use field members to create menus, not text cast members.
Caution
A space before and after the vertical bar character is optional. If you do add spaces, those spaces will be part of the name for that menu item. Also, adding spaces becomes an issue when you are referring to these menu items from Lingo, because you must use the exact name.
773
3486-6 ch22.f.qc
774
7/24/00
5:54 PM
Page 774
Part V ✦ Further into Lingo
In this example, the saveMovie command saves the current movie, using the movieName property. When the Quit menu item is chosen, the Lingo command halt executes. In a projector, the halt command causes the program to quit, but when authoring, it just stops the movie. Lingo does have a quit command, but if you use that command in authoring mode, it doesn’t just stop the movie, it causes Director to quit (which can be inconvenient). For this menu to be used in the program, you need to use the installMenu command. Because we want this menu to appear as soon as the movie runs, a good place for the code to insert it is in a prepareMovie handler. Create a movie script and type the code shown in Figure 22-2.
Figure 22-2: Using the installMenu command
Figure 22-3 demonstrates how this menu appears when the movie is played back in authoring mode. The menu appears in the upper-left corner of the screen, not on the Stage area. Save this movie as mars scanner 2.dir.
Figure 22-3: The custom File menu as it appears in authoring mode Tip
When you add menus and menu options, be sure to use the capitalization that you want displayed. Capitalization for the Lingo instructions is not important, because Lingo is not case sensitive. For the menus and their contents, however, what you type is what is displayed on-screen.
In Windows, graphics and other objects on the Stage are shifted down because the menu bar occupies a 24-pixel band across the top of the Stage, as shown in Figure 22-4. On the Mac, the menu bar goes right over the Stage graphics. This functionality is irritating and did not exist in earlier versions of Director. It makes cross-platform development more difficult, because each platform displays menu bars in a different manner. We hope that Macromedia will change this in a future version.
3486-6 ch22.f.qc
7/24/00
5:54 PM
Page 775
Chapter 22 ✦ Menus and Dialog Boxes
Figure 22-4: A Windows pull-down menu as it appears during playback from a projector
You need to keep this in mind when you add a menu to a movie. To avoid screen layout problems, you must: ✦ Shift everything on the Stage down 24 pixels from where you normally place the sprites. ✦ Leave the bottom 24-pixel band across the screen blank. Note
This downward shift of objects on the Stage does not increase the Stage size; it just pushes the bottom 24-pixel band into never-never land.
You can display more than one pull-down menu at a time on the Stage. To do so, you simply define the first menu (as just described), and then sequentially define each additional menu in the same field cast member. Each new menu and each new menu option within the field must start on a new line. Open the mars scanner 2.dir movie from the EXERCISE:CH22 (EXERCISE\CH22) folder on the CD-ROM. Open member 6, which is the field “myMenu”. Add the text shown in Figure 22-5. The field cast member creates a menu bar with four command menus (@, File, Location, Infrared). The File menu part is already there. If you are a Mac user, add the first two lines before the menu: File line (the menu: @ and About Mars Scanner lines); Windows users should leave those off.
Figure 22-5: Defining the menus for a program
775
3486-6 ch22.f.qc
776
7/24/00
5:54 PM
Page 776
Part V ✦ Further into Lingo
This menu: @ instruction only adds the Apple menu, not any options. You must create the desired options just as you would for any other menu that you want included in your movie. By convention, the Apple menu is always the first menu on the menu bar (starting at the upper left edge of the screen), so the menu: @ instruction (followed by the options you want available) should always be listed as the first menu entry in the field cast member. If you leave this menu off, then the Apple and Application menus will not be available. The instructions for the menus are stored in the same field, one after the other. If you put a RETURN character between menus, it will appear as a blank menu item. The menu Location in Figure 22-5 has four menu items. When one is selected, the Lingo to the right of the bar is executed. The Infrared menu has one item. The Lingo it executes is a handler in a movie script. Calling a handler enables you to execute several lines of Lingo. Save this movie as mars scanner 3.dir. Figure 22-6 shows the Apple menu.
Figure 22-6: When you add the @ menu, the Apple and Application menus become available on a Macintosh.
3486-6 ch22.f.qc
7/24/00
5:54 PM
Page 777
Chapter 22 ✦ Menus and Dialog Boxes
Installing a menu After you have created the menu, you must install it, using the Lingo installMenu command as follows: installMenu fieldNameorNumber
Replace the fieldNameorNumber parameter with the name or number of the field cast member that contains the menu instructions. In the following on prepareMovie handler, the menu is stored in a field that is cast member 6: on prepareMovie installMenu 6 end
In this next example, the menu is stored in a field cast member named “myField”. on prepareMovie installMenu “myField” end
The initial installation of a menu is typically handled from within a movie script, but you can also install a menu from a cast, sprite, parent, or frame script. For instance, you can attach a cast member script to a button that, when clicked, switches from one menu to another. You simply issue the installMenu command and name a new field cast member that includes the new menu. To remove the menu, use the following form of the installMenu command: installMenu 0
Finishing the job To finish the project, you need to save the movie and create a projector, play it, and test it. Be sure that the following are true: ✦ The menu options work as expected. ✦ The area used by the menu bar does not shift Stage objects down and hide important text or images. ✦ You have provided all necessary menu options. Additionally, you might want to enhance your menu, by adding such features as the following: ✦ Keyboard shortcuts ✦ Checkmarks that indicate the currently selected options
777
3486-6 ch22.f.qc
778
7/24/00
5:54 PM
Page 778
Part V ✦ Further into Lingo
✦ Grayed-out (disabled) options ✦ Formatting (boldface, underline, or shadow) for menu options
Adding keyboard shortcuts to a menu Most applications provide keyboard shortcuts, or quick keys, to access frequently used features. These keyboard shortcuts perform the same function as choosing a menu option. You can easily add keyboard shortcuts to each menu item in your Director movie. On a Macintosh system, keyboard shortcuts are typically assigned to the Command key plus a letter; on a Windows system, a combination of the Ctrl key plus a letter is used. To add the shortcut, you simply edit the field that contains your menu’s instructions and add the slash ( / ) character, which represents the Command (Ctrl) key, followed by the name of the key you want to use in this key combination to invoke the menu option. On the CD-ROM
You can find the movie mars scanner 3.dir in the EXERCISE:CH22 (EXERCISE\ CH22) folder on the CD-ROM that accompanies this book.
Open the movie mars scanner 3.dir on the CD-ROM. You can add shortcuts by changing the menu instructions to match those shown in Figure 22-7. Figure 22-7: Adding shortcuts to the menu
In this example, either press Command+S on a Macintosh or press Ctrl+S on a Windows system; this is the same as choosing the File ➪ Save command. Pressing Command+Q on a Macintosh or Ctrl+Q in Windows is the same as choosing the File ➪ Exit command. Figure 22-8 shows how the shortcuts appear in the menu.
Figure 22-8: A menu with keyboard shortcuts
3486-6 ch22.f.qc
7/24/00
5:54 PM
Page 779
Chapter 22 ✦ Menus and Dialog Boxes
Make it intuitive! When you select quick keys (keyboard shortcuts), use commonly accepted intuitive combinations. Users of Macintosh and Windows workstations expect consistency from application to application. The following quick-key conventions will be familiar to your users:
✦ Command+C (Ctrl+C) invokes the Copy command. ✦ Command+N (Ctrl+N) invokes the New Document command. ✦ Command+P (Ctrl+P) invokes the Print command. ✦ Command+S (Ctrl+S) invokes the Save command. ✦ Command+V (Ctrl+V) invokes the Paste command. ✦ Command+X (Ctrl+X) invokes the Cut command.
Adding check marks To add a check mark to a menu item, use the checkMark of menuItem property. To display the check mark, you can issue an instruction that uses this syntax: set the checkMark of menuItem itemName of menu menuNameorNumber to True
In this instruction, itemName is replaced with the menu item’s name or number that you want preceded by a check mark. If you use a number to identify the menu item, you must start counting with the first item on the menu. The menuNameorNumber parameter is replaced with the menu’s name or number. The menu number is based on the menu’s position, counting from left to right on the menu bar. Note
On the Macintosh, the Apple Menu is menu 1. Be sure to include it when you determine the menu number.
Continuing with the mars scanner 3.dir, you could set the check mark to be in front of the first item in the Location menu to show that is where you are. In the Message window, type what is shown in Figure 22-9. You can freely use names or numbers for menus and menu items. Names are often better to use in your code. Numbers are convenient when you just want to test something quickly in the Message window. To remove the check mark, issue this instruction: set the checkMark of menuItem 1 of menu 3 to FALSE
779
3486-6 ch22.f.qc
780
7/24/00
5:54 PM
Page 780
Part V ✦ Further into Lingo
Figure 22-9: Menus and menuItems can be referenced by name or number, or by a combination of the two.
Disabling menu items By adding the left parenthesis character — ( — after the menu item name, you can display a menu option as disabled. Disabled menu items appear grayed out and cannot be selected with a mouse click. This is a manual way to do it. Most of the time, however, you will be doing it through Lingo. You use the enabled of menuItem property to enable or disable a menu item. In fact, using Lingo to reset the enabled of menuItem property while a movie is running is really a better solution than creating multiple field cast members to enable and disable menu options. Note
Even if you disable or enable a menu item by “hard coding” the instructions in the field cast member, you can use Lingo to change the property’s setting.
The full Lingo syntax to enable or disable a menu entry is as follows: set the enabled of menuItem itemName of menu menuName to state
In this instruction, the itemName is replaced with the menu item’s name or number. If you use a number to identify the menu item, you must start counting with the first item on the menu. The menuName parameter is replaced with the menu’s name or number. The menu number is based on the menu’s position, counting from left to right on the menu bar. The last parameter, state, is either true or false, depending on whether you want the menu item enabled or disabled, respectively. As Figure 22-10 shows, you can set the enabled of menuItem many different ways. After this property is set to FALSE, the user cannot select the menu item.
3486-6 ch22.f.qc
7/24/00
5:54 PM
Page 781
Chapter 22 ✦ Menus and Dialog Boxes
Figure 22-10: Just like the checkMark of menuItem, the enabled of menuItem can be set many different ways.
It is possible to use Lingo to disable a menu item with a visible check mark, but it doesn’t make much sense to do so. In general, for any given menu item you should decide whether you want it to switch between the enabled and disabled state, or between the checked and unchecked state. The best way of assigning the correct behavior is to question whether it makes sense to display the menu item’s state as turned ON or OFF. If it does, use a check mark. On the other hand, if you want to indicate whether a menu item is currently available or not, use the enabled/disabled pair. For example, a menu item that saves work in progress makes no sense as a toggle — either you can save the file or you can’t, and if you can’t (because you have not made changes to the file), then the menu item should be disabled. On the other hand, a menu item that turns background music ON or OFF is a perfect toggle, and you should use a check mark to visibly indicate whether the music is audible or inaudible.
Adding text formatting to a menu item You can add some formatting to your menu, but because the Macintosh and Windows operating systems have their own idiosyncrasies, the menus you create for a Macintosh system might not be supported under Windows (and vice versa). We recommend creating two versions of your menus, one for each platform. Before actually installing a menu, check which platform the user is running, and then install the Macintosh or Windows menu as appropriate. Tables 22-1 and 22-2 show the options that are supported on the Macintosh and Windows platforms, respectively. Although more options are available for Macintosh programs, many of the options aren’t often used these days. The Mac formatting commands can appear before or after the menu item’s text, as in the following example: