1. Trang chủ
  2. » Công Nghệ Thông Tin

Tài liệu Foundation Flash CS5 For Designers- P16 docx

50 393 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 50
Dung lượng 1,31 MB

Nội dung

BUILDING STUFF 729 hugging the left edge of SeekBar. As it is, however, the numbers are easy. To coordinate its movements with SeekBar, all SeekKnob has to do is know SeekBar‘s horizontal position ( seekBar.x ) and take into consideration SeekBar’s width ( seekBar.width ). To position the knob along the bar’s left edge, all you need to do set its MovieClip.x property to the bar’s MovieClip.x property. To slide it halfway across, set the knob’s x property to the x property of the bar, plus half of the bar’s width. To shove it all the way over, set its x property to bar’s, plus the full width of the bar. Keep this principle in mind as we work through the seek slider ActionScript. To begin, copy another one of the commented code block headers and paste it below the last bit of ActionScript ( nextHandler() , from the Buttons section). Change the header’s caption to Seek slider , and then type in the following ActionScript, so that your code looks like this: //////////////////////////////////////// // Seek slider //////////////////////////////////////// // prep seekKnob.buttonMode = true; // events seekKnob.addEventListener(MouseEvent.MOUSE_DOWN, seekStartDrag); Like the Prev, Play/Pause, and Next movie clip “buttons,” the seekKnob instance needs to have its buttonMode property set to true . When the user clicks it, you want the user to be able to start dragging that knob, so the MouseEvent.MOUSE_DOWN event is associated with a custom function you’re about to write, called seekStartDrag() . That function is triggered when the user clicks the mouse ( MOUSE_DOWN ) on the seekKnob instance. Type the following new ActionScript: function seekStartDrag(evt:MouseEvent):void { if (song != null) { pauseSong(); rect = new Rectangle(seekBar.x, seekKnob.y, seekBar.width, 0); seekKnob.startDrag(true, rect); stage.addEventListener(MouseEvent.MOUSE_UP, seekStopDrag); } }; If the song instance isn’t null — for example, it’s null before a song is chosen from the combo box—then pause the song, in case it’s playing. Next, define a Rectangle instance (stored in the rect variable), which will be used to constrain dragging to the desired location. Rectangle instances are specified at a particular location (x and y) and at a particular width and height. In this case, we want the knob to be draggable only from the left side of the bar ( seekBar.x , the first parameter) to the right side ( seekBar.width , the third parameter). Its vertical position is fine where it is ( seekKnob.y , the second parameter) and shouldn’t vary from that, which means we set the rectangle to a height of 0 (the fourth parameter). www.zshareall.com Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. CHAPTER 14 730 The MovieClip.startDrag() method, invoked on seekKnob , is fed two parameters: true , which snaps dragging to the symbol’s registration point, and rect , which confines dragging to the dimensions just described. Finally, a MouseEvent.MOUSE_UP event handler is associated with the stage, configured to trigger a custom seekStopDrag() function. Why is this association made with the stage, rather than with seekKnob ? Because the user might just drag the mouse off the knob before releasing the mouse ( MOUSE_UP ). If the event handler were associated with seekKnob , then seekStopDrag() wouldn’t be triggered. But when it’s assigned to the stage, that pretty much means the mouse can be lifted anywhere, and the dragging routine will stop. Here’s the seekStopDrag() function. Type the following new ActionScript: function seekStopDrag(evt:MouseEvent):void { seekKnob.stopDrag(); playSong(song.length * (seekKnob.x - seekBar.x) / seekBar.width); stage.removeEventListener(MouseEvent.MOUSE_UP, seekStopDrag); }; The first thing this function does is invoke MovieClip.stopDrag() on the seekKnob instance. That part is easy. The challenge comes in telling the song where to begin playing again, because it all depends on where the knob, as shown in Figure 14-16, is currently positioned along the bar. Figure 14-16. The variables used in the calculation to relate the position of the knob with a time in the song. To illustrate, let’s imagine the user dragged the knob right to the middle, and let’s pretend the song is exactly 60 seconds long. Let’s use those figures and run the math. Here’s the actual expression: song.length * (seekKnob.x - seekBar.x) / seekBar.width Using the numbers we just agreed on, that equates to this: This book was purchased by flashfast1@gmail.com www.zshareall.com Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. BUILDING STUFF 731 60 seconds  (knob's position—bar's position) / bar's width 60 * (329—260) / 138 60 multiplied by the difference between 329 and 260 (namely, 69) is 4,140. Divided by 138, the final number is 30 seconds, which is exactly what’s expected when the knob is dropped halfway across. The final total of the arithmetic equation is fed into the playSong() function, which starts the song from whatever value, in seconds, is provided. The last thing this function does is to tell the stage to stop listening for the MOUSE_UP event, because the event obviously just occurred (since this function handles it). In the playSong() function definition, seekKnob is associated with an Event.ENTER_FRAME event, which tells the knob to continuously update its position according to how much of the song has played. Here’s that function. Type the following new ActionScript: function seekKnobUpdate(evt:Event):void { var pos:Number = seekBar.width * channel.position / song.length; if (!isNaN(pos)) { seekKnob.x = seekBar.x + pos; } else { seekKnob.x = seekBar.x; } }; Here’s that pos variable again (a third one!). This one is unrelated to the other two, except in name. To the authors, pos just seems like an appropriate name for a variable for noting the position of something. In this case, pos is declared within the scope of this function and set to an expression that effectively does the opposite of the expression shown earlier. Let’s run the numbers again, assuming that, at this very moment, our hypothetical -60-second song has played halfway through. Here’s the actual expression: seekBar.width * channel.position / song.length, It equates to this: bar's width  song's position / song's length 138 * 30 / 60 138 multiplied by 30 is 4,140 (sounds familiar, doesn’t it?). 4,140 divided by 60 is 69. Hold that thought. There may be times when neither channel nor song has a property value that yields a valid number when run through the math. To safeguard against that, an if statement uses the isNaN() function (is Not a Number) to prod the value of pos (which is hypothetically 69). If pos is a valid number—that is, if !isNaN(pos) evaluates to true —then it is added to the current MovieClip.x value of seekBar, the sum of which is bestowed upon seekKnob. Because seekBar’s position is 260, that (added to 69) puts seekKnob at 329, which is exactly halfway across the bar. www.zshareall.com Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. CHAPTER 14 732 The exclamation point ( ! ) in front of the isNaN() function inverts whatever that function says, in the same way that the inequality operator ( != ) means “is not equal to.” If you want to find out if a value is not a valid number, check it against isNaN() . On the other hand, if you want to find out if a value is a valid number, check it against !isNaN() . The flip side of that if statement—meaning, pos is an unusable number—simply sets the knob’s position to the position of the bar, which resets the knob to its original hug-the-left-side location. As the song plays through, this seekKnobUpdate() function is triggered every time the timeline enters a frame, in other words, continuously. This causes the knob to indicate progress until the function is instructed to stop. Go ahead, test the SWF and give it a whirl. The mechanics of the volume slider work in pretty much the same way. A similar knob symbol is instructed to drag within a constrained area. The difference is that the knob’s position in relation to its bar is used to adjust the volume of the currently playing song. In addition, a separate symbol is instructed to follow the knob, whose movement either hides or reveals that symbol behind a mask. Let’s add the code. Continuing below the previous ActionScript, give yourself another code comment heading, this time captioned as Volume slider . Type in these additional new lines: //////////////////////////////////////// // Volume slider //////////////////////////////////////// // prep volumeSlider.volumeKnob.buttonMode = true; // events volumeSlider.volumeKnob.addEventListener(MouseEvent.MOUSE_DOWN, volumeStartDrag); The volumeKnob instance is nested inside volumeSlide r , and that’s because those movie clips are nested. Other than that, there is nothing remarkable about this addition. Let’s keep rolling. Enter the following new ActionScript, which defines the volumeStartDrag() function just referenced: function volumeStartDrag(evt:MouseEvent):void { rect = new Rectangle(8, volumeSlider.volumeKnob.y, volumeSlider.volumeBar.width - 8, 0); volumeSlider.volumeKnob.startDrag(true, rect); volumeSlider.volumeKnob.addEventListener(MouseEvent.MOUSE_MOVE, volumeAdjust); stage.addEventListener(MouseEvent.MOUSE_UP, volumeStopDrag); }; www.zshareall.com Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. BUILDING STUFF 733 As with the other slider, rect is set to a new Rectangle instance when the knob is clicked and fed appropriate values. In this case, the values are purposefully tweaked to move the knob in from the left edge just a bit. Why? Because if the volume knob were dragged all the way to the left, it would completely obscure the red movie clip rectangle behind the slanted five-column mask. Letting it go almost all the way to the left—8 pixels shy, in this case—looks good visually. Where did the 8 come from? Even though it is an arbitrary figure, sometimes these numbers just appear, and you learn to live with them (but they still make you feel a bit weird because they don’t quite adhere to the normal programmatic logic). The startDrag() method is invoked on volumeKnob, and again the stage is associated with a MouseEvent.MOUSE_UP event to stop the dragging. This time, though, an additional event ( MOUSE_MOVE ) is associated with a custom function named volumeAdjust() . Let’s look at both of those. Enter the following new ActionScript: function volumeStopDrag(evt:MouseEvent):void { volumeSlider.volumeKnob.stopDrag(); stage.removeEventListener(MouseEvent.MOUSE_UP, volumeStopDrag); volumeSlider.volumeKnob.removeEventListener(MouseEvent.MOUSE_MOVE, volumeAdjust); }; function volumeAdjust(evt:MouseEvent):void { volumeSlider.volumeBar.x = volumeSlider.volumeKnob.x; if (channel != null) { xform = channel.soundTransform; xform.volume = (volumeSlider.volumeKnob.x - 8) /  (volumeSlider.volumeBar.width - 8); channel.soundTransform = xform; } }; The volumeStopDrag() function is old hat by now. It stops the dragging and stops the MOUSE_MOVE handler. Let’s break down the volumeAdjust() function. First off, it sets the position of volumeBar to the position of volumeKnob. That hides and reveals the red rectangle behind its mask in concert with the knob’s position. After that, assuming channel is not null , the xform variable—declared early on—is set to the SoundChannel.soundTransform property of the channel instance. This gives xform a SoundTransform.volume property, whose value is set in terms of volumeKnob’s position (accounting for that 8-pixel shy span) in relation to the width of volumeBar. www.zshareall.com Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. CHAPTER 14 734 The VolumeBar symbol happens to be 50 pixels wide, so let’s run the numbers assuming the knob has been dragged halfway across the valid range. (Normally, halfway across would be 25, but we’re adding half of that 8-pixel buffer, so half is 29 here.) Here’s the actual expression: (volumeSlider.volumeKnob.x - 8) / (volumeSlider.volumeBar.width – 8) It equates to this: knob's position - 8, divided by bar's width - 8 29 - 8 / 50 - 8 29 minus 8 is 21. 50 minus 8 is 42. 21 divided by 42 is 0.5, or 50%. xform ’s volume property is set to 0.5, and then the final line reassigns xform to the channel.soundTransform property, which cuts the volume in half. Remember that this function is triggered every time the mouse moves, as it drags the knob. Almost in the clear! Finishing up the controls The rest of the controls require barely a flick of the tail. All we need to do is hide the LoadingDisplay symbol (the spinning dots) by default and handle the Event.ID3 event. Let’s do it. Add another block of code that looks like this: //////////////////////////////////////// // Loading display //////////////////////////////////////// loadingDisplay.stop(); loadingDisplay.visible = false; This stops and hides the spinning dots. Now, enter your final block of code, and make it look like this: //////////////////////////////////////// // Song Data //////////////////////////////////////// function soundID3Handler(evt:Event):void { songData.text = song.id3.artist + ": " + song.id3.songName + " (" + song.id3.year + ")"; }; This function is triggered whenever an MP3’s ID3 tags are encountered. Tag information is retrieved from the Sound.id3 property of the song instance—here, song.id3.artist , .songName , and .year —and concatenated into a string fed to the songData text field’s text property. www.zshareall.com Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. BUILDING STUFF 735 ID3 tags have nothing to do with ActionScript 3.0 per se. The concept is part of the MP3 file format, and it just happens to be supported by ActionScript. On their own, ID3 tag names aren’t especially easy to read. The tag intended for the artist’s name, for example, is TPE1; the publication year is TYER, and so on. ActionScript provides friendly names for the most popular tags— comment , album , genre , songName , artist , track , and year — but the others are available by their less intuitive tag names. To see the full list, look up the Sound class in the ActionScript 3.0 Language and Components Reference, and then skim down the Properties heading until you come to id3 . Click that listing. Test your MP3 player to give it a spin. Kick the tires a bit. Evaluating and improving the MP3 player Even with the best of planning, you might be surprised to find that some aspects of a project, including its faults, don’t make themselves apparent until the work is done—or at least, until a first draft is done. (Some projects never do seem to end! Hey, at least it’s a paycheck.) In Chapter 15, we discuss the idea of planning an FLA beforehand—the authors do believe in the practice, with a passion—but sometimes you can’t tell how a car is going to handle until you actually wrap your fingers around the steering wheel and slam your boot on the gas pedal. In this case, you may have noticed that every time a new song plays, the volume jumps back up to 100 percent, no matter where you drag the volume slider. Worse, when this happens, the volume is audibly at full, even though the slider might be positioned all the way to the left. That’s a bug, and we’re going to fix it. In addition, you might want the player to cycle through the whole playlist, rather than simply stop after a song ends. You might also want the first song to start playing automatically. All of these options are possible, and thanks to the thoughtful arrangement of our existing ActionScript, they’re easy to implement. Let’s tie up this MP3 player with a bow. First, let’s address the volume bug. Locate the volumeAdjust() function, just above the Loading display block, and give its evt parameter a default value of null —like this (revision in bold): function volumeAdjust(evt:MouseEvent = null):void { What does this do? Without the addition, this function requires a MouseEvent parameter, which pretty much means it must be triggered in response to an event, which passes in the MouseEvent automatically. By giving the evt parameter a null value by default, you’re making the parameter optional. This means the volumeAdjust() function can be triggered from anywhere, as an event handler or not. Locate the playSong() function and update it to look like this (revision in bold): www.zshareall.com Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. CHAPTER 14 736 function playSong(pos:Number = 0):void { channel = song.play(pos); volumeAdjust(); btnPlay.gotoAndStop("pause"); seekKnob.addEventListener(Event.ENTER_FRAME, seekKnobUpdate); }; Just like that, the bug is fixed! The playSong() function actually sets the newly loaded song in motion, to speak, and associates the song instance with the channel instance. With channel updated, the xform variable, referenced inside volumeAdjust() , has what it needs to check the current position of the volume slider and adjust the volume accordingly. Since we’re in the playSong() function anyway, it’s the perfect time to add a new event listener that will allow the player loop through its playlist. Update the playSong() function again to look like this (revision in bold): function playSong(pos:Number = 0):void { channel = song.play(pos); channel.addEventListener(Event.SOUND_COMPLETE, nextHandler); volumeAdjust(); btnPlay.gotoAndStop("pause"); seekKnob.addEventListener(Event.ENTER_FRAME, seekKnobUpdate); }; Once the channel variable is updated, it’s associated with the already-written nextHandler() function in response to the Event.SOUND_COMPLETE event, which is dispatched when the sound channel of a currently playing sound reaches the end of the file. Remember that the nextHandler() function is also associated with the MouseEvent.CLICK event, which is triggered when someone clicks the Next button. The MouseEvent class inherits some of its functionality from the Event class, and in this case, it’s safe to strongly type the evt parameter inside the nextHandler() function as Event . This is because, at rock bottom, both Event and MouseEvent instances are ultimately instances of Event . Locate the nextHandler() function and change it to look like this (revision in bold): function nextHandler(evt:Event):void { Finally, to make this MP3 player begin in ”auto-play” mode, locate the completeHandler() function, just above the ComboBox block, and add the new lines shown in bold: function completeHandler(evt:Event):void { songList = XML(evt.target.data); songsCB.dataProvider = new DataProvider(songList); loadSong(songList.song[1].@data); songsCB.selectedIndex = 1; }; www.zshareall.com Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. BUILDING STUFF 737 When the XML playlist fully loads, completeHandler() is triggered. It populates the ComboBox component. In addition to that, it now invokes the loadSong() function and feeds it the filename from the first <song> element that actually refers to an MP3 file (remember that the very first <song> element— songList.song[0] —doesn’t contain file data). After that, the function updates the ComboBox component to its first song entry (the one after the filler Select a song entry), by setting its selectedIndex property to 1 . Test your movie again and, while you’re tapping your feet, give yourself a pat on the back. Going mobile A year or so ago one of the authors, in response to a question around developing Flash projects for mobile devices, woke up the audience when he commented, “Not me. I’d rather drive chop sticks into my eyeballs.” He didn’t make this comment to be funny but to express to the audience that mobile is a frustrating and bewildering space fraught with competing operating systems, varying Flash Players requiring different versions of ActionScript with some playing video and others not, devices with varying screen sizes…we think you get the picture. Just to make things even more interesting, Apple, in April 2010, dropped an atomic bomb on developers. They essentially told them they have to use Apple-approved development tools to create applications for the iPhone. Though widely regarded as a slap against Adobe and Flash, it became pretty clear that that if you wanted to play in Apple’s sandbox, you had to use their toys. This was a rather interesting development because the “nobody cares how you did it they just care that you did it” approach to developing applications for the iPhone was no longer in play. This naturally had a rather major impact on us because the iPhone compiler—a choice in the New Document list—went out the window along with our plans for this chapter. Over the weeks following this uproar the mobile community started looking for a new sandbox, which let them use their toys. As such there developed a loose consensus that the Google mobile OS, Android, might just be the place to go. Just to make sure that everyone knew that the Android sandbox was open for business Google announced, in May 2010, an updated version of the OS—code name Froyo—and Adobe, minutes later on that very same stage, made it crystal clear that Flash Player 10.1 was rock steady and ready to go to work with Froyo and practically every other smartphone on the planet (…elephant in the room excepted). In this final section of the chapter, we are going to develop a small game—Whack-A-Bunny—that will be developed for play back on a Google Nexus One Android device, which is the test device used by Google and chipset manufacturer Qualcomm. To start, we need to take a stroll over to Device Central. A quick tour of Device Central Device Central has been around for while. Its purpose is to let you choose a variety of devices from a variety of manufacturers and test your project in an environment that emulates how a user would actually use the device and your application. When you install any of the Adobe Collections—we use the Master Collection—Device Central is installed with all of the other applications in the bundle. Let’s go check it out: www.zshareall.com Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. CHAPTER 14 738 1. Launch Device Central. When it launches, you will see the Start page shown in Figure 14-17. Figure 14-17. The Device Central Start page As you can see, the page is quite similar to the Flash CS5 Start page in that it is divided into distinct sections:  Open for Testing: Any files that you have tested in Device Central will be listed here, or you can click the Browse button to navigate to the file to be tested.  Device Profiles: Click the Browse Devices button, and you will be taken to a list of every device resident in Device Central. There are quite a few of them, but don’t let the list intimidate you. You get to choose which devices will be used. The listing lets you pick them.  Create New Mobile: This area is new to Device Central CS5 and contains a listing of the applications that have a direct ‘hook” into Device Central. Click an application, and Device Central doesn’t launch the application; it opens the New Document panel in Device Central. When you are there, you can choose the player version, ActionScript version, and content type. From there, you choose your test player and click the Create button to launch the application chosen. We’ll show you how in a couple of minutes. 2. Click the Browse Devices button to open a list of devices. 3. Scroll down the list and, as shown in Figure 14-18, locate the Google Nexus One device. The categories are self-explanatory. The device, if it has an image of the device, is an actual template of the device. The odd icon in the Location area—a globe over a handset—tells you the device is found on your hard drive. Just the globe indicates an online version will be used. You are also told the version of Flash Player that is used on the device, the screen size, and the Creator category that indicates who created the Device Profile, which, in this case, is Adobe. www.zshareall.com Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. [...]... Download AIR for Android Extension for Flash CS5 link, and the page shown in Figure 14-28 will open Download both the extension and the documentation Figure 14-28 The AIR for Android Extension is available on the Adobe labs site 4 When the file finishes downloading, double-click the zxp file This will open the Adobe Extension Manager CS5, and the extension will be automatically installed into Flash When... need to install the AIR for Android extension To get it, point your browser to http://labs.adobe.com/technologies/air2/android/, and click the Sign Up link Adobe Labs is a site where public betas of new technologies are available for you to “kick the tires.” Alternatively, go to www.adobe.com and search for AIR for Android 2 Create an account, and you will be taken to the AIR for Android Developer Prerelease... practical experience using Flash CS5 Now that you’ve learned the ropes and have practiced numerous techniques, let’s concentrate on the end game of the Flash design and development process: publishing your file 756 www.zshareall.com Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Chapter 15 Optimizing and Publishing Flash Movies When it comes to Flash on the Web, a common... about how to improve the user experience Here’s what we’ll cover in this chapter: Understanding how Flash movies are streamed to a web page Using the Bandwidth Profiler to turbo-charge movies Optimizing Flash movies Converting a Flash movie to a QuickTime video Choosing web formats Publishing a SWF for web playback Dealing with remote content 757 www.zshareall.com Please purchase PDF Split-Merge on... text file, which uses HTML—a formatting language of tags and text—to define how a page should look and behave This is important, because your Flash movies should always be found in an HTML wrapper This book was purchased by flashfast1@gmail.com The concept of hyperlinks and hypertext was around long before the Internet The gentleman who managed the atomic bomb project for the United States during World... article for the Atlantic Monthly in July 1945 that proposed a system of linking all information with all other information The article was entitled “As We May Think,” and you can still read it at www.theatlantic.com/ doc/194507/bush An HTML page may be nothing more than a text file, but it can contain links to other assets, such as CSS files, JPEGs, GIFs, and your Flash movies These links take the form... click the phrase “Play Ball” (hip for “Enter this site”) to start the neverending Flash intro Of course, some Flash people will take their sense of humor to outrageous levels One of the best was a site that really was nothing more than one massive intro is www.zombo.com To deal with the bloat issue, it is critical that you understand the underlying technology behind your Flash movie This means we need... tutorials for a number of online tutorial sites and, included in the folder, is a list of links to some of his more popular tutorials Enjoy! What you have learned Rather than list what we covered in this chapter, we think it is more important to take a broader view of that statement Step back for a moment and think about what you knew when you first laid this book on your desk and flamed up Flash CS5 The... desk So, users began to see the button not as a Skip Intro option but as a “skip site” warning This resulted in Flash gaining a rather nasty reputation for bloat, which it still has not shaken entirely Of course, the Flash community does have quite a sense of humor One of the more popular Flash sites of the time was named “Skip Intro.” You can watch it via Archive.org’s Wayback Machine at http://web.archive.org/web/20011214005850/... we’re dealing with here It is the prudent Flash designer who approaches technology with a dose of pragmatism and does not assume a constant flow This has implications for your design efforts, and we will get into those implications shortly You need to regard the pipe and data transmission in much the same manner you regard your local highway It may have six lanes for traffic and a posted speed limit of . { xform = channel.soundTransform; xform.volume = (volumeSlider.volumeKnob.x - 8) /  (volumeSlider.volumeBar.width - 8); channel.soundTransform = xform;. , the xform variable—declared early on—is set to the SoundChannel.soundTransform property of the channel instance. This gives xform a SoundTransform.volume

Ngày đăng: 15/12/2013, 01:16