you-get下载b站选集
Sadly, sound within Flash projects is often included as an afterthought – if it’s included at all. Hurried, last-minute sound additions typically amount to no more than a clichéd loop that serves little purpose. If you ever find yourself in the position of importing a sound clip into a project without a clear idea of why you’re doing it, stop and repeat the Flash designers’ mantra: bad use of sound can destroy the entire user experience.
可悲的是,Flash项目中的声音通常是事后才考虑的-如果已包含在内。 匆匆忙忙地添加最后一分钟的声音通常只不过是没有什么用处的陈词滥调。 如果您发现自己将声音片段导入到项目中时却不清楚为什么要这么做,请停止并重复Flash设计师的口头禅: 不良地使用声音会破坏整个用户体验 。
In this age of digital media, sound can and should be a part of the online environment. A little sound can go a long way toward enhancing and solidifying the user experience. Even a simple "click" sound can provide valuable auditory feedback, provided it’s used in the right manner. But beware overloading your projects with sound "just for the sake of it." The use of sound, then, is a question of balance.
在这个数字媒体时代,声音可以而且应该成为在线环境的一部分。 一点声音可以大大增强和巩固用户体验。 如果正确使用,即使是简单的“喀哒”声也可以提供有价值的听觉反馈。 但是请注意,“仅仅为了它”会使声音过载。 因此,声音的使用是一个平衡的问题。
Note that you can download this chapter in pdf format if you’d prefer to read this content offline.
请注意,如果您想离线阅读此内容,则可以pdf格式下载本章 。
This is one of those golden questions, and the answer depends on the type of project you’re developing . Some productions don’t require any sound when viewed in isolation; yet, when incorporated into a larger project, they call for some degree of aural enhancement. If a project is heavily related to sound, then it should definitely involve an appropriate variety of audio clips.
这是那些黄金问题之一,答案取决于您正在开发的项目类型。 当单独观看时,某些作品不需要任何声音。 但是,当合并到一个较大的项目中时,它们需要一定程度的听觉增强。 如果一个项目与声音密切相关,那么它绝对应该包含各种适当的音频片段。
Always consider your work from the perspective of users: will the addition of sound increase their enjoyment of the project? Including short or long musical loops, sound bytes, or a narrative can greatly increase the appeal of an interface, but may also detract from other content and become extremely annoying after just a short while. Consider the following examples of possible Flash projects and think about sound might benefit them. Your choice could include sound effects, musical loops, narratives, or, of course, nothing at all.
始终从用户的角度考虑您的作品:声音的增加会增加他们对项目的享受吗? 包括短或长的音乐循环,声音字节或叙事可以极大地增加界面的吸引力,但也可能减损其他内容,并在短时间后变得非常烦人。 考虑以下可能的Flash项目的示例,并考虑声音可能会使它们受益。 您的选择可能包括声音效果,音乐循环,叙述,或者,当然什么都没有。
Looping animation 循环动画 Single level menu system 单级菜单系统 Multilevel menu system 多级菜单系统 Multi-paged Flash site 多页Flash网站 Flash form Flash表格 Streaming video content 流视频内容Quickly run through these examples in your head. It’s not difficult to see what will and won’t work for different projects. Over time, you’ll become increasingly adept at making decisions about when and how to add sound to your projects.
在您的脑海中快速浏览这些示例。 不难看出什么将适用于不同的项目。 随着时间的流逝,您将变得越来越擅长于决定何时以及如何向项目中添加声音。
One of the major benefits of digital sound is its flexibility. Audio processing software such as Steinberg Wavelab makes it easy to edit, modify, loop, and add effects to sounds. You can take a ten-second section from one audio loop, paste it into another, or paste it across multiple tracks, with no more difficulty than editing a Word document. The advanced sound processing tools that are now available, combined with a microphone and your own imagination, allow you to create a huge array of audio clips. If you’re pushed for time or need extra inspiration, there are many online resources from which you can download free clips or purchase collections of clips for use in your projects.
数字声音的主要优点之一是灵活性。 诸如Steinberg Wavelab之类的音频处理软件可轻松编辑,修改,循环播放和添加声音效果。 您可以从一个音频循环中提取一个十秒钟的片段,将其粘贴到另一个音频循环中,或者将其粘贴到多个轨道中,这与编辑Word文档相比没有什么困难。 现在可用的高级声音处理工具,再加上麦克风和您自己的想象力,使您可以创建大量的音频剪辑。 如果您时间紧张或需要其他灵感,可以从许多在线资源中下载免费的剪辑或购买剪辑集以用于项目。
The application of sound to your projects should not be taken lightly. You need to pay attention to a number of factors if the effects are to be successful – most notably, timing, volume, and composition. Remember, you’re seeking to enhance your visual messages rather than work against them, so your choice of sound is important. A manic techno loop attached to the submit button of a Flash form may well provoke visitors to close the browser. On the other hand, if you give users subtle feedback that the form has been submitted, they’ll likely gain confidence in the interface and continue to interact.
声音在您的项目中的应用不应掉以轻心。 要使效果成功,您需要注意许多因素-最明显的是时机,音量和组成。 请记住,您是在寻求增强视觉信息,而不是与之对抗,因此声音的选择很重要。 附加到Flash表单的“提交”按钮上的躁狂性技术循环很可能会引起访问者关闭浏览器。 另一方面,如果您向用户提供有关表单已提交的微妙反馈,则他们可能会对界面充满信心并继续进行交互。
As you can see, it’s all about context. The appropriate integration of sound into a project can support the efficient communication of the message.
如您所见,这全都与上下文有关。 将声音适当集成到项目中可以支持消息的有效通信。
Flash MX 2004 offers a built-in sound editor, which is fine for simple editing tasks. However, this tool is too basic for most needs: it doesn’t allow you to add effects to your sound selections, for example. I definitely advocate the use of a more powerful sound processor, especially when it comes to trimming, duplicating, and looping clips.
Flash MX 2004提供了内置的声音编辑器,非常适合简单的编辑任务。 但是,该工具对于大多数需求来说太基础了:例如,它不允许您在声音选择中添加效果。 我绝对主张使用功能更强大的声音处理器,尤其是在剪辑,复制和循环播放剪辑时。
You can import a sound clip from the File menu just as you would any other media type. Imported sounds can be applied directly to buttons and button states (Up, Down, Over, etc.), incorporated via streaming external files, included through ActionScripted control in the Action Panel, or added via other means.
您可以像从其他任何媒体类型一样从“文件”菜单导入声音片段。 导入的声音可以直接应用于按钮和按钮状态(向上,向下,上方等),可以通过流外部文件合并,通过“动作面板”中的ActionScripted控件包含,也可以通过其他方式添加。
The addition of a "click" sound to a button’s Down state to simulate a real world mouse click is an example of a basic sound effect. It doesn’t require ActionScript knowledge, but it certainly can be created via script. In the following example, the necessary code is applied to a button called myButton, which references a sound clip that has a linkage identifier of mySound in the Library Panel:
将“点击”声音添加到按钮的“按下”状态以模拟现实世界中的鼠标点击是基本声音效果的一个示例。 它不需要 ActionScript知识,但是肯定可以通过脚本创建。 在下面的示例中,必要的代码被应用到名为myButton的按钮上,该按钮在“库面板”中引用一个链接标识符为mySound的声音剪辑:
myButton.onPress = function () { newSound = new Sound (); newSound.attachSound ("mySound"); newSound.start (); }For more advanced effects, including streaming and abstract playback mechanisms, we need to look under the hood of the ActionScript Sound class to see how we can control sound from within the interface and code conditions. It’s an exciting arena in which you can create interesting and dramatic effects quickly, with just a little imagination.
要获得更高级的效果,包括流和抽象播放机制,我们需要查看ActionScript Sound类的内幕,以了解如何在界面和代码条件下控制声音。 这是一个令人兴奋的舞台,您只需一点点想象力就可以快速创建有趣且引人注目的效果。
As this book is concentrated on the creation of effects via ActionScript, we won’t cover the integration of sound effects into buttons and frames on the timeline. For examples of this, refer to the Flash MX 2004 documentation.
由于本书着重于通过ActionScript创建效果,因此我们将不讨论将声音效果集成到时间轴上的按钮和帧中的问题。 有关此示例,请参阅Flash MX 2004文档。
Let’s start with an interesting volume control that’s linked to an animation.
让我们从链接到动画的有趣的音量控制开始。
In the following demonstration, we scale the vertical height of a movie clip dynamically, tying the volume of a sound associated with the clip to its height. It’s an important example, as it forms the basis for many of the effects you’ll create in future.
在下面的演示中,我们动态缩放影片剪辑的垂直高度,并将与该剪辑关联的声音的音量与其高度相关联。 这是一个重要的示例,因为它构成了将来将要创建的许多效果的基础。
To edit a completed version of the effect, locate volcontrol.fla in the code archive. Setting the Scene
要编辑效果的完整版本, volcontrol.fla在代码档案中找到volcontrol.fla 。 设置场景
Create a new Flash document that’s 500 pixels wide and 400 pixels high. Set the frame rate to 24 fps (Modify > Document…). 创建一个新的Flash文档,该文档的宽度为500像素,高度为400像素。 将帧频设置为24 fps(修改>文档…)。 Rename the default layer Actions, and create two new folders in the Library Panel: Movie Clips and Sound. 重命名默认图层“动作”,然后在“库面板”中创建两个新文件夹:“影片剪辑”和“声音”。 Create a new movie clip symbol in the Movie Clips folder with some arbitrary content. The example in the code archive includes a static text area in which the text "sound effect" appears. 在“影片剪辑”文件夹中创建一个包含一些任意内容的新影片剪辑元件。 代码档案库中的示例包括一个静态文本区域,在该区域中出现文本“声音效果”。Drag an instance of the movie clip to the stage and name it clipper.
将影片剪辑的一个实例clipper舞台上,并将其命名为clipper 。
Select File > Import to Library… and either select reverb.mp3 from the code archive, or import another sound file of your choice. Place it in the Sound folder.
选择“文件”>“导入到库...”, reverb.mp3从代码档案库中选择reverb.mp3 ,或导入您选择的另一个声音文件。 将其放在声音文件夹中。
The file used here is a short, three-second clip of medium quality chosen primarily because it’s a small file.
此处使用的文件是中等质量的短短三秒钟的剪辑,主要是因为它是一个小文件而被选择。
Select the sound clip from the Library Panel, right-click and select Linkage…. Check the Export for ActionScript checkbox and enter reverb as the identifier. 从“库面板”中选择声音片段,右键单击并选择“链接…”。 选中“导出为ActionScript”复选框,然后输入reverb作为标识符。Having added the element we’re going to animate and linked the sound clip for ActionScript export, we can now add the control code.
添加元素后,我们将进行动画处理并链接到声音片段以进行ActionScript导出,现在我们可以添加控制代码。
Example 5.1. volcontrol.fla Actions : 1 (excerpt)
示例5.1 volcontrol.fla操作:1(节选)
MovieClip.prototype.WaveFade = function (minValue, maxValue, period) { this.period = period; this.minValue = minValue; this.maxValue = maxValue; this.count = 0; this.onEnterFrame = function () { var value = (1 + Math.cos (this.count++ * 2 * Math.PI / this.period)) / 2; this._yscale = this.minValue + value * Math.abs (this.maxValue - this.minValue); }; }; clipper.WaveFade (20, 100, 48);Here, we extend the movie clip class with a new method called WaveFade, which scales the clip up and down vertically in a smooth, regular pattern. The method is relatively straightforward, with the exception that careful use of the cosine function is required to produce the values that control the scaling.
在这里,我们使用称为WaveFade的新方法扩展了影片剪辑类,该方法以平滑,规则的模式垂直向上和向下缩放剪辑。 该方法相对简单,所不同的是,需要仔细使用余弦函数来产生控制缩放的值。
The method takes three parameters: minValue, the minimum scale for the clip (as a percentage); maxValue, the maximum scale for the clip; and period, the number of frames in one oscillation (from the maximum scale to the minimum and back again).
该方法采用三个参数: minValue ,剪辑的最小比例(以百分比为单位); maxValue ,剪辑的最大比例; 和period ,一次振荡中的帧数(从最大比例到最小比例,然后又返回)。
The value variable is assigned a value using the cosine function. We add one and then divide the result by two to get values oscillating between zero and one. (Cosine oscillates between one and minus one.) We then multiply that by the difference between the maximum and minimum scaling values to determine the vertical scaling of the clip for each frame.
使用余弦函数为value变量分配一个值。 我们加一,然后将结果除以二,得到在零和一之间波动的值。 (余弦在1到负1之间振荡。)然后,将其乘以最大和最小比例值之间的差,以确定每个帧的剪辑的垂直比例。
Save and preview your work. 保存并预览您的工作。Notice that the _yscale of the movie clip oscillates smoothly from its full height down to 20% and then back up again. Now that we have the animation in place, we can add the sound clip:
请注意,影片剪辑的_yscale从其整个高度向下平滑地振荡到20%,然后再次返回。 现在我们已经有了动画,我们可以添加声音片段:
Add the lines shown in bold to the existing code in the Actions Panel: 将以粗体显示的行添加到“动作”面板中的现有代码:Example 5.2. volcontrol.fla Actions : 1
示例5.2 volcontrol.fla操作:1
MovieClip.prototype.WaveFade = function (minValue, maxValue, period) { this.period = period; this.minValue = minValue; this.maxValue = maxValue; this.count = 0; this.reverb = new Sound (); this.reverb.attachSound ("reverb"); this.reverb.start (0, 999); this.onEnterFrame = function () { var value = (1 + Math.cos (this.count++ * 2 * Math.PI / this.period)) / 2; this._yscale = this.minValue + value * Math.abs (this.maxValue - this.minValue); this.reverb.setVolume (this.minValue + value * Math.abs (this.maxValue - this.minValue)); }; }; clipper.WaveFade (20, 100, 48);We start by creating a new Sound object and attaching the sound from the Library Panel. We start the clip at the beginning (0), and set it to loop 999 times.
我们首先创建一个新的Sound对象,然后从“库面板”中附加声音。 我们从(0)开头开始剪辑,并将其设置为循环播放999次。
Meanwhile, within the onEnterFrame event handler, we set the percentage volume of the sound clip using the same calculation we employed for its _yscale:
同时,在onEnterFrame事件处理程序中,我们使用与_yscale相同的计算方法来设置声音片段的百分比音量:
this.reverb.setVolume (this.minValue + value * Math.abs (this.maxValue - this.minValue));
this.reverb.setVolume (this.minValue + value * Math.abs (this.maxValue - this.minValue));
This is the same code we used to control the clip’s _yscale; in theory, we could replace it with the following:
这与我们用来控制剪辑的_yscale的代码相同; 从理论上讲,我们可以将其替换为以下内容:
this.reverb.setVolume(this._yscale);
this.reverb.setVolume(this._yscale);
However, we avoid using this code as it’s less readable. When you revisit your code at a later date, you might easily become confused if you saw sound properties linked to movie clip properties.
但是,我们避免使用此代码,因为它的可读性较差。 以后当您重新访问代码时,如果看到与影片剪辑属性链接的声音属性,您可能会很容易感到困惑。
Save and preview your work. 保存并预览您的工作。Notice that, as the scale of the clip decreases, so does the volume of the sound. As the scale increases, so does the volume. The addition of scripted sound has enhanced this simple effect, which strengthens the message and creates a more powerful experience.
请注意,随着剪辑的比例减小,声音的音量也会减小。 随着比例的增加,音量也随之增加。 脚本声音的添加增强了这种简单的效果,从而增强了信息并创造了更强大的体验。
In this example, we animate an object across the screen and alter the panning of sound in accordance with the object’s location. Panning involves the movement of a sound in stereo, which can add dynamism to even a single continuous tone. This builds on the previous example to increase your skills with the Sound class using a new method: setPan.
在此示例中,我们在屏幕上为对象设置动画,并根据对象的位置更改声音的声像。 平移涉及立体声中声音的移动,甚至可以为单个连续音调增加动感。 它建立在前面的示例的基础上,使用新方法setPan提高了Sound类的技能。
By default, the panning of a sound is set to 0, but we can use setPan to alter that between the limits of -100 (all sound to the left channel) and +100 (all sound to the right channel).
默认情况下,声音的声像设置为0 ,但我们可以使用setPan在-100 (所有声音发送到左声道)和+100 (所有声音发送到右声道)之间更改限制。
Let’s mirror the movement of a simple animation from left to right with an effect that moves the sound from the left channel to the right.
让我们从左向右镜像一个简单动画的运动,效果是将声音从左声道向右移动。
To skip ahead and modify this effect, locate pancontrol.fla in the code archive.
要跳过并修改此效果, pancontrol.fla在代码存档中找到pancontrol.fla 。
Drag an instance of the movie clip to the stage and name it clipper.
将影片剪辑的一个实例clipper舞台上,并将其命名为clipper 。
Select File > Import to Library… and choose reverb.mp3 from the code archive, or import a sound file of your choice.
选择“文件”>“导入到库...”, reverb.mp3从代码档案库中选择reverb.mp3 ,或导入您选择的声音文件。
Select the sound clip from the Library Panel, then right-click and select Linkage…. Check the Export for ActionScript checkbox, and enter reverb as the identifier.
从“库面板”中选择声音片段,然后右键单击并选择“链接…”。 选中“导出为ActionScript”复选框,然后输入reverb作为标识符。
We’re done setting the scene. It’s time to add the code to bring it all together.
场景设置完毕。 现在是时候添加代码以将它们组合在一起了。
Select the first frame of the Actions layer and add the following code within the Actions Panel. As this is so similar to the previous example, I’ve highlighted the differences in bold: 选择“动作”图层的第一帧,然后在“动作面板”中添加以下代码。 由于这与前面的示例非常相似,因此我以粗体突出显示了不同之处:Example 5.3. pancontrol.fla Actions : 1
示例5.3 pancontrol.fla动作:1
MovieClip.prototype.WavePan = function (minValue, maxValue, period) { this.period = period; this.minValue = minValue; this.maxValue = maxValue; this.count = 0; this.reverb = new Sound (); this.reverb.attachSound ("reverb"); this.reverb.start (0, 999); this.onEnterFrame = function () { var value = (1 + Math.cos (this.count++ * 2 * Math.PI / this.period)) / 2; this._x = this.minValue + value * Math.abs (this.maxValue - this.minValue); this.reverb.setPan (-100 + value * 200); }; }; clipper.WavePan (50, Stage.width - 100, 48);We give the method a new name (WavePan), we’ve, set the horizontal position (instead of the vertical scale) of the movie clip to oscillate between the maximum and minimum values, and have the sound pan between the left and right speakers.
我们给该方法起一个新名称( WavePan ),我们将影片剪辑的水平位置(而不是垂直比例)设置为在最大值和最小值之间振荡,并在左右扬声器之间进行声像平移。
In our call to WavePan, we pass minimum and maximum values to ensure that the movie clip covers most of the stage:
在对WavePan的调用中,我们传递了最小值和最大值,以确保影片剪辑覆盖舞台的大部分内容:
clipper.WavePan (50, Stage.width - 100, 48);All that remains is to test-drive the effect!
剩下的就是试驾效果!
Save your Flash document and preview your work. 保存您的Flash文档并预览您的工作。Move your speakers apart or put your headphones on, so you can enjoy this effect to the full.
将扬声器移开或戴上耳机,即可充分享受此效果。
This simple effect can serve multiple purposes within your projects. It can really bring your creations to life, adding pizzazz to animations, navigation systems, and more!
这种简单的效果可以在您的项目中达到多种目的。 它可以真正使您的创作栩栩如生,为动画,导航系统等添加更多乐趣!
It’s time to stretch our legs! We’ve covered the fundamentals of sound control. Now, let’s move into the development of a fully functional sound playback device. In this example, we’ll create a random sound player that provides visual feedback about various properties of the random sound clips it plays, as shown in Figure 5.1.
是时候伸展我们的双腿了! 我们已经介绍了声音控制的基础知识。 现在,让我们进入功能齐全的声音播放设备的开发。 在此示例中,我们将创建一个随机声音播放器,该播放器提供有关其播放的随机声音片段的各种属性的视觉反馈,如图5.1所示。
Figure 5.1. Create a mini sound player.
图5.1。 创建一个迷你声音播放器。
To jump forward and edit this effect, locate miniplayer.fla in the code archive.
要跳转并编辑此效果,请在代码档案中找到miniplayer.fla 。
Create four buttons (as symbols in the Library) that visually reflect the following functions: Play, Stop, Increase Volume, and Decrease Volume. Refer to miniplayer.fla in the code archive or Figure 5.1 for examples.
创建四个按钮(作为库中的符号),以可视方式反映以下功能:播放,停止,增大音量和减小音量。 有关示例,请参见代码档案中的miniplayer.fla或图5.1。
Drag instances of the buttons into the first frame of the Elements layer, naming them PlayClip, StopClip, VolumeUp, and VolumeDown. Arrange the buttons so they sit within the bounds of the background you created in step 3.
将按钮的实例拖到Elements层的第一帧中,将它们命名为PlayClip , StopClip , VolumeUp和VolumeDown 。 排列按钮,使它们位于您在步骤3中创建的背景的范围内。
Add a static text box beneath each of the buttons to identify the tasks they perform. In the example file, I labeled them play, stop, volume + and volume -, respectively.
在每个按钮下方添加一个静态文本框,以标识它们执行的任务。 在这个例子中的文件,我标记他们play , stop , volume +和volume -分别。
Locate the following files in the code archive and import them into your library (File > Import to Library…): choir1.mp3, choir2.mp3, choir3.mp3, choir4.mp3, and choir5.mp3.
在代码档案库中找到以下文件,并将它们导入到您的库中(“文件”>“导入到库...”): choir1.mp3 , choir2.mp3 , choir3.mp3 , choir4.mp3和choir5.mp3 。
Select each sound clip within the Library Panel, then right-click and select Linkage…. Check the Export for ActionScript checkbox and accept the default identifier value (which should be choir1, choir2, etc.).
在“库面板”中选择每个声音片段,然后右键单击并选择“链接…”。 选中“导出为ActionScript”复选框,并接受默认的标识符值(应为choir1 , choir2等)。
As I’ve explained before, this allows us to access the sound clips dynamically without having to drag them onto the stage.
如前所述,这使我们能够动态访问声音片段,而不必将它们拖动到舞台上。
We’ve successfully created the objects and imported the sounds we need to achieve basic functionality. All that remains is to add the ActionScript that controls the application.
我们已经成功创建了对象并导入了实现基本功能所需的声音。 剩下的就是添加控制应用程序的ActionScript。
First, we’ll add the code that controls the playback of the sounds we imported.
首先,我们将添加控制导入的声音回放的代码。
Select the first frame of the Actions layer and add the following code within the Actions Panel: 选择“动作”层的第一帧,然后在“动作面板”中添加以下代码:Example 5.4. miniplayer.fla Actions : 1 (excerpt)
示例5.4 miniplayer.fla动作:1(节选)
function randomBetween (a, b) { return Math.min (a, b) + random (Math.abs (a - b) + 1); } PlayClip.onPress = function () { stopAllSounds (); _root.orchestra = new Sound (); _root.orchestra.attachSound ("choir" + randomBetween (1, 5)); _root.orchestra.start (); };As the music player plays clips at random, our familiar randomBetween function comes in handy.
当音乐播放器随机播放剪辑时,我们熟悉的randomBetween函数randomBetween上用场。
As the heart of this example, the onPress event handler of the PlayClip button definitely merits further study. The first thing it does is stop any sound that may already be playing, so that multiple sound clips aren’t played at the same time if the PlayClip button is clicked repeatedly. The built-in stopAllSounds function handles this:
作为该示例的核心, PlayClip按钮的onPress事件处理程序PlayClip值得进一步研究。 它做的第一件事是停止可能正在播放的任何声音,所以如果多个声音片段不是在同一时间打PlayClip按钮被点击多次。 内置的stopAllSounds函数可以处理以下问题:
stopAllSounds ();
stopAllSounds ();
Next, we create a new Sound object and store it in a variable in the main movie (_root) called orchestra. We then use attachSound to load one of the five sounds from the library start it playing:
接下来,我们创建一个新的Sound对象,并将其存储在名为orchestra的主电影( _root )中的变量中。 然后,我们使用attachSound从库中加载五种声音之一,开始播放:
_root.orchestra = new Sound (); _root.orchestra.attachSound ("choir" + randomBetween (1, 5)); _root.orchestra.start ();
_root.orchestra = new Sound (); _root.orchestra.attachSound ("choir" + randomBetween (1, 5)); _root.orchestra.start ();
Save and preview your work. 保存并预览您的工作。Press the Play button and a randomly selected clip will begin to play; press it again and another random clip will play. It’s all functioning as expected.
按下“播放”按钮,随机选择的片段将开始播放; 再按一次,将播放另一个随机剪辑。 一切都按预期运行。
Now, we’ll add the Stop button’s control code. This is much the same as the code we used with the Play button to remove the movie clips and stop all sound on the stage:
现在,我们将添加“停止”按钮的控制代码。 这与我们使用“播放”按钮删除影片剪辑并停止舞台上所有声音的代码非常相似:
Add the following code beneath what you already have: 将以下代码添加到已有的代码下面:Example 5.5. miniplayer.fla Actions : 1 (excerpt)
示例5.5 miniplayer.fla动作:1(节选)
StopClip.onPress = function () { stopAllSounds (); _root.orchestra = null; };We use stopAllSounds to stop any playing sounds, and throw away the Sound object we’d stored in the orchestra variable. This frees up the memory the object was using.
我们使用stopAllSounds停止播放任何声音,并丢弃存储在orchestra变量中的Sound对象。 这样可以释放对象正在使用的内存。
Save and preview your work. 保存并预览您的工作。When you press the Play button, the sound plays; when you hit the Stop button, it stops. Let’s add the volume control buttons and finish this example.
当您按下“播放”按钮时,声音会播放; 当您按停止按钮时,它停止。 让我们添加音量控制按钮并完成本示例。
Insert the following code beneath what you already have: 将以下代码插入已有的代码下面:Example 5.6. miniplayer.fla Actions : 1 (excerpt)
示例5.6 miniplayer.fla动作:1(节选)
VolumeUp.onPress = function () { if (_root.orchestra.getVolume () < 100) { _root.orchestra.setVolume (_root.orchestra.getVolume () + 10); } }; VolumeDown.onPress = function () { if (_root.orchestra.getVolume () > 0) { _root.orchestra.setVolume (_root.orchestra.getVolume () - 10); } };When the volume of a sound clip is less than 100, we increase it in increments of ten each time the VolumeUp button is pressed. Conversely, when its volume is greater than zero, it’s decreased in steps of ten each time the VolumeDown button is pressed.
当声音片段的音量小于100时,每按一次VolumeUp按钮,我们将以10为增量增加VolumeUp 。 相反,当其音量大于零时,每次按下VolumeDown按钮时, VolumeDown十为单位VolumeDown 。
Save and preview your work. 保存并预览您的工作。You can select a random clip by pressing the Play button, stop the dynamically loaded clip with the Stop button, and increase or decrease the volume of the clip using the volume controls. You may want to experiment with sound clips of your own, as those distributed in the code archive are quite short.
您可以通过按“播放”按钮选择一个随机剪辑,使用“停止”按钮停止动态加载的剪辑,并使用音量控件增大或减小剪辑的音量。 您可能要尝试自己的声音片段,因为代码档案库中分发的声音片段非常短。
We’ve successfully created an interface for the playback of random sound clips! We can extend it easily to provide visual feedback about the duration of the loaded track, the play time remaining, the name of the playing clip, and the volume level.
我们已经成功创建了一个用于播放随机声音片段的界面! 我们可以轻松扩展它,以提供有关已加载曲目的持续时间,剩余播放时间,播放剪辑的名称和音量级别的视觉反馈。
To edit these additions, locate miniplayer-feedback.fla in the code archive.
要编辑这些添加,请在代码档案中找到miniplayer-feedback.fla 。
Working from the previous example, add a new layer below the Actions layer, and name it Labels. This will hold our text labels, which provide feedback about what’s going on. 从上一个示例开始,在Actions层下面添加一个新层,并将其命名为Labels。 这将保留我们的文本标签,该标签提供有关正在发生的事情的反馈。Select the first frame of the Labels layer and create a new dynamic text field to the right of the volume buttons, as depicted in Figure 5.1. Name the instance volume.
选择Labels层的第一帧,然后在音量按钮的右侧创建一个新的动态文本字段,如图5.1所示。 命名实例volume 。
With the text box selected, click Character… in the Property Inspector and select Basic Latin (All Characters in Flash MX). Click OK. 选中文本框后,在属性检查器中单击“字符...”,然后选择“基本拉丁语(Flash MX中的所有字符)”。 单击确定。Referencing Figure 5.1 for placement, create the titles clip length and time remaining using static text areas.
参见图5.1进行放置,使用静态文本区域创建标题clip length和剩余time 。
Insert three dynamic text fields beside the relevant titles, naming the fields clipname, cliplength and timeleft. Repeat step 3 for each of the text boxes. Make sure each box is large enough to hold the required information.
在相关标题旁边插入三个动态文本字段,命名字段clipname , cliplength和timeleft 。 对每个文本框重复步骤3。 确保每个盒子足够大以容纳所需的信息。
Select the first frame of the Actions layer and replace the existing code with the following. The changes are extensive, but once again I’ve highlighted them in bold: 选择“动作”层的第一帧,然后将现有代码替换为以下内容。 所做的更改是广泛的,但是我再次以粗体突出显示了它们:Example 5.7. miniplayer-feedback.fla Actions : 1
示例5.7 miniplayer-feedback.fla动作:1
function roundNumber (toRound, numDecimals) { return Math.round (toRound * Math.pow (10, numDecimals)) / Math.pow (10, numDecimals); } function randomBetween (a, b) { return Math.min (a, b) + random (Math.abs (a - b) + 1); } _root.createEmptyMovieClip ("tracker", 1); PlayClip.onPress = function () { stopAllSounds (); _root.orchestra = new Sound (); var clipnumber = randomBetween (1, 5); _root.orchestra.attachSound ("choir" + clipnumber); _root.orchestra.start (); _root.tracker.onEnterFrame = function () { _root.timeleft.text = roundNumber ( (_root.orchestra.duration - _root.orchestra.position) / 1000, 2) + " seconds"; }; _root.cliplength.text = roundNumber ( _root.orchestra.duration / 1000, 2) + " seconds"; _root.clipname.text = "Choir" + clipnumber; _root.volume.text = _root.orchestra.getVolume (); }; StopClip.onPress = function () { stopAllSounds (); _root.orchestra = null; _root.cliplength.text = ""; _root.clipname.text = ""; _root.timeleft.text = ""; }; VolumeUp.onPress = function () { if (_root.orchestra.getVolume () < 100) { _root.orchestra.setVolume (_root.orchestra.getVolume () + 10); _root.volume.text = _root.orchestra.getVolume (); } }; VolumeDown.onPress = function () { if (_root.orchestra.getVolume () > 0) { _root.orchestra.setVolume (_root.orchestra.getVolume () - 10); _root.volume.text = _root.orchestra.getVolume (); } };Let’s dissect the changes we’ve made, so we understand how it all works!
让我们剖析我们所做的更改,以便我们了解它们的工作原理!
First, we introduce a new math function, roundNumber, which rounds figures to a specified number of decimal places. This will be used to show both the play time remaining for each clip and the clip’s total duration.
首先,我们引入一个新的数学函数roundNumber ,它将数字四舍五入到指定的小数位数。 这将用于显示每个剪辑的剩余播放时间以及剪辑的总持续时间。
function roundNumber (toRound, numDecimals) { return Math.round (toRound * Math.pow (10, numDecimals)) / Math.pow (10, numDecimals); }We’ll be updating the track time remaining with each frame of the movie, so we’ll need an onEnterFrame event handler. Unfortunately, we don’t have any obvious movie clip to hook that handler to. We could attach it to one of the buttons in our interface, but it’s tidier to create an empty movie clip called tracker to host it:
我们将更新电影每一帧剩余的跟踪时间,因此我们需要一个onEnterFrame事件处理程序。 不幸的是,我们没有任何明显的影片剪辑可将该处理程序挂接到。 我们可以将其附加到界面中的按钮之一上,但是创建一个名为tracker的空影片剪辑来托管它比较整齐:
_root.createEmptyMovieClip ("tracker", 1);We then add the following code to the PlayClip button’s onPress handler that sets up the event handler itself:
然后,将以下代码添加到PlayClip按钮的onPress处理程序中,该处理程序自行设置事件处理程序:
_root.tracker.onEnterFrame = function () { _root.timeleft.text = roundNumber ((_root.orchestra.duration - _root.orchestra.position) / 1000, 2) + " seconds"; };
_root.tracker.onEnterFrame = function () { _root.timeleft.text = roundNumber ((_root.orchestra.duration - _root.orchestra.position) / 1000, 2) + " seconds"; };
This continuously updates the timeleft dynamic text field we created earlier. We constantly monitor the position of the sound clip using the duration and position properties of the Sound object, calculating the remaining time in milliseconds. We then convert this to a value in seconds, rounding to two decimal places with the help of our roundNumber function.
这会不断更新我们之前创建的timeleft动态文本字段。 我们使用Sound对象的持续时间和位置属性不断监视声音剪辑的位置,并计算剩余时间(以毫秒为单位)。 然后,我们将其转换为以秒为单位的值,借助roundNumber函数将其舍入到小数点后roundNumber 。
We also update the other dynamic text fields that hold the length of the clip being played, its name, and its volume.
我们还更新了其他动态文本字段,这些字段保存正在播放的剪辑的长度,其名称和音量。
_root.cliplength.text = roundNumber (_root.orchestra.duration / 1000, 2) + " seconds"; _root.clipname.text = "Choir" + clipnumber; _root.volume.text = _root.orchestra.getVolume ();
_root.cliplength.text = roundNumber (_root.orchestra.duration / 1000, 2) + " seconds"; _root.clipname.text = "Choir" + clipnumber; _root.volume.text = _root.orchestra.getVolume ();
Within the StopClip button’s onPress event handler, we include the following code, which clears the dynamic text fields of the information associated with the clip played previously:
在StopClip按钮的onPress事件处理程序中,我们包含以下代码,该代码清除与先前播放的剪辑关联的信息的动态文本字段:
_root.cliplength.text = ""; _root.clipname.text = ""; _root.timeleft.text = "";Finally, the VolumeUp and VolumeDown onPress event handlers are updated. This ensures that any changes to the clip’s volume are reflected in the volume dynamic text field.
最后,更新VolumeUp和VolumeDown onPress事件处理程序。 这样可以确保对剪辑音量的任何更改都将反映在volume动态文本字段中。
_root.volume.text = _root.orchestra.getVolume ();That’s it for the code changes.
代码更改就是这样。
Save your Flash document and preview it. 保存您的Flash文档并对其进行预览。There! We have a fully-fledged random clip player that provides information on the duration of the current clip, its name, and the play time remaining.
那里! 我们有一个成熟的随机剪辑播放器,它提供有关当前剪辑的持续时间,其名称和剩余播放时间的信息。
This example can easily be extended through the addition of more clips to the library. Export them for ActionScript reference, and alter the code that selects the clip to play within the PlayClip button’s onPress event handler.
通过向库中添加更多剪辑,可以轻松扩展此示例。 导出它们以供ActionScript参考,并更改选择要在PlayClip按钮的onPress事件处理程序中播放的剪辑的代码。
Use an array! A useful variation would be to store the linkage names of available clips in an array, so that the number of clips available would not have to be hard-coded.
使用数组! 一个有用的变化是将可用片段的链接名称存储在一个数组中,这样就不必对可用片段的数量进行硬编码。
This effect is different from others in the book in that it has no interface! There’s nothing to see, but plenty to hear. We’re aiming to overlay random tracks to create a unique sound – something that’s a little different from what a user might normally hear. The composition contains four ten-second loops comprising a random selection from the following categories:
此效果与书中的其他内容不同,因为它没有界面! 没什么可看的,但是有很多可以听的。 我们的目标是覆盖随机轨道以创建独特的声音-与用户通常听到的声音有些不同。 该组合包含四个十秒的循环,其中包括从以下类别中进行的随机选择:
Background: a selection of five background bed tracks 背景:五种背景床轨道的选择 Drums: a selection of five drum tracks 鼓:五种鼓音轨选择 Guitar: a selection of five guitar loops 吉他:五种吉他循环选择 Overlay: a selection of different overlays 叠加层:选择不同的叠加层As the movie loads, a random selection is made from each category. The tracks are then combined to create one of 625 possible soundtracks.
电影加载时,将从每个类别中随机选择一个。 然后将音轨合并以创建625种可能的音轨之一。
That’s enough of the introduction – let’s get cracking! To edit this effect, locate random.fla in the code archive.
简介就够了–让我们开始吧! 要编辑此效果, random.fla在代码存档中找到random.fla 。
Select File > Import > Import to Library… and select the following MP3 files from the code archive: Background1.mp3, Background2.mp3, Background3.mp3, Background4.mp3, Background5.mp3, Drum1.mp3, Drum2.mp3, Drum3.mp3, Drum4.mp3, Drum5.mp3, Guitar1.mp3, Guitar2.mp3, Guitar3.mp3, Guitar4.mp3, Guitar5.mp3, Overlay1.mp3, Overlay2.mp3, Overlay3.mp3, Overlay4.mp3, and Overlay5.mp3.
选择“文件”>“导入”>“导入到库...”,然后从代码档案库中选择以下MP3文件: Background1.mp3 , Background2.mp3 , Background3.mp3 , Background4.mp3 , Background5.mp3 , Drum1.mp3 , Drum2.mp3 , Drum3.mp3 , Drum4.mp3 , Drum5.mp3 , Guitar1.mp3 , Guitar2.mp3 , Guitar3.mp3 , Guitar4.mp3 , Guitar5.mp3 , Overlay1.mp3 , Overlay2.mp3 , Overlay3.mp3 , Overlay4.mp3和Overlay5.mp3 。
Select these sound clips within the Library Panel, then right-click and select Linkage…. Check the Export for ActionScript checkbox, accept the provided identifier (remove the .mp3 extension if you’re using Flash MX 2004), and click OK.
在“库面板”中选择这些声音片段,然后右键单击并选择“链接…”。 选中“导出为ActionScript”复选框,接受提供的标识符(如果使用的是Flash MX 2004,请删除.mp3扩展名),然后单击“确定”。
That’s all the setting up we need to do for this example. As we’re not adding an interface or allowing any user interaction, no other elements need to be included, apart from the ActionScript to produce the sound composition.
这就是我们在此示例中需要做的所有设置。 由于我们没有添加界面或不允许任何用户交互,因此除了ActionScript之外,不需要包括其他元素来生成声音。
Example 5.8. random.fla Actions : 1
示例5.8 random.fla动作:1
function randomBetween (a, b) { return Math.min (a, b) + random (Math.abs (a - b) + 1); } MovieClip.prototype.PlayQueue = function (clip) { var orchestra = new Sound (this); orchestra.attachSound (clip); orchestra.start (); }; function PlayClips () { var background = "background" + randomBetween (1, 5); var drums = "drum" + randomBetween (1, 5); var guitar = "guitar" + randomBetween (1, 5); var overlay = "overlay" + randomBetween (1, 5); var clips = new Array (background, drums, guitar, overlay); for (var i = 0; i < clips.length; i++) { var mc = createEmptyMovieClip ("SoundHolder" + i, i); mc.PlayQueue (clips[i]); } } PlayClips ();That’s a fairly concise piece of code. Preview the movie and skip the code walkthrough, or read on for the nitty-gritty details – the choice is yours!
那是一段相当简洁的代码。 预览电影并跳过代码演练,或继续阅读有关细节的内容–选择就是您的!
Let’s look at the PlayClips function to see how it all fits together. For each of the tracks, we create a variable (e.g. drums) that we fill with one of the linkage identifiers for the sound clips in the library, using the randomBetween function to generate a random number between one and five. We then combine these variables into an array of sound clips:
让我们看一下PlayClips函数,看它们如何组合在一起。 对于每个音轨,我们创建一个变量(例如drums ),并使用库中声音片段的链接标识符之一填充该变量,并使用randomBetween函数生成一个介于1到5之间的随机数。 然后,我们将这些变量组合成一个声音片段数组:
var clips = new Array (background, drums, guitar, overlay);
var clips = new Array (background, drums, guitar, overlay);
From here, we use a for loop to create an empty movie clip for each element of the array. These clips play the selected sound clips at random. This is accomplished by calling the PlayQueue movie clip method (which we’ll examine in a moment) and passing the sound clip linkage identifier as a parameter.
从这里开始,我们使用for循环为数组的每个元素创建一个空的影片剪辑。 这些片段随机播放选定的声音片段。 这是通过调用PlayQueue电影剪辑方法(我们将在稍后进行检查)并将声音剪辑链接标识符作为参数来实现的。
for (var i = 0; i < clips.length; i++) { var mc = createEmptyMovieClip ("SoundHolder" + i, i); mc.PlayQueue (clips[i]); }
for (var i = 0; i < clips.length; i++) { var mc = createEmptyMovieClip ("SoundHolder" + i, i); mc.PlayQueue (clips[i]); }
We call the PlayQueue method for each of the new movie clips created by the PlayClips function. This embeds a sound clip into each of these movie clips, then plays it.
我们为由PlayClips函数创建的每个新的影片剪辑调用PlayQueue方法。 这会将声音剪辑嵌入到每个影片剪辑中,然后播放。
MovieClip.prototype.PlayQueue = function (clip) { var orchestra = new Sound (this); orchestra.attachSound (clip); orchestra.start (); };Because the sound clips are created in quick succession at runtime, the effect is one of a single composite track with a background, plus drum, guitar, and overlay sections.
由于声音片段是在运行时快速连续创建的,因此效果是具有背景,加上鼓,吉他和叠加部分的单个复合音轨之一。
Save and preview your document. 保存并预览您的文档。You may notice that every time you play the movie, you get a different composition. Some work very well, while others sound fairly clunky! It’s all about experimentation and seeing what’s possible.
您可能会注意到,每次播放电影时,都会得到不同的构图。 有些效果很好,而另一些听起来很笨拙! 一切都与实验有关,看看有什么可能。
This effect is based on the previous "headless" example, but builds on it quite extensively, utilizing the CheckBox component, custom event handlers, and providing users with the ability to switch tracks on or off. The user interface is shown in Figure 5.2.
此效果基于先前的“无头”示例,但在此基础上进行了相当广泛的构建,利用了CheckBox组件,自定义事件处理程序,并为用户提供了打开或关闭轨道的功能。 用户界面如图5.2所示。
Figure 5.2. This random track overlay effect builds on the previous example.
图5.2。 此随机轨道叠加效果建立在前面的示例上。
CheckBox Incompatibilities
复选框不兼容
While developing this effect, which uses the CheckBox component, I was perplexed to find that the code I had in place for Flash MX didn’t work with Flash MX 2004. I investigated this through the Reference Panel and found that there is no getValue method for the Flash MX 2004 version of the CheckBox component. Additionally, the CheckBox no longer allows for a change event handler.
在开发使用CheckBox组件的效果时,我感到困惑,发现我为Flash MX使用的代码不适用于Flash MX2004。我通过“参考面板”进行了调查,发现没有getValue方法。适用于CheckBox组件的Flash MX 2004版本。 此外, CheckBox不再允许更改事件处理程序。
An engineer friend at Macromedia told me that these features hadn’t just been deprecated – they had been removed completely!
Macromedia的一位工程师朋友告诉我,这些功能并不仅被弃用-它们已被完全删除!
The code and steps that follow are for Flash MX, while the changes for the 2004 version are provided as asides. The example provided in the code archive was developed using the Flash MX version of the component.
后面的代码和步骤适用于Flash MX,而2004版本的更改将作为辅助提供。 代码存档中提供的示例是使用组件的Flash MX版本开发的。
To modify this effect, locate random-gui.fla in the code archive.
要修改此效果, random-gui.fla在代码档案中找到random-gui.fla 。
Rename Layer1 as Actions and create beneath it three layers named CheckBoxes, Elements, and Background.
将Layer1重命名为Actions并在其下创建名为CheckBoxes,Elements和Background的三个层。
Select File > Import to Library… and select the following MP3 files in the code archive: Background1.mp3, Background2.mp3, Background3.mp3, Background4.mp3, Background5.mp3, Drum1.mp3, Drum2.mp3, Drum3.mp3, Drum4.mp3, Drum5.mp3, Guitar1.mp3, Guitar2.mp3, Guitar3.mp3, Guitar4.mp3, Guitar5.mp3, Overlay1.mp3, Overlay2.mp3, Overlay3.mp3, Overlay4.mp3, and Overlay5.mp3.
选择“文件”>“导入到库...”,然后在代码存档中选择以下MP3文件: Background1.mp3 , Background2.mp3 , Background3.mp3 , Background4.mp3 , Background5.mp3 , Drum1.mp3 , Drum2.mp3 , Drum3.mp3 Drum4.mp3 , Drum5.mp3 , Guitar1.mp3 , Guitar2.mp3 , Guitar3.mp3 , Guitar4.mp3 , Guitar5.mp3 , Overlay1.mp3 , Overlay2.mp3 , Overlay3.mp3 , Overlay4.mp3和Overlay5.mp3 。
Select each of the sound clips within the Library Panel, then right-click and select Linkage…. Check the Export for ActionScript checkbox, accept the provided unique identifier (remove the .mp3 extension if you’re using Flash MX 20004), and click OK.
在“库”面板中选择每个声音片段,然后单击鼠标右键并选择“链接…”。 选中“导出为ActionScript”复选框,接受提供的唯一标识符(如果使用的是Flash MX 20004,请删除.mp3扩展名),然后单击“确定”。
From the Components Panel (Window > Development Panels > Components), select Flash UI Components (or just UI Components in Flash MX 2004) and drag four instances of the CheckBox component onto the CheckBoxes layer of the stage. Arrange them from left to right using the Align Panel to set their spacing if necessary (Window > Design Panels > Align).
从“组件面板”(“窗口”>“开发面板”>“组件”)中,选择Flash UI组件(或Flash MX 2004中的UI组件),然后将CheckBox组件的四个实例拖到舞台的CheckBoxes层上。 如有必要,使用“对齐面板”从左到右排列它们的间距(“窗口”>“设计面板”>“对齐”)。
Select each CheckBox component on the stage in turn, from left to right, and apply the instance name and parameters shown in Figure 5.3.
从左到右依次选择舞台上的每个CheckBox组件,并应用图5.3所示的实例名称和参数。
Figure 5.3. The properties for the four CheckBox components are displayed in Flash.
图5.3。 四个CheckBox组件的属性显示在Flash中。
No Change Handler in Flash MX 2004 The Change Handler parameter for each CheckBox is especially important here, as it will be used to mute a track when the corresponding checkbox is unchecked. This parameter doesn’t exist in Flash MX 2004, so we’ll add some ActionScript later to handle these events in that version.
Flash MX 2004中没有更改处理程序每个CheckBox的Change Handler参数在这里特别重要,因为当未选中相应的复选框时,它将用于使轨道静音。 此参数在Flash MX 2004中不存在,因此我们稍后将添加一些ActionScript来处理该版本中的这些事件。
Select the first frame of the Elements layer and insert into it a 270×4 pixel rectangle. Convert this to a movie clip symbol named Progress, and name the instance progress. This will act as a quick progress bar, indicating the progress of the composition as it plays.
选择Elements图层的第一帧,并在其中插入一个270×4像素的矩形。 将其转换为名为Progress的影片剪辑元件,然后将实例命名为progress 。 这将充当快速进度条,指示合成播放时的进度。
Select the first frame of the Background layer and create a frame around the controls. If you’re stuck for inspiration, look at Figure 5.2. Once you’re happy with the frame, lock this layer. 选择“背景”层的第一帧,并在控件周围创建一个帧。 如果您想获得灵感,请参阅图5.2。 对框架感到满意后,请锁定该层。Now, let’s add the code to make the effect work.
现在,让我们添加代码以使效果生效。
Example 5.9. random-gui.fla Actions : 1 (excerpt)
示例5.9 random-gui.fla操作:1(节选)
function randomBetween (a, b) { return Math.min (a, b) + random (Math.abs (a - b) + 1); } function roundNumber (toRound, numDecimals) { return Math.round (toRound * Math.pow (10, numDecimals)) / Math.pow (10, numDecimals); } MovieClip.prototype.PlayQueue = function (clip) { this.orchestra = new Sound (this); this.orchestra.attachSound (clip); this.orchestra.start (); }; function PlayClips () { var background = "background" + randomBetween (1, 5); var drums = "drum" + randomBetween (1, 5); var guitar = "guitar" + randomBetween (1, 5); var overlay = "overlay" + randomBetween (1, 5); var clips = new Array (background, drums, guitar, overlay); var mc; for (var i = 0; i < clips.length; i++) { mc = createEmptyMovieClip ("SoundHolder" + i, i); mc.PlayQueue (clips[i]); } mc.onEnterFrame = function () { _root.progress._xscale = this.orchestra.position / this.orchestra.duration * 100; }; mc.orchestra.onSoundComplete = function () { stopAllSounds (); LoopClips (); }; } function LoopClips () { _root.SoundHolder0.orchestra.start (); _root.SoundHolder1.orchestra.start (); _root.SoundHolder2.orchestra.start (); _root.SoundHolder3.orchestra.start (); } PlayClips ();We’ve used the randomBetween and roundNumber functions previously in this chapter, so there’s no need to cover them again.
我们在本章前面已经使用了randomBetween和roundNumber函数,因此无需再次介绍它们。
The PlayQueue method is identical to that used in the previous example, as is the PlayClips function, except for a couple of event handlers we added to the last dynamically generated movie clip.
PlayQueue方法与上一个示例中使用的方法相同, PlayClips函数也是PlayClips ,除了我们添加到最后一个动态生成的影片剪辑的几个事件处理程序之外。
mc.onEnterFrame = function () { _root.progress._xscale = this.orchestra.position / this.orchestra.duration * 100; }; mc.orchestra.onSoundComplete = function () { stopAllSounds (); LoopClips (); };
mc.onEnterFrame = function () { _root.progress._xscale = this.orchestra.position / this.orchestra.duration * 100; }; mc.orchestra.onSoundComplete = function () { stopAllSounds (); LoopClips (); };
After the sound object is initialized, the sound clip is attached, and the sound clip has started to play, we dynamically track the position of the last sound object that’s created using an onEnterFrame event handler attached to the containing movie clip. This event handler controls the width of the progress bar by altering its _xscale property. When the sound finishes, the onSoundComplete event handler will call the stopAllSounds function. Immediately after that, we call LoopClips to restart the four tracks we’ve produced, creating the effect of an infinite loop.
在初始化声音对象,附加声音剪辑并开始播放声音剪辑之后,我们使用附加到包含的影片剪辑的onEnterFrame事件处理程序动态跟踪最后创建的声音对象的位置。 此事件处理程序通过更改进度条的_xscale属性来控制其宽度。 当声音结束时,onSoundComplete事件处理程序将调用stopAllSounds函数。 之后,我们立即调用LoopClips重新开始生成的四个轨道,从而产生无限循环的效果。
function LoopClips () { _root.SoundHolder0.orchestra.start (); _root.SoundHolder1.orchestra.start (); _root.SoundHolder2.orchestra.start (); _root.SoundHolder3.orchestra.start (); }So far, so good, right? When the movie is running, we want to dynamically switch the different tracks on or off by clicking the checkboxes on the stage. To this end, each CheckBox has its own event handler that controls the volume of the track. Let’s add these now.
到目前为止,一切都很好,对吗? 电影放映时,我们想通过单击舞台上的复选框来动态地打开或关闭不同的曲目。 为此,每个CheckBox都有其自己的事件处理程序,该事件处理程序控制轨道的音量。 让我们现在添加这些。
Add the following code below the existing code in the Actions Panel: 在“动作”面板中的现有代码下方添加以下代码:Example 5.10. random-gui.fla Actions : 1 (excerpt)
示例5.10 random-gui.fla操作:1(节选)
function backgroundChange (background) { if (background.getValue ()) { _root.SoundHolder0.Orchestra.setVolume (100); } else { _root.SoundHolder0.Orchestra.setVolume (0); } } function drumsChange (drums) { if (drums.getValue ()) { _root.SoundHolder1.Orchestra.setVolume (100); } else { _root.SoundHolder1.Orchestra.setVolume (0); } } function guitarChange (guitar) { if (guitar.getValue ()) { _root.SoundHolder2.Orchestra.setVolume (100); } else { _root.SoundHolder2.Orchestra.setVolume (0); } } function overlayChange (overlay) { if (overlay.getValue ()) { _root.SoundHolder3.Orchestra.setVolume (100); } else { _root.SoundHolder3.Orchestra.setVolume (0); } }The names of these functions correspond to the Change Handler parameter values we assigned to each of the heckBox components when we created them. All these event handlers work the same way. They check whether the CheckBox is checked using the getValue method, then set the volume of the corresponding sound clip to match. The initial state of each CheckBox is true (checked). So, when the checkbox is clicked, its status switches to false, and the volume is set to 0 for that particular Sound object. Clicking it again changes the status to true and the volume to 100. Using the change handlers in this way, we can drop individual tracks out and bring them back in at will.
这些函数的名称与创建它们时分配给每个heckBox组件的Change Handler参数值相对应。 所有这些事件处理程序都以相同的方式工作。 他们检查是否使用getValue方法选中了CheckBox ,然后将相应的声音片段的音量设置为匹配。 每个CheckBox的初始状态为true (选中)。 因此,当单击该复选框时,其状态将切换为false ,并且该特定Sound对象的音量将设置为0 。 再次单击它会将状态更改为true ,并将音量更改为100 。 通过这种方式使用变更处理程序,我们可以删除各个轨道并将其随意带回。
Save your Flash document and preview it. 保存您的Flash文档并对其进行预览。You’re probably listening to a funky composition right now. Click the checkboxes to drop different tracks out and bring them back in. If you don’t like the composition, or it’s a little too wild for your tastes, preview the movie again to see what the random sequencer comes up with!
您现在可能正在听时髦的音乐。 单击复选框以放下不同的曲目,然后再将它们放回。如果您不喜欢该作品,或者有点不喜欢您的口味,请再次预览电影以查看随机音序器的功能!
If you’re using Flash MX 2004, you’ll find that the checkboxes don’t work as advertised. That’s because the CheckBox component, besides looking better, lacks a Change Handler parameter. As a result, our event handler methods have not been hooked up to the checkboxes. This is a good thing, because these methods use another feature that’s missing from the Flash MX 2004 CheckBox component: the getValue method. Let’s now make the changes necessary to get the example working in Flash MX 2004.
如果您使用的是Flash MX 2004,则会发现这些复选框无法像宣传的那样工作。 这是因为CheckBox组件除了看起来更好之外,还缺少Change Handler参数。 结果,我们的事件处理程序方法尚未连接到复选框。 这是一件好事,因为这些方法使用Flash MX 2004 CheckBox组件中缺少的另一个功能: getValue方法。 现在让我们进行必要的更改,以使示例在Flash MX 2004中运行。
First, change each of the event handler functions so they check the selected property of the appropriate CheckBox, rather than the getValue method, which no longer exists. For example, adjust this line of the backgroundChange function:
首先,更改每个事件处理函数,以便它们检查相应CheckBox的选定属性,而不是不再存在的getValue方法。 例如,调整backgroundChange函数的这一行:
if (background.getValue ())
if (background.getValue ())
Replace it with this line:
替换为这一行:
if (background.selected)
if (background.selected)
Next, set up the event handler functions so they’re called when one of the checkboxes is clicked.
接下来,设置事件处理函数,以便在单击其中一个复选框时调用它们。
Add the following code below all the other code in the Actions Panel:
在“动作”面板中的所有其他代码下面添加以下代码:
var cboxListener = new Object (); cboxListener.click = function() { backgroundChange (background); drumsChange (drums); guitarChange (guitar); overlayChange (overlay); }; background.addEventListener ("click", cboxListener); drums.addEventListener ("click", cboxListener); guitar.addEventListener ("click", cboxListener); overlay.addEventListener ("click", cboxListener);This creates a new Object with a single method called click, which is set up as an event listener for each of the four CheckBox objects on the stage. When any one of the checkboxes is clicked, the click method is called. In turn, it calls each of our four event handlers to update the volume accordingly.
这将使用一个名为click方法创建一个新Object ,该方法被设置为舞台上四个CheckBox对象中每个对象的事件侦听器。 单击任一复选框时,将调用click方法。 反过来,它调用我们四个事件处理程序中的每个事件处理程序来相应地更新卷。
Watch the file size! This example contains 20 ten-second clips, weighing in at nearly 3MB in total! This project would be better suited to CD or kiosk deployment than to distribution over the Internet. If the clips were shorter, or if there were fewer of them, it might be possible to distribute the application over the Internet – just be careful with the file size. Don’t say I didn’t warn you!
观看文件大小! 此示例包含20个10秒的剪辑,总共重约3MB! 与通过Internet分发相比,此项目将更适合CD或信息亭的部署。 如果片段较短,或者片段较少,则可以在Internet上分发应用程序–注意文件大小。 不要说我没有警告过你!
We can make this effect even more interactive by, for example, directly controlling the properties of the Sound objects. In the following modification, we’ll control the volume of the various sound clips with the NumericStepper component, which ships with Flash MX 2004. The interface is shown in Figure 5.4.
例如,通过直接控制Sound对象的属性,我们可以使这种效果更具交互性。 在以下修改中,我们将使用Flash MX 2004附带的NumericStepper组件来控制各种声音片段的音量。界面如图5.4所示。
Figure 5.4. Add volume control to the dynamic sound clips.
图5.4。 将音量控制添加到动态声音片段。
As we’ll be adding the Flash MX 2004 NumericStepper component, we’ll take advantage of the new CheckBox component that comes with Flash MX 2004, rather than the Flash MX version we used in the previous example.
当我们将添加Flash MX 2004 NumericStepper组件时,我们将利用Flash MX 2004附带的新CheckBox组件,而不是前面示例中使用的Flash MX版本。
If you’re working with Flash MX, you might as well skip ahead to the next example.
If you're working with Flash MX, you might as well skip ahead to the next example.
To edit this effect, locate random-volume.fla in the code archive.
To edit this effect, locate random-volume.fla in the code archive.
Building on the previous example, we’ll add several pieces of code to accommodate the volume control mechanism, and we’ll replace the existing Flash MX CheckBox components with their Flash MX 2004 counterparts. We’ll also add the new NumericStepper component to the interface to provide users with volume control.
Building on the previous example, we'll add several pieces of code to accommodate the volume control mechanism, and we'll replace the existing Flash MX CheckBox components with their Flash MX 2004 counterparts. We'll also add the new NumericStepper component to the interface to provide users with volume control.
If you’re working from the previous example, locate the Flash MX CheckBox components within the CheckBoxes layer, and delete them. If you're working from the previous example, locate the Flash MX CheckBox components within the CheckBoxes layer, and delete them.Select the first frame of the CheckBoxes layer and drag four instances of the CheckBox component from the UI Components section of the Components Panel, spacing them evenly across the stage. Name these instances, from left to right: backgroundCBox, drumsCBox, guitarCBox, and overlayCBox.
Select the first frame of the CheckBoxes layer and drag four instances of the CheckBox component from the UI Components section of the Components Panel, spacing them evenly across the stage. Name these instances, from left to right: backgroundCBox , drumsCBox , guitarCBox , and overlayCBox .
For each of the CheckBox instances you just created, change the selected parameter within the Property Inspector to true, so that the checkboxes will be selected by default.
For each of the CheckBox instances you just created, change the selected parameter within the Property Inspector to true , so that the checkboxes will be selected by default.
Change the label parameter for each of the CheckBox instances. From left to right, they should read: Background, Drums, Guitar, and Overlay.
Change the label parameter for each of the CheckBox instances. From left to right, they should read: Background , Drums , Guitar , and Overlay .
Drag four instances of the NumericStepper component from the UI Components section of the Components Panel into the first frame of the CheckBoxes layer. Align each NumericStepper beneath each of the checkboxes. Name the instances vol1Control, vol2Control, vol3Control, and vol4Control, and set their widths to 50 pixels.
Drag four instances of the NumericStepper component from the UI Components section of the Components Panel into the first frame of the CheckBoxes layer. Align each NumericStepper beneath each of the checkboxes. Name the instances vol1Control , vol2Control , vol3Control , and vol4Control , and set their widths to 50 pixels.
For each of the NumericStepper component instances, set the parameters within the Property Inspector as follows:
For each of the NumericStepper component instances, set the parameters within the Property Inspector as follows:
maximum100
maximum 100
minimum0
minimum 0
stepSize5
stepSize 5
value100
value 100
Above each of the NumericStepper components, add a static text box containing the text "Volume" to indicate the purpose of the NumericStepper component. The outcome should resemble Figure 5.4.
Above each of the NumericStepper components, add a static text box containing the text "Volume" to indicate the purpose of the NumericStepper component. The outcome should resemble Figure 5.4.
Alter the width and height of the movie and the rounded rectangle frame to accommodate the extra controls we’ve added. Alter the width and height of the movie and the rounded rectangle frame to accommodate the extra controls we've added.Now we can add the extra ActionScript needed to accomplish this effect.
Now we can add the extra ActionScript needed to accomplish this effect.
Select the first frame of the Actions layer. We’ll leave the math and playback functions/methods (randomBetween, roundNumber, PlayQueue, PlayClips, LoopClips) alone, but replace the remaining code (the checkbox event handlers) with the following:
Select the first frame of the Actions layer. We'll leave the math and playback functions/methods ( randomBetween , roundNumber , PlayQueue , PlayClips , LoopClips ) alone, but replace the remaining code (the checkbox event handlers) with the following:
var backgroundOff = false; var drumsOff = false; var guitarOff = false; var overlayOff = false; function backgroundChange () { if (backgroundCBox.selected) { backgroundOff = false; vol1Control.enabled = true; } else { backgroundOff = true; vol1Control.enabled = false; _root.SoundHolder0.orchestra.setVolume (0); } } function drumsChange () { if (drumsCBox.selected) { drumsOff = false; vol2Control.enabled = true; } else { drumsOff = true; vol2Control.enabled = false; _root.SoundHolder1.orchestra.setVolume (0); } } function guitarChange () { if (guitarCBox.selected) { guitarOff = false; vol3Control.enabled = true; } else { guitarOff = true; vol3Control.enabled = false; _root.SoundHolder2.orchestra.setVolume (0); } } function overlayChange () { if (overlayCBox.selected) { overlayOff = false; vol4Control.enabled = true; } else { overlayOff = true; vol4Control.enabled = false; _root.SoundHolder3.orchestra.setVolume (0); } } function setCustomVolume () { if (!backgroundOff) { SoundHolder0.orchestra.setVolume (vol1Control.value); } if (!drumsOff) { SoundHolder1.orchestra.setVolume (vol2Control.value); } if (!guitarOff) { SoundHolder2.orchestra.setVolume (vol3Control.value); } if (!overlayOff) { SoundHolder3.orchestra.setVolume (vol4Control.value); } } var volumeListener = new Object (); volumeListener.change = function () { setCustomVolume (); }; var cboxListener = new Object (); cboxListener.click = function () { backgroundChange (); drumsChange (); guitarChange (); overlayChange (); setCustomVolume (); }; vol1Control.addEventListener ("change", volumeListener); vol2Control.addEventListener ("change", volumeListener); vol3Control.addEventListener ("change", volumeListener); vol4Control.addEventListener ("change", volumeListener); backgroundCBox.addEventListener ("click", cboxListener); drumsCBox.addEventListener ("click", cboxListener); guitarCBox.addEventListener ("click", cboxListener); overlayCBox.addEventListener ("click", cboxListener);Once again, we have functions to handle the CheckBox changes (backgroundChange, drumsChange, guitarChange, and overlayChange). They all look fairly similar.
Once again, we have functions to handle the CheckBox changes ( backgroundChange , drumsChange , guitarChange , and overlayChange ). They all look fairly similar.
function backgroundChange () { if (backgroundCBox.selected) { backgroundOff = false; vol1Control.enabled = true; } else { backgroundOff = true; vol1Control.enabled = false; _root.SoundHolder0.orchestra.setVolume (0); } }These functions detect the current status of the relevant CheckBox by analyzing its selected property. If the CheckBox is selected, we set a variable to false (in this case, the variable is backgroundOff) to indicate that the corresponding clip is not switched off. These four variables are set to false to begin with, since all four sound clips are switched on at the start of the movie. We also enable the associated volume control NumericStepper (vol1Control).
These functions detect the current status of the relevant CheckBox by analyzing its selected property. If the CheckBox is selected, we set a variable to false (in this case, the variable is backgroundOff ) to indicate that the corresponding clip is not switched off. These four variables are set to false to begin with, since all four sound clips are switched on at the start of the movie. We also enable the associated volume control NumericStepper ( vol1Control ).
If the CheckBox is not selected, we set the variable to true and disable the corresponding NumericStepper component, indicating that the sound clip is switched off. We also set the volume of the related sound clip to zero. This switches the clip off, but allows it to keep playing silently, maintaining its position in case we decide to switch it back on later.
If the CheckBox is not selected, we set the variable to true and disable the corresponding NumericStepper component, indicating that the sound clip is switched off. We also set the volume of the related sound clip to zero. This switches the clip off, but allows it to keep playing silently, maintaining its position in case we decide to switch it back on later.
The setCustomVolume function sets the volume of each clip to the value specified by its associated NumericStepper control, unless the flag variable indicates that it’s currently switched off.
The setCustomVolume function sets the volume of each clip to the value specified by its associated NumericStepper control, unless the flag variable indicates that it's currently switched off.
function setCustomVolume () { if (!backgroundOff) { SoundHolder0.orchestra.setVolume (vol1Control.value); } if (!drumsOff) { SoundHolder1.orchestra.setVolume (vol2Control.value); } if (!guitarOff) { SoundHolder2.orchestra.setVolume (vol3Control.value); } if (!overlayOff) { SoundHolder3.orchestra.setVolume (vol4Control.value); } }All that’s left is to ensure these functions are called at the appropriate times. A new listener Object called volumeListener offers a method called change that calls the setCustomVolume function.
All that's left is to ensure these functions are called at the appropriate times. A new listener Object called volumeListener offers a method called change that calls the setCustomVolume function.
var volumeListener = new Object (); volumeListener.change = function () { setCustomVolume (); };By calling the addEventListener method from each of the NumericStepper components, we have this object handle changes to the volume of our clips:
By calling the addEventListener method from each of the NumericStepper components, we have this object handle changes to the volume of our clips:
vol1Control.addEventListener ("change", volumeListener); vol2Control.addEventListener ("change", volumeListener); vol3Control.addEventListener ("change", volumeListener); vol4Control.addEventListener ("change", volumeListener);If any of the NumericStepper component values change, the setCustomVolume function is called to handle it.
If any of the NumericStepper component values change, the setCustomVolume function is called to handle it.
We’ve also set up an event listener in a similar manner for the CheckBox components:
We've also set up an event listener in a similar manner for the CheckBox components:
cboxListener = new Object (); cboxListener.click = function () { backgroundChange (); drumsChange (); guitarChange (); overlayChange (); setCustomVolume (); }; ... backgroundCBox.addEventListener ("click", cboxListener); drumsCBox.addEventListener ("click", cboxListener); guitarCBox.addEventListener ("click", cboxListener); overlayCBox.addEventListener ("click", cboxListener);When any one of the checkboxes is clicked, the event handler calls the four functions we defined earlier (switching on or off the correct sound clip) before calling setCustomVolume to correctly set the volume of any clip that has just been switched on.
When any one of the checkboxes is clicked, the event handler calls the four functions we defined earlier (switching on or off the correct sound clip) before calling setCustomVolume to correctly set the volume of any clip that has just been switched on.
Save your document and export the SWF file to an appropriate location. Save your document and export the SWF file to an appropriate location.Don’t forget ActionScript 2.0 Components distributed with Flash MX 2004 work internally using features of ActionScript 2.0. If you try to publish a movie that contains such components with Publish settings configured for ActionScript 1.0, the components will not work (they’ll look like white rectangles with black borders).
Don't forget ActionScript 2.0 Components distributed with Flash MX 2004 work internally using features of ActionScript 2.0. If you try to publish a movie that contains such components with Publish settings configured for ActionScript 1.0, the components will not work (they'll look like white rectangles with black borders).
New movies created in Flash MX 2004 default to ActionScript 2.0, so you’re okay there. But, if you start from the finished version of the previous example provided in the code archive, you’ll need to change the ActionScript version setting for the file. Simply click the background of the movie, then click the Settings… button in the Property Inspector. You can adjust the ActionScript version setting on the Flash tab.
New movies created in Flash MX 2004 default to ActionScript 2.0, so you're okay there. But, if you start from the finished version of the previous example provided in the code archive, you'll need to change the ActionScript version setting for the file. Simply click the background of the movie, then click the Settings… button in the Property Inspector. You can adjust the ActionScript version setting on the Flash tab.
Use the checkboxes to switch on and off some of the tracks; notice how they disable and enable the volume controls we’ve added. Experiment with the volume controls to set a nice balance between the tracks, and see what masterpieces you can come up with!
Use the checkboxes to switch on and off some of the tracks; notice how they disable and enable the volume controls we've added. Experiment with the volume controls to set a nice balance between the tracks, and see what masterpieces you can come up with!
You can build on this example to modify any number of sound object properties. Spend a little time with it and see what you can achieve.
You can build on this example to modify any number of sound object properties. Spend a little time with it and see what you can achieve.
This effect uses the same choir sound clips we used previously in this chapter, but with a slightly different approach. We’ll import a playlist from an XML file and load the MP3 files dynamically into Flash. We’ll also present song information (including Album, Artist, and Song Title) that’s stored within the MP3 in what are called ID3 tags, as shown in Figure 5.5.
This effect uses the same choir sound clips we used previously in this chapter, but with a slightly different approach. We'll import a playlist from an XML file and load the MP3 files dynamically into Flash. We'll also present song information (including Album, Artist, and Song Title) that's stored within the MP3 in what are called ID3 tags , as shown in Figure 5.5.
Figure 5.5. Create a random MP3 player using XML and ID3 data.
Figure 5.5. Create a random MP3 player using XML and ID3 data.
ID3 tag information is referenced differently in Flash MX than in Flash MX 2004, owing to the differences between versions of Flash Player. Macromedia Flash Player 7 supports the latest ID3 v2.2 and v2.4 tags. As the data is stored at the beginning of the MP3 file, this information is referenced immediately upon opening the MP3 stream. On the other hand, Macromedia Flash Player 6 supports only ID3 v1.0 and v1.1 tags, which are stored at the end of the file. On that platform, we must wait until the stream is fully loaded before we can retrieve the ID3 tag information.
ID3 tag information is referenced differently in Flash MX than in Flash MX 2004, owing to the differences between versions of Flash Player. Macromedia Flash Player 7 supports the latest ID3 v2.2 and v2.4 tags. As the data is stored at the beginning of the MP3 file, this information is referenced immediately upon opening the MP3 stream. On the other hand, Macromedia Flash Player 6 supports only ID3 v1.0 and v1.1 tags, which are stored at the end of the file. On that platform, we must wait until the stream is fully loaded before we can retrieve the ID3 tag information.
We’ll initially create an MP3 player for version 6 of the Flash Player, supporting ID3 v1.x tags. Then, we’ll modify the effect to take advantage of ID3 v2.x tag support within version 7 of the Flash Player.
We'll initially create an MP3 player for version 6 of the Flash Player, supporting ID3 v1.x tags. Then, we'll modify the effect to take advantage of ID3 v2.x tag support within version 7 of the Flash Player.
To edit this effect, locate mp3–mx.fla in the code archive.
To edit this effect, locate mp3–mx.fla in the code archive.
It uses several MP3 files: choir1.mp3, choir2.mp3, choir3.mp3, choir4.mp3, and choir5.mp3. We’ll also be needing the XML file that acts as the playlist; it’s called playlist.xml and can also be found in the code archive.
It uses several MP3 files: choir1.mp3 , choir2.mp3 , choir3.mp3 , choir4.mp3 , and choir5.mp3 . We'll also be needing the XML file that acts as the playlist; it's called playlist.xml and can also be found in the code archive.
For this project, we need a clickable movie clip that loads a random MP3 file and a dynamic text field that displays the ID3 data from the MP3 file.
For this project, we need a clickable movie clip that loads a random MP3 file and a dynamic text field that displays the ID3 data from the MP3 file.
Create a new Flash document that’s 500 pixels wide and 450 pixels high. Accept the default frame rate and click OK. Create a new Flash document that's 500 pixels wide and 450 pixels high. 接受默认的帧速率,然后单击确定。 Rename the default layer Actions and add beneath it two new layers named Interface and Background. Rename the default layer Actions and add beneath it two new layers named Interface and Background.Select the first frame of the Interface layer and create a movie clip called PlayRandomButton containing a button that’s approximately 70 pixels high and 70 pixels wide. Name the instance randomplayer and move the clip to the left of the stage centre, as shown in Figure 5.5.
Select the first frame of the Interface layer and create a movie clip called PlayRandomButton containing a button that's approximately 70 pixels high and 70 pixels wide. Name the instance randomplayer and move the clip to the left of the stage centre, as shown in Figure 5.5.
We’ll use this clip to randomly load an MP3 file and pass the ID3 tag information from the MP3 file into a dynamic text field.
We'll use this clip to randomly load an MP3 file and pass the ID3 tag information from the MP3 file into a dynamic text field.
Create a new, 320×160 pixel dynamic text field to the right of the button. Name the field trackID3Info.
Create a new, 320×160 pixel dynamic text field to the right of the button. Name the field trackID3Info .
In the Property Inspector for the new field, click the Character… button and choose Basic Latin (or All Characters in Flash MX). In the Property Inspector for the new field, click the Character… button and choose Basic Latin (or All Characters in Flash MX).This dynamic text field will act as a container that receives the ID3 tag information from the dynamically loaded MP3 files.
This dynamic text field will act as a container that receives the ID3 tag information from the dynamically loaded MP3 files.
Now, for a little window-dressing:
Now, for a little window-dressing:
Add to the first frame of the Background layer a rectangle that frames the text area you just created. Add to the first frame of the Background layer a rectangle that frames the text area you just created.You can add as many extras as you wish to increase the aesthetics of the interface. Refer to Figure 5.5 for inspiration!
You can add as many extras as you wish to increase the aesthetics of the interface. Refer to Figure 5.5 for inspiration!
Save your work. 保存您的工作。Locate the files choir1.mp3, choir2.mp3, choir3.mp3, choir4.mp3 and choir5.mp3 from the code archive and move them into the same folder in which you saved the document.
Locate the files choir1.mp3 , choir2.mp3 , choir3.mp3 , choir4.mp3 and choir5.mp3 from the code archive and move them into the same folder in which you saved the document.
We now need to create the XML playlist that references the MP3 files we’re planning to load.
We now need to create the XML playlist that references the MP3 files we're planning to load.
Tip For more information on working with XML, see Introduction to XML, by Harry Fuecks.
Tip For more information on working with XML, see Introduction to XML, by Harry Fuecks.
Type the following code into a text editor and save it as playlist.xml in the same folder.
Type the following code into a text editor and save it as playlist.xml in the same folder.
Example 5.11. playlist.xml Actions : 1
Example 5.11. playlist.xml Actions : 1
<?xml version="1.0" encoding="iso-8859-1"?> <playlist> <mp3file track="choir1.mp3"/> <mp3file track="choir2.mp3"/> <mp3file track="choir3.mp3"/> <mp3file track="choir4.mp3"/> <mp3file track="choir5.mp3"/> </playlist>Unlike HTML, which uses a predefined set of tags, XML allows you to create custom data structures. As long as all opening tags have a matching closing tag (or, as in the case of the mp3File tag in this example, they close themselves), Flash will import the data structure as an ActionScript XML object, allowing you to manipulate and access the information contained within the file.
Unlike HTML, which uses a predefined set of tags, XML allows you to create custom data structures. As long as all opening tags have a matching closing tag (or, as in the case of the mp3File tag in this example, they close themselves), Flash will import the data structure as an ActionScript XML object, allowing you to manipulate and access the information contained within the file.
This XML file is structurally simple. The playlist tag is the top-level node, and the mp3file tags are its child nodes. These child nodes also contain an attribute called track, which holds the name of the MP3 file we wish to pull into Flash.
This XML file is structurally simple. The playlist tag is the top-level node, and the mp3file tags are its child nodes. These child nodes also contain an attribute called track , which holds the name of the MP3 file we wish to pull into Flash.
Our ActionScript will import this XML file and move through the data structure, populating an array with the names of the MP3 files it contains.
Our ActionScript will import this XML file and move through the data structure, populating an array with the names of the MP3 files it contains.
Example 5.12. mp3–mx.fla Actions : 1 (excerpt)
Example 5.12. mp3–mx.fla Actions : 1 (excerpt)
var tracklist = new Array (); var mp3List = new XML (); mp3List.ignoreWhite = true; mp3List.onLoad = createPlayList; mp3List.load ("playlist.xml"); function createPlayList (success) { if (!success) { return; } var topLevel = null; for (i = 0; i <= this.childNodes.length; i++) { if (this.childNodes[i].nodeValue == null && this.childNodes[i].nodeName == "playlist") { topLevel = this.childNodes[i]; break; } } if (topLevel != null) { for (i = 0; i <= topLevel.childNodes.length; i++) { if (topLevel.childNodes[i].nodeName == "mp3file") { var track = topLevel.childNodes[i].attributes["track"]; _root.tracklist.push (track); } } } } function randomBetween (a, b) { return Math.min (a, b) + random (Math.abs (a - b) + 1); } function playTrack () { var track = _root.track; if (track.getBytesLoaded () == track.getBytesTotal () && track.duration > 0) { clearInterval (_root.checkLoaded); trackID3Info.text = ""; trackID3Info.text += "Title: " + track.id3.songname + newline; trackID3Info.text += "Artist: " + track.id3.artist + newline; trackID3Info.text += "Album: " + track.id3.album + newline; trackID3Info.text += "Year: " + track.id3.year + newline; trackID3Info.text += "Comments: " + track.id3.comment + newline; } } randomplayer.onPress = function () { stopAllSounds (); var trackNo = randomBetween (0, _root.tracklist.length - 1); _root.track = new Sound (); _root.track.loadSound (_root.tracklist[trackNo], true); _root.checkLoaded = setInterval (playTrack, 500); };Let’s break this code into manageable chunks and see what’s going on.
Let's break this code into manageable chunks and see what's going on.
First, we create an empty array to contain our list of MP3 tracks.
First, we create an empty array to contain our list of MP3 tracks.
var tracklist = new Array ();Next, we create an XML object called mp3List, and set its ignoreWhite property to true so that line feeds and whitespace aren’t parsed as separate nodes.
Next, we create an XML object called mp3List , and set its ignoreWhite property to true so that line feeds and whitespace aren't parsed as separate nodes.
var mp3List = new XML (); mp3List.ignoreWhite = true;We then set the event handler that will execute when the XML file has loaded (createPlayList) and load the data from playlist.xml.
We then set the event handler that will execute when the XML file has loaded ( createPlayList ) and load the data from playlist.xml .
mp3List.onLoad = createPlayList; mp3List.load ("playlist.xml");Now we define the createPlayList function, which gets called to handle the XML data once it has loaded.
Now we define the createPlayList function, which gets called to handle the XML data once it has loaded.
function createPlayList (success) { if (!success) { return; } var topLevel = null; for (i = 0; i <= this.childNodes.length; i++) { if (this.childNodes[i].nodeValue == null && this.childNodes[i].nodeName == "playlist") { topLevel = this.childNodes[i]; break; } }The first thing we do is check whether the XML file loaded successfully, as indicated by the success parameter. If it didn’t, we bail out before attempting to process it.
The first thing we do is check whether the XML file loaded successfully, as indicated by the success parameter. If it didn't, we bail out before attempting to process it.
We then enter a for loop based on the number of top-level nodes within the XML object (this). We check these nodes until we find the one that has a null nodeValue, meaning it’s a tag (as opposed to a piece of text) and that its name is playlist. This node is stored in a variable named topLevel. We then break out of the for loop.
We then enter a for loop based on the number of top-level nodes within the XML object ( this ). We check these nodes until we find the one that has a null nodeValue, meaning it's a tag (as opposed to a piece of text) and that its name is playlist . This node is stored in a variable named topLevel . We then break out of the for loop.
Next, we enter another for loop, in order to examine its children:
Next, we enter another for loop, in order to examine its children:
if (topLevel != null) { for (i = 0; i <= topLevel.childNodes.length; i++) { if (topLevel.childNodes[i].nodeName == "mp3file") { var track = topLevel.childNodes[i].attributes["track"];
if (topLevel != null) { for (i = 0; i <= topLevel.childNodes.length; i++) { if (topLevel.childNodes[i].nodeName == "mp3file") { var track = topLevel.childNodes[i].attributes["track"];
For each of the child nodes, we check to see if it’s an mp3file tag, and then populate a variable with the track attribute of the tag, which is the name of an MP3 file.
For each of the child nodes, we check to see if it's an mp3file tag, and then populate a variable with the track attribute of the tag, which is the name of an MP3 file.
Finally, we populate the tracklist array using its push method to add the filename to the start of the array.
Finally, we populate the tracklist array using its push method to add the filename to the start of the array.
_root.tracklist.push (track);
_root.tracklist.push (track);
That takes care of building the playlist. Now, when the randomplayer movie clip is clicked, the following code is brought into play:
That takes care of building the playlist. Now, when the randomplayer movie clip is clicked, the following code is brought into play:
randomplayer.onPress = function () { stopAllSounds (); var trackNo = randomBetween (0, _root.tracklist.length - 1); _root.track = new Sound (); _root.track.loadSound (_root.tracklist[trackNo], true); _root.checkLoaded = setInterval (playTrack, 500); };First, we stop all currently running sounds using the stopAllSounds function. We then populate a variable called trackNo with a random number in order to choose one of the tracks in our tracklist array.
First, we stop all currently running sounds using the stopAllSounds function. We then populate a variable called trackNo with a random number in order to choose one of the tracks in our tracklist array.
We then create a new Sound object and load it up with a random MP3 file using the trackNo variable we have just populated.
We then create a new Sound object and load it up with a random MP3 file using the trackNo variable we have just populated.
Finally, we use the setInterval function to call the playTrack function every half-second. We store the interval identifier in a variable called checkLoaded in the root of the movie so we can cancel it when appropriate.
Finally, we use the setInterval function to call the playTrack function every half-second. We store the interval identifier in a variable called checkLoaded in the root of the movie so we can cancel it when appropriate.
Now, all that’s left to discuss is the playTrack function:
Now, all that's left to discuss is the playTrack function:
function playTrack () { var track = _root.track; if (track.getBytesLoaded () == track.getBytesTotal () && track.duration > 0) { clearInterval (_root.checkLoaded); trackID3Info.text = ""; trackID3Info.text += "Title: " + track.id3.songname + newline; trackID3Info.text += "Artist: " + track.id3.artist + newline; trackID3Info.text += "Album: " + track.id3.album + newline; trackID3Info.text += "Year: " + track.id3.year + newline; trackID3Info.text += "Comments: " + track.id3.comment + newline; } }Each time this function is called, we check whether the MP3 file has loaded successfully. Once it has, we cancel the interval that is set to call the function every half-second with the clearInterval function. We can then populate the trackID3Info dynamic text field with the ID3 tag information from the MP3 file.
Each time this function is called, we check whether the MP3 file has loaded successfully. Once it has, we cancel the interval that is set to call the function every half-second with the clearInterval function. We can then populate the trackID3Info dynamic text field with the ID3 tag information from the MP3 file.
ID3 v1.x Caveat As Flash Player 6 and Flash MX support only ID3 v1.0 and v1.1 tags, we have to make sure that the MP3 file is completely loaded before we attempt to pull the ID3 tag information from it. This is essential, as the ID3 tag data is found at the end of the MP3 file.
ID3 v1.x Caveat As Flash Player 6 and Flash MX support only ID3 v1.0 and v1.1 tags, we have to make sure that the MP3 file is completely loaded before we attempt to pull the ID3 tag information from it. This is essential, as the ID3 tag data is found at the end of the MP3 file.
In Flash MX 2004, which can produce content for Flash Player 7 and supports the ID3 v2.2 and v2.4 tag information located at the beginning of the MP3 file, this information is much more easily accessed. We’ll see what this means to Flash developers when we modify this example.
In Flash MX 2004, which can produce content for Flash Player 7 and supports the ID3 v2.2 and v2.4 tag information located at the beginning of the MP3 file, this information is much more easily accessed. We'll see what this means to Flash developers when we modify this example.
Save your document and preview your work. Save your document and preview your work.When the movie loads, the XML file is imported and the tracklist array is populated with all the track information from the playlist.xml file. Clicking on the randomplayer movie clip loads an MP3 file and displays its ID3 tag data in the dynamic text field.
When the movie loads, the XML file is imported and the tracklist array is populated with all the track information from the playlist.xml file. Clicking on the randomplayer movie clip loads an MP3 file and displays its ID3 tag data in the dynamic text field.
As we discussed before, it’s much easier to reference ID3 tag data in Flash Player 7. This Player supports v2.2 and v2.4 ID3 tags, which are stored at the beginning of the MP3 file rather than at the end.
As we discussed before, it's much easier to reference ID3 tag data in Flash Player 7. This Player supports v2.2 and v2.4 ID3 tags, which are stored at the beginning of the MP3 file rather than at the end.
Flash MX 2004 only!
Flash MX 2004 only!
As you can only produce Flash Player 7 SWF files using Flash MX 2004, this modification is suitable for Flash MX 2004 only.
As you can only produce Flash Player 7 SWF files using Flash MX 2004, this modification is suitable for Flash MX 2004 only.
To edit this effect, locate mp3–mx2004.fla in the code archive.
To edit this effect, locate mp3–mx2004.fla in the code archive.
We need only make a couple of simple modifications to the movie to allow Flash MX 2004 to read ID3 v2.2 and 2.4 tag information.
We need only make a couple of simple modifications to the movie to allow Flash MX 2004 to read ID3 v2.2 and 2.4 tag information.
Select the first frame of the Actions layer, then locate and delete the playTrack function from the Actions Panel. It’s no longer needed!
Select the first frame of the Actions layer, then locate and delete the playTrack function from the Actions Panel. It's no longer needed!
Replace the onPress event handler code for the randomPlayer movie clip with the following code:
Replace the onPress event handler code for the randomPlayer movie clip with the following code:
Example 5.13. mp3–mx2004.fla Actions : 1 (excerpt)
Example 5.13. mp3–mx2004.fla Actions : 1 (excerpt)
randomPlayer.onPress = function () { stopAllSounds (); var trackNo = randomBetween (0, trackInfo.length - 1); var track = new Sound (); track.onID3 = function () { trackID3Info.text = ""; trackID3Info.text += "Title: " + track.id3.TIT2 + newline; trackID3Info.text += "Artist: " + track.id3.TPE1 + newline; trackID3Info.text += "Album: " + track.id3.TALB + newline; trackID3Info.text += "Year: " + track.id3.TYER + newline; trackID3Info.text += "Comments: " + track.id3.COMM + newline; }; track.loadSound (tracklist[trackNo], true); };This code is essentially the same as before, but it uses an event handler to process the ID3 tag information rather than calling a function every half-second to check for it.
This code is essentially the same as before, but it uses an event handler to process the ID3 tag information rather than calling a function every half-second to check for it.
After we’ve created the new Sound object (track), we reference a new event handler, called onID3, which is available in Flash Player 7. This is invoked when new ID3 data is detected for a loaded MP3 file, which means that we don’t need to confirm that the MP3 file has completely loaded before we check for the ID3 tag data. Once the onID3 event handler is invoked, we can proceed to populate the trackID3Info dynamic text field with the ID3 2.0 tags. It’s as simple as that!
After we've created the new Sound object ( track ), we reference a new event handler, called onID3, which is available in Flash Player 7. This is invoked when new ID3 data is detected for a loaded MP3 file, which means that we don't need to confirm that the MP3 file has completely loaded before we check for the ID3 tag data. Once the onID3 event handler is invoked, we can proceed to populate the trackID3Info dynamic text field with the ID3 2.0 tags. 就这么简单!
ID3 Reference
ID3 Reference
For a complete listing of supported ID3 tags within Flash MX 2004, search for Sound.ID3 in the Help Panel.
For a complete listing of supported ID3 tags within Flash MX 2004, search for Sound.ID3 in the Help Panel.
Save and preview your work. 保存并预览您的工作。Now, when you click the randomPlayer movie clip, the MP3 file starts to play and the ID3 tag data is displayed in the dynamic text field almost instantly. You no longer need to wait for the MP3 file to load completely as you did in the previous example.
Now, when you click the randomPlayer movie clip, the MP3 file starts to play and the ID3 tag data is displayed in the dynamic text field almost instantly. You no longer need to wait for the MP3 file to load completely as you did in the previous example.
Who said that all you can do with sound clips is play them? Certainly not me! I hope that we’ve covered enough material within this chapter to fuel your desire to create some really interesting sound-based interfaces, experimental effects, and other items.
Who said that all you can do with sound clips is play them? Certainly not me! I hope that we've covered enough material within this chapter to fuel your desire to create some really interesting sound-based interfaces, experimental effects, and other items.
It’s now time to see what we can accomplish using video effects in Flash!
It's now time to see what we can accomplish using video effects in Flash!
This marks the end of our series containing three chapters from SitePoint’s The Flash Anthology: Cool Effects & Practical ActionScript, which contains over 60 practical ActionScript solutions for Flash developers and designers.
This marks the end of our series containing three chapters from SitePoint's The Flash Anthology: Cool Effects & Practical ActionScript , which contains over 60 practical ActionScript solutions for Flash developers and designers.
The book contains a total of 10 chapters that provide over 60 ActionScipted solutions to common problems in Flash. Every solution you’ll ever need for your Flash projects, from text and video effects, to debugging and using external data in your applications, is covered in this 455-page reference. All the code included in the book is available in a free downloadable archive.
The book contains a total of 10 chapters that provide over 60 ActionScipted solutions to common problems in Flash. Every solution you'll ever need for your Flash projects, from text and video effects, to debugging and using external data in your applications, is covered in this 455-page reference. All the code included in the book is available in a free downloadable archive.
For more information, see the book page.
For more information, see the book page .
翻译自: https://www.sitepoint.com/flash-anthology-5-sound-effects/
you-get下载b站选集
相关资源:JSmooth_0.9.9-7中文版