第一部分 Flash网站交互类

第1章 Flash进度加载类

每当打开一个在线的Flash应用时,第一时间映入眼帘的往往是各式各样的加载效果。在这些效果中,有的是在Flash应用中加载SWF子文件,有的是加载文字、图片、音乐、视频等资源文件。Flash对于各种外部文件的灵活加载和运用,充分体现了它的开放性,这也是Flash能够呈现出丰富多彩交互效果的基石。可以说,在交互设计中,进度加载是入门必学的基础课程。现在,就从Flash进度加载方面的小例子开始,带读者迈出交互设计的第一步。

1.1 Flash进度加载之——简单的加载

源文件位置 资源下载 > 源文件 > 第1章 > 01

视频位置 资源下载 > 视频 > 第1章 > 01

难易指数 ★☆☆☆☆

学习目的 掌握在Flash中简单加载外部图片文件的技巧

1.1.1 实现效果

加载,顾名思义,就是将一件事物动态地放入另外一件事物,或者称之为“容器”之中。最简单也是最寻常的加载莫过于在Flash中加载一张外部图片。虽然是最基础的功能,但与在网页中加载和显示一张图片不同,在Flash中加载图片并不是仅仅靠写一行类似<img>的标签语句就能完成,其中不可避免地需要使用到ActionScript。对于一些没有任何代码基础的初学者来说,这也许是一件令人头疼的事情。但实际上,它并没有想象中那么艰深和难以掌握。

在本例中,将制作一个简单的相册,如图1.1所示。相册包括两个组成部分:相册背景和被加载的图片。现在所要做的是,使用ActionScript在相册中载入这张外部图片。通过本例,读者应掌握简单加载外部图片的制作方法。同时,这也可能是某些代码初学者和ActionScript的第一次接触。

图1.1 相册的实现效果

1.1.2 制作步骤

1.1.2.1 制作相册背景

首先,打开Flash软件,选择主菜单栏的“文件→新建”命令,或者按快捷键Ctrl+N,打开“新建文档”对话框,如图1.2所示。在“常规”选项卡中,选择ActionScript 3.0,单击“确定”按钮,创建一个Flash文件。

接下来,选择主菜单栏的“文件→保存”命令,或者按快捷键Ctrl+S,保存Flash文档为flower.fla,如图1.3所示。

图1.2 新建Flash文档

图1.3 保存Flash文档

·注意·

这里推荐使用当前最新的Flash版本,即Adobe Flash CC(Creative Cloud)或者Adobe Flash Professional CS6。此外,由于本书的互动案例都基于ActionScript 3.0,读者也可以使用支持ActionScript 3.0的Adobe Flash Professional CS3及其之后的CS4、CS5等版本进行学习和开发。但老版本的Flash开发环境含有一些Flash Player版本限制,有可能无法支持一些较新的ActionScript特性。

选择主菜单栏的“文件→导入→导入到舞台”命令,将制作好的背景图片导入Flash中;或是直接在Flash中用矢量绘图工具绘制相册背景。制作好的相册背景被放在Flash文件的“图层1”中,如图1.4所示。

最后,在flower.fla所在目录下新建文件夹,命名为images。在images文件夹下放置需要加载的图片,将图片命名为flower.jpg。这样,图片相对于Flash文档的路径即为“images/flower.jpg”。

图1.4 相册的背景

1.1.2.2 加载图片

接下来,将用ActionScript代码来完成加载图片的动作。为了给书写的代码一个相对独立的空间,使其不与Flash中其他元素相混淆,这里需要专门创建一个空白的图层来编写代码。在时间轴面板中新建图层,将图层命名为“as”,如图1.5所示。

图1.5 创建“as”图层

·经验·

在ActionScript 2.0时代,设计师书写代码往往是非常随意的。代码可能被写在图层中,也可能被直接写在元件之上。这种混乱的状态直到ActionScript 3.0出现才被终结。在ActionScript 3.0中,代码已经不允许被直接写在元件上。但为了保持代码的集中和可读,专门创建空白图层来书写相应代码不失为一种良好的开发习惯。当代码量较大时,可以创建多个空白图层,将代码按功能或用途分散书写于其中,并将各图层按代码用途分别命名。如开发某个Flash应用时,可以创建“as_home”“as_product”“as_about”3个图层,分别将首页、产品页和介绍页的功能代码放在对应图层中。这样便于按照图层名称快速查找和修改相应功能代码,从而提高工作效率。

接下来,选择主菜单栏的“窗口→动作”命令,或者按快捷键F9,打开“动作”面板,如图1.6所示。动作面板是在Flash中编辑ActionScript代码的工具。此时,在动作面板中输入的所有代码都将存放于“as”图层中。

图1.6 动作面板

·经验·

在代码书写过程中,很可能不小心把代码写到其他图层之上。此时可以在“动作”面板中,单击(固定活动脚本)图标,将当前的代码编辑位置锁定。这种做法的另一个好处是,当在多个图层中编辑代码时,仅在“动作”面板中就能够切换代码的编辑位置。固定活动脚本图标在Adobe Flash Professional CS6之前版本的“动作”面板中都存在,但在Adobe Flash CC中被暂时移除了。

首先,需要定义一个变量,用来存储相册中需要加载文件的路径。在这里需要加载的是一个相对路径,即“images/flower.jpg”。在动作面板中输入如下代码:

    //创建一个URLRequest对象以定义需要加载文件的路径
    var request:URLRequest = new URLRequest("images/flower.jpg");

·注意·

如果读者想了解更多关于创建变量和实例化对象方面的基础知识,可以浏览本书配套资源文件中“ActionScript 3.0应用视频手册”的“定义变量”和“创建对象”部分。

接下来,创建一个Loader对象,用来加载之前定义的URLRequest路径。在动作面板中输入如下代码:

    //创建一个Loader对象以加载文件
    var loader:Loader = new Loader();
    //在Loader对象中加载flower.jpg文件
    loader.load(request);

·经验·

ActionScript是一种平易近人的语言,其代码的语义化很强,便于编程者阅读和理解其中的含义。比如,以上加载代码阅读起来就是“loader加载request”,这和人们的语言习惯是非常接近的。

通过以上代码,flower.jpg这张图片已经被加载到loader中。但是,loader本身并没有显示在屏幕上,所以看不到图片。要让loader显示在屏幕上,需要使用addChild函数。在动作面板中,输入如下代码:

    //将Loader对象显示到舞台上
    addChild(loader);

·经验·

addChild,顾名思义,就是在某个元素中“添加一个子元素”。直接在时间轴所在的图层中使用addChild函数,等同于this. addChild(loader)。这里的this代表的是主时间轴,即Flash当前的主舞台。整句代码的含义实际上是将loader作为子元素添加到主舞台。由于Flash的主舞台是随时显示在屏幕中的,因此将loader添加到其中后,loader本身也能够随之显示出来。

以上代码中,按顺序创建了Loader、URLRequest对象。其中,Loader对象是加载文件的载体,URLRequest对象是加载文件的路径。然后,用Loader的load方法加载图片到Flash中,并将Loader显示到舞台上。这样,就完成了Flash中加载外部文件的基本步骤。

选择主菜单栏的“控制→测试影片→测试”命令,或者按快捷键Ctrl+Enter测试影片。此时,在相册中就能够看到被加载的图片了,如图1.7所示。

图1.7 影片测试结果

1.1.2.3 调整图片位置

现在,相册中还存在一个问题,即图片被加载到了相册的左上角,而并非规划好的位置。此时,可以通过调节loader的位置,即其x、y属性,以调整图片的显示位置。

在动作面板中,输入如下代码:

    loader.x = 556;
    loader.y = 60;

其中,556和60这两个数值都是在设计相册时确定的图片位置参数,即被加载图片的左上角位于离屏幕最左侧556像素、离顶部60像素的位置。

接下来,测试影片,图片就显示在相册中合适的位置了,如图1.8所示。

图1.8 相册最终效果

1.1.3 案例延伸 圆形遮罩

源文件位置 资源下载 > 源文件 > 第1章 > 01

学习目的 掌握在加载外部图片文件的同时对图片进行遮罩的技巧

难易指数 ★☆☆☆☆

这里制作的相册非常简单,事实上,通过简单的HTML代码也能够实现。而Flash的优势在于能够充分发挥设计师的想象力,可以通过简单的操作来实现千变万化的交互效果。比如想要使相册中加载的图片显示为圆形,只需在之前的制作基础上增加一些变化即可。

首先,在舞台中绘制一个圆形形状,将其转换为影片剪辑,在“属性”面板中命名为masker,如图1.9所示。

图1.9 相册最终效果

接下来,只需要设置这个圆形元件对Loader对象的遮罩即可。在动作面板中输入如下代码:

      //设置loader的遮罩为masker
      loader.mask = masker;

测试影片,现在就能够看到被加载的图片以圆形的方式显示在舞台了,如图1.10所示。

按照以上方法,还可以轻易制作各种不同形状的相片显示效果,甚至是动态的遮罩效果。

图1.10 相片的圆形遮罩效果

1.2 Flash进度加载之——百分比加载

源文件位置 资源下载 > 源文件 > 第1章 > 02

视频位置 资源下载 > 视频 > 第1章 > 02

难易指数 ★☆☆☆☆

学习目的 掌握在Flash中获取加载信息、制作加载百分比效果的技巧

1.2.1 实现效果

在之前的相册案例中,已经展示了一种最为简单的外部文件加载方法。在本例中,希望为它增加一些人性化的功能,比如百分比进度。

虽然目前互联网的网速已经比10年前快了很多,但在互动设计中,给任何加载行为加上一个百分比进度还是很有必要的。即使用户在网速很慢的状况下,看到屏幕上的百分比数字过了很久才会变化一下,他仍然能够感受到一丝心理上的安慰,因为他知道这个程序仍然是在执行下载任务的。况且,设计师无法知道用户将在什么样的网络状况下使用自己的Flash应用。

在本例中,将制作一个具有百分比加载进度显示的相册,如图1.11所示。

图1.11 加载的百分比进度效果

1.2.2 制作步骤

1.2.2.1 制作相册背景和进度文本框

01首先,新建一个Flash文档,并在默认的图层中导入准备好的相册背景,如图1.12所示。

图1.12 在Flash文档中导入相册背景

02新建图层,使用文本工具,绘制一个文本框。在属性面板中,将文本框命名为tLoadingProgress,如图1.13所示。tLoadingProgress文本框将用来显示加载的百分比进度。

图1.13 将文本框命名为tLoadingProgress

03为了使百分比进度有良好的显示效果,需要在文本框中嵌入相应的字体。首先,在属性面板中设置文本框字体为Arial,再单击“嵌入”按钮,打开“字体嵌入”对话框,如图1.14所示。为文本框嵌入从0到9的所有数字,以及代表百分比的%符号。最后,单击“确定”按钮,完成字体嵌入。

图1.14 “字体嵌入”对话框

·经验·

如果需要在影片运行时对文本框内容进行动态编辑,例如使用ActionScript代码修改文本框的文字,都应该相应地在制作时为文本框嵌入文字字体。

04为了预览百分比文字效果,可以在文本框中输入某个百分比进度的文字。在tLoadingProgress文本框中输入起始百分比进度“0%”,如图1.15所示。这样,当没有任何加载代码执行时,相册将显示默认的加载进度为“0%”。

图1.15 百分比进度预览

05接下来,为了使百分比进度元件更容易得到控制,可以将文本框放在一个影片剪辑元件里。在工作区中,使文本框处于选择状态,并选择主菜单栏的“修改→转换为元件”命令,或者按快捷键F8,此时将弹出“转换为元件”对话框。在对话框中将元件命名为mProgress,元件类型选择为“影片剪辑”,如图1.16所示。

图1.16 “转换为元件”对话框

·经验·

虽然文本框也可以直接设置x、y位置及visible、alpha等属性,甚至可以制作动画,但用户习惯上总是倾向将其放置于Sprite、MovieClip之类的显示对象容器中,以方便对其进行控制。

06单击“确定”按钮完成转换。此时,舞台上的文本框被转换为一个影片剪辑,如图1.17所示。

图1.17 文本框被转换为影片剪辑

07接下来,在“属性”面板中,将影片剪辑命名为“mProgress”,如图1.18所示。有了这个命名,就能够在ActionScript代码中对该影片剪辑进行控制了。

图1.18 命名影片剪辑

现在就完成了相册背景和百分比文本框的制作。在后续的制作中,将赋予文本框在图片加载时动态显示百分比进度的功能。

1.2.2.2 制作图片加载

接下来,制作图片的加载,这与上一节的制作方法相同。创建一个专门用于编写代码的图层,在动作面板中输入如下代码:

    //创建一个Loader对象以加载图片
    var loader:Loader = new Loader();
    //在加载动作中直接定义一个URLRequest对象
    loader.load(new URLRequest("images/flower_2.jpg"));
    //将图片显示在舞台上
    addChild(loader);
    //调整图片的位置
    loader.x = 127;
    loader.y = 83;

需要注意的是,以上代码将创建URLRequest的步骤整合到了Loader的加载动作中,这样代码看上去更加精简了。测试影片,可以看到目前相册的图片加载效果,如图1.19所示。

图1.19 图片的加载效果

1.2.2.3 制作加载进度

接下来,需要使用代码来显示加载进度。Flash中加载文件的各种状态信息,都存放在相应的Loaderlnfo对象中。以前面在相册中加载的图片为例,该信息存放在图片的loaderlnfo属性中。然而,在图片加载的时候,很难获取到它的loaderlnfo属性,除非图片已经加载完毕。幸好ActionScript 3.0提供了另外一种途径以获得该信息,即使用加载该图片的Loader对象的contentLoaderlnfo属性。Loader对象的contentLoaderlnfo属性与被加载图片本身的loaderlnfo属性是完全相同的。

这里所要做的就是为Loader对象的contentLoaderlnfo属性注册事件侦听。侦听的事件有两种,分别为图片正在下载和图片下载完毕。在动作面板中输入如下代码:

    //当图片正在下载时,不断触发progressHandler函数
    loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
    //当下载结束时,触发initHandler函数
    loader.contentLoaderInfo.addEventListener(Event.INIT, initHandler);
    //progressHandler函数用以刷新加载进度
    function progressHandler(event:ProgressEvent):void {
        mProgress.tLoadingProgress.text =
    Math.round(event.bytesLoaded/event.bytesTotal*100)+"%";
    }
    //initHandler函数用以在图片加载完毕后隐藏进度显示
    function initHandler(event:Event):void {
        mProgress.visible = false;
    }

·注意·

如果读者想了解更多关于事件侦听方面的基础知识,可以浏览本书配套资源文件中“ActionScript 3.0应用视频手册”的“事件侦听”部分。

控制百分比进度显示的代码实际上只有一句,即上述代码中的强调部分。其原理也很容易理解,用图片已加载的字节数除以图片的总字节数,再乘以100就能够获得图片的加载百分比。由于这个数字可能还带有小数,这里用Math.round( )数学函数略去小数,再加上一个百分号,这样就能获得诸如“70%”的直观的进度文字。

百分比进度的制作工作已经完成了,但是在测试时很难直观看到进度的显示效果。这是因为在测试影片时,加载本地文件的速度很快,几乎在瞬间就已经完成了加载,中间的进度自然无法体现出来。要重现图片在网络中的加载情形,需要一个模拟测试环境来“慢慢”地加载图片。

测试影片,打开测试窗口。在该窗口中,选择菜单栏的“视图→下载设置”命令,设置一个合适的模拟下载速度,例如选择“56K(4.7 KB/S)”,如图1.20所示。

图1.20 影片的下载设置

在测试窗口中,选择菜单栏的“视图→模拟下载”命令。此时,影片会再次刷新,并将模拟4.7KB/S的网络下载速度加载图片。现在,就能看到图片的加载进度了,如图1.21所示。

图1.21 图片的加载进度

·经验·

本案例制作环境为Flash Professional CS6。令人遗憾的是,在Adobe Flash CC中已经移除了“模拟下载”功能。如果要使用这一功能,可以结合Adobe公司推出的另一个软件:Adobe Scout。

1.2.3 案例延伸 淡入效果

源文件位置 资源下载 > 源文件 > 第1章 > 02

学习目的 掌握为图片加载添加淡入动画的技巧

难易指数 ★☆☆☆☆

虽然这里的相册已经有了百分比显示效果,但是加载完毕后的一瞬间,图片就显示在舞台上了,给人的感觉比较突兀。通常,可使用ActionScript渐变动画效果让图片更自然地显示在舞台上。

要创建ActionScript渐变动画,目前最佳的选择是使用GreenSock公司的TweenLite和TweenMax。该动画引擎的运行效率很高,动画效果相比Flash自带的Tween动画类来说更为流畅。读者可以参考几种常见动画引擎的比较页面,网址为http://www.greensock.com/tweening-speed-test/,如图1.22所示。

图1.22 几种常见动画引擎的效率比较

·经验·

要使用TweenLite和TweenMax,可以到GreenSock的网站页面中下载,网址为http://www.greensock.com/tweenmax/

要使用TweenLite和TweenMax,只需要将下载好的TweenMax文件解压,将解压后的com子文件夹复制到与Fla文件相同的目录下。在动作面板中输入以下代码进行导入:

    import com.greensock.*;
    import com.greensock.easing.*;

·注意·

如果想了解更多关于面向对象编程中导入方面的基础知识,可以浏览本书配套资源文件中“ActionScript 3.0应用视频手册”的“继承与导入”部分。

ActionScript动画的对象一般是MovieClip或者Sprite之类的显示对象,在此将Loader对象放置在一个MovieClip中进行显示。在动作面板中输入如下代码:

    //创建一个名为mc的MovieClip对象
    var mc:MovieClip = new MovieClip();
    var loader:Loader = new Loader();
    loader.load(new URLRequest("images/flower_2.jpg"));
    //将loader放入mc中,并将mc显示在舞台上
    mc.addChild(loader);
    addChild(mc);
    mc.x = 127;
    mc.y = 83;
    //设置mc初始为完全透明
    mc.alpha = 0;

最后,只需要在侦听下载结束事件的处理函数中,设置图片和进度的淡入、淡出效果即可。在动作面板中输入如下代码::

    function initHandler(event:Event):void {
    //下载结束后,使mc从透明到不透明淡出显示,并使进度文字淡出
        TweenLite.to(mc, 1, {alpha:1});
        TweenLite.to(mProgress, 1, {alpha:0});
    }

测试影片,图片加载完毕后,就能够看到柔和的渐变动画效果了,如图1.23所示。

图1.23 下载图片的渐变动画效果

·经验·

TweenLite和TweenMax的使用非常简单,如Tween Lite.to(mProgress, 1, {alpha:0})这句代码,表示将mProgress元件的透明度(alpha)变化为0,动画的用时为1秒。这样,在执行代码时,mProgress元件就能够在1秒的时长内逐渐由不透明变化到完全透明。

1.3 Flash进度加载之——进度条加载

源文件位置 资源下载 > 源文件 > 第1章 > 03

视频位置 资源下载 > 视频 > 第1章 > 03

难易指数 ★☆☆☆☆

学习目的 掌握在Flash中制作加载进度条的原理和技巧

1.3.1 实现效果

相比百分比进度,进度条能够更加直观地呈现下载进度。本例中,将制作一款经典的横向进度条,如图1.24所示。随着下载的进行,进度条从左到右增长,抵达最右侧时即表示下载结束。

图1.24 进度条实现效果

1.3.2 制作步骤

1.3.2.1 制作背景和进度条元件

01首先,新建一个Flash文档,并在默认的图层中导入准备好的文件背景,如图1.25所示。

图1.25 在Flash文档中导入相册背景

02接下来,需要制作进度条元件。在舞台上绘制一个矩形,将其转换为影片剪辑元件,如图1.26所示。在“属性”面板中,将舞台实例命名为mProgress。mProgress元件将作为进度条元件的容器。

图1.26 创建mProgress元件

·经验·

在转换元件时,给元件设置的名称实际上是该元件在库中的名称,这和舞台实例命名并不相同。通常情况下,Flash会自动给元件进行命名,如元件1、元件2等。这样的自动命名省去了手动给每个元件命名的麻烦,能够加快制作进度,但也有其不利的一面,即不能一目了然地知道该元件是用来做什么的。为了便于制作时在库中快速找到想要编辑的元件,最佳的方式是按照元件的功能名称,手动给元件命名。

03进度条一般由两部分组成,分别是背景元件和进度元件。在mProgress元件中已经存在前面绘制的矩形,这里需要做的是将该矩形复制两份,分别设置不同的颜色,并各自转换为元件,分别命名为bar和bg, bar位于bg之上。其中,bar元件颜色较深,用于显示进度;bg元件颜色较浅,用于显示进度条背景。如果将bar元件宽度缩小一半,则可以看到进度为50%时的进度条效果,如图1.27所示。

图1.27 进度为50%时的进度条效果

1.3.2.2 制作进度功能

接下来,需要用代码来实现进度功能。首先需要制作基础的图片加载功能,这和之前的案例类似。创建一个新图层用来书写as代码,在动作面板中输入如下代码:

    //导入TweenLite以便制作ActionScript动画
    import com.greensock.*;
    //将图片加载到loader中,并通过mc显示到舞台
    var mc:MovieClip = new MovieClip();
    var loader:Loader = new Loader();
    loader.load(new URLRequest("images/flower_3.jpg"));
    mc.addChild(loader);
    addChild(mc);
    //初始化mc的显示状态
    mc.x = 77;
    mc.y = 203;

测试影片,虽然此时进度条功能没有完成,但仍然能够看到图片的基础加载效果,如图1.28所示。

图1.28 图片的基础加载效果

·经验·

以上代码在创建mc对象的同时,设置了其x、y的数值,初始化了mc的显示状态。除此之外,还可以通过侦听图片的下载开始事件,在图片开始下载时对mc的各种属性进行设置,如接下来的mc透明度设置。

接下来,注册loader的contentLoaderlnfo属性的事件侦听。当图片正在下载时,通过不断刷新mProgress中bar元件的宽度来更新进度条显示。在动作面板中输入如下代码:

    //分别侦听图片的下载开始、下载中和下载结束事件
    loader.contentLoaderInfo.addEventListener(Event.OPEN, openHandler);
    loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
    loader.contentLoaderInfo.addEventListener(Event.INIT, initHandler);
    //图片开始下载时,设置mc为完全透明,以便于设置后面的淡入动画效果
    function openHandler(event:Event):void {
        mc.alpha = 0;
    }
    //图片下载时,不断触发progressHandler函数,刷新进度条显示
    function progressHandler(event:ProgressEvent):void {
        mProgress.bar.scaleX = event.bytesLoaded/event.bytesTotal;
    }
    //图片下载完毕后,进度条淡出,0.5秒后图片淡入。此处的delay属性代表延迟时间长度
    function initHandler(event:Event):void {
        TweenLite.to(mc, 1, {alpha:1, delay:.5});
        TweenLite.to(mProgress, 1, {alpha:0});
    }

从以上代码中可以看出,通过更改显示元件的scaleX属性就能够很方便地反映进度百分比,而不需要专门去计算具体的宽度值。以“模拟下载”方式测试影片,将看到进度条运行效果,如图1.29所示。

图1.29 图片的基础加载效果

·经验·

和显示百分比进度不同,在计算bar元件的scaleX值时,只需要将已下载的字节数除以总字节数即可,并不需要在此基础上再乘以100。这是因为scaleX的取值范围为0到1,如scaleX数值为0.5,则表示缩放为原宽度的50%。

1.3.3 案例延伸 缓动效果

源文件位置 资源下载 > 源文件 > 第1章 > 03

学习目的 掌握为加载进度条添加缓动动画的技巧

难易指数 ★★☆☆☆

以上进度条案例的一个缺点是进度效果不太平滑。人们经常在各种网站中看到带有缓动效果的进度条,不仅视觉体验更佳,而且能够给予用户以“网站正在快速下载”的错觉。

要制作进度条的缓动效果,首先不能让进度条实时显示为当前的下载进度,而是需要设置一个弹性值,使进度条缓动接近该目标进度。在之前的案例基础上适当修改,即可实现该效果。代码如下:

      //分别侦听图片的下载开始、下载中事件
      loader.contentLoaderInfo.addEventListener(Event.OPEN, openHandler);
      loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
      //图片开始下载时,初始化bar元件的scaleX数值,定义tsx属性来储存bar元件的目标进度值,并设置bar元件的enterframe事件侦听
      function openHandler(event:Event):void {
          mc.alpha = 0;
          mProgress.bar.scaleX = 0;
          mProgress.bar.tsx = 0;
          mProgress.bar.addEventListener(Event.ENTER_FRAME, refreshBar);
      }
      //图片下载过程中,bar元件的宽度以平滑方式变化
      function refreshBar(event:Event):void{
          //该算法设置了一个弹性值,使bar元件的宽度变化带有缓动值,缓动程度取决于算法的分母
          mProgress.bar.scaleX += ( mProgress.bar.tsx - mProgress.bar.scaleX) / 10;
          //由于以上算法将使bar元件永远无限接近100%宽度,当bar元件的宽度缩放值大于99%时,移除enterframe事件侦听,显示图片
            if(mProgress.bar.scaleX>.99){
              mProgress.bar.removeEventListener(Event.ENTER_FRAME, refreshBar);
              showImage();
          }
      }
      //图片下载时,不断触发progressHandler函数,刷新bar元件的scaleX目标值
      function progressHandler(event:ProgressEvent):void {
          mProgress.bar.tsx = event.bytesLoaded/event.bytesTotal;
      }
      //显示图片
      function showImage():void {
          TweenLite.to(mc, 1, {alpha:1, delay:.5});
          TweenLite.to(mProgress, 1, {alpha:0});
      }

测试影片,进度条将以“更酷”的缓动方式运动。即使不通过模拟下载,也能够看到进度条的运动过程,如图1.30所示。

图1.30 进度条的缓动效果

1.4 Flash进度加载之——自定义进度加载

源文件位置 资源下载 > 源文件 > 第1章 > 04

视频位置 资源下载 > 视频 > 第1章 > 04

难易指数 ★☆☆☆☆

学习目的 掌握在Flash中将时间轴动画与进度加载相结合的技巧,以制作更加自定义的进度加载效果

1.4.1 实现效果

百分比进度和进度条都是经典的显示加载进度的方式。然而在交互设计中,加载进度的显示方式从来不会循规蹈矩,人们往往需要制作一些奇怪的进度效果,诸如用沙漏效果模拟处理进度,以及向一个杯子注满水来表示下载进度等。在制作这样的效果时,在视觉上往往需要使用时间轴动画来完成,并且通过ActionScript实现时间轴动画与进度加载的紧密结合。

本例中,将通过一个简单的例子来说明两者的结合方式。在图片下载的过程中,水平面逐渐上升,使得圆形区域被慢慢注满。当下载完成时,圆形被全部注满,此时图片将淡入显示,如图1.31~图1.36所示。其中,水平面上升动画将通过时间轴动画的方式来制作。

图1.31 自定义加载进度效果1

图1.32 自定义加载进度效果2

图1.33 自定义加载进度效果3

图1.34 自定义加载进度效果4

图1.35 自定义加载进度效果5

图1.36 自定义加载进度效果6

1.4.2 制作步骤

1.4.2.1 制作时间轴动画

01首先,新建一个Flash文件,制作好网站背景,如图1.37所示。

图1.37 网站背景效果

02在舞台中创建一个影片剪辑,将其实例命名为mProgress。在mProgress中制作时间轴动画,动画总长度为50帧,分为3个图层,分别为代码层、遮罩层和被遮罩层,如图1.38所示。

图1.38 mProgress的图层

03在遮罩层中绘制一个蓝色圆形和一个白色矩形,两者的宽度和高度相同,以确保遮罩效果的契合度。在动画的第一帧,被遮罩层中的白色矩形位于遮罩层中蓝色圆形的下方,如图1.39所示。

图1.39 mProgress的第一帧

04在动画的最后一帧,被遮罩层中的白色矩形与遮罩层中蓝色圆形重叠,如图1.40所示。这样,白色矩形的形状动画在被遮罩后,将产生在圆形区域中水平面上升的动画效果。

图1.40 mProgress的第50帧

05最后,为了确保动画在图片下载时才开始播放,在代码层的第一帧添加stop()语句,以避免动画自动播放。

1.4.2.2 将时间轴动画与代码结合

接下来,需要将时间轴动画与代码进行结合,创建图片加载进度效果。需要加载的图片为clock.png,位于images文件夹下。clock.png为背景透明的圆形图片,如图1.41所示。

图1.41 背景透明的clock.png

新建一个图层,专门用以编写as代码。在动作面板中输入如下代码:

    import com.greensock.*;
    //在mc影片剪辑中加载clock.png
    var mc:MovieClip = new MovieClip();
    var loader:Loader = new Loader();
    var urlrequest:URLRequest = new URLRequest("images/clock.png");
    loader.load(urlrequest);
    mc.addChild(loader);
    addChild(mc);
    mc.x = 287;
    mc.y = 115;

测试影片,可以看到clock.png被加载到舞台中,如图1.42所示。

图1.42 clock.png的加载效果

·经验·

所有在Flash中交互的外部文件的路径都需要转换为URLRequest对象,之后才能够得以使用。

为了使时间轴动画与下载进度相结合,在创建事件侦听时,不能再像制作百分比进度和进度条一样,通过ProgressEvent.PROGRESS事件所触发的函数直接控制进度效果的显示,否则不能很好地表现时间轴动画的过程。在此,考虑使用mProgress自身的enterframe事件来刷新它的进度显示。在动作面板中输入如下代码:

    //注册图片开始下载和下载中的事件侦听
    loader.contentLoaderInfo.addEventListener(Event.OPEN, openHandler);
    loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
    //i用来存储时间轴动画播放的当前帧值
    var i:Number = 0;
    //loadingProgress用来存储时间轴动画播放的目标帧值
    var loadingProgress:Number = 0;
    //当图片开始下载时,为mProgress注册enterframe事件侦听
    function openHandler(event:Event):void {
        mc.alpha = 0;
        mProgress.addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
    }
    //图片下载中,不断刷新时间轴动画的目标帧值。由于动画只有50帧,所以帧值范围为1到50
    function progressHandler(event:ProgressEvent):void {
        loadingProgress = Math.round(event.bytesLoaded/event.bytesTotal*50)
    }
    //每播放一帧,onEnterFrameHandler都被不断触发,显示水平面上升动画
    function onEnterFrameHandler(e){
        //这个判断确保了mProgress动画在平滑播放的同时,其显示进度不会超出当前下载进度
        if(loadingProgress>i){
            i++;
            mProgress.gotoAndStop(i);
        }
        //当mProgress的动画播放到最后一帧时,移除enterframe事件侦听,并且显示下载好的图片
          if(i==50){
            mProgress.removeEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
            TweenLite.to(mc, 1, {alpha:1, delay:0});
        }
    }

在以上代码中,ProgressEvent.PROGRESS事件所触发的函数仅仅只刷新了变量loadingProgress的数值,它为mProgress的动画提供了目标帧值。进度的刷新显示主要通过onEnterFrameHandler函数完成。测试影片,现在就可以看到跟随下载进度变化的水平面上升动画了,如图1.43所示。

图1.43 跟随下载进度变化的水平面上升动画

·经验·

在以上代码中,50这个数值作为时间轴动画的帧长度,被直接写在代码之中。当代码中多处用到这个数值时,一旦时间轴动画长度发生变化,需要找到每一个数值进行修改,维护起来麻烦且容易出错。较好的办法是将这个数值定义为一个变量,一旦有任何修改,只需要修改变量的赋值即可。这也是对代码进行优化的一种经验。

1.4.3 案例延伸 波浪效果

源文件位置 资源下载 > 源文件 > 第1章 > 04

学习目的 学习如何制作带有波浪动画效果的自定义加载进度条

难易指数 ★☆☆☆☆

在前面的例子中,水平面平缓地上升,动画效果让人觉得略显平淡。毕竟这只是用一个最基础的例子来显示时间轴动画与加载进度的结合。有了代码的基础,就可以在时间轴动画上大显身手,制作各种个性化的自定义加载进度。

比如,可以在时间轴中制作水面的波动动画,使整个加载效果显得更有动感。在mProgress元件中,将被遮罩层的形状转换为元件,将形状动画切换为元件动画。在转换的元件中,可以制作水波流动的效果。绘制一个能够无缝重复的水波形状,创建形状动画。设置动画的第一帧水波形状最左侧位于中心点,如图1.44所示。并设置动画的最后一帧水波形状的无缝重复点位于中心点,如图1.45所示。

图1.44 水波动画的第一帧

图1.45 水波动画的最后一帧

·经验·

此处提到的无缝重复,是指形状自身可以无缝拼合在一起。如以上波浪形状的最左侧和最右侧能够自然地结合,这样可以通过无限排列该形状来形成流畅而长度不限的波浪。

通过以上简单的操作,给上升的水平面增加了水波荡漾的效果。测试影片,现在就能够看到更加优美的进度显示了,如图1.46~图1.48所示。在掌握本案例的制作原理后,读者也可以发挥自己的创意,制作各种别致的进度加载效果。

图1.46 带水波效果的进度显示1

图1.47 带水波效果的进度显示2

图1.48 带水波效果的进度显示3

1.4.4 案例延伸 环状加载

源文件位置 资源下载 > 源文件 > 第1章 > 04

难易指数 ★☆☆☆☆

学习目的 学习如何制作环形动画效果的自定义加载进度条

环状加载是另外一种常见的自定义进度显示方式,比起其他加载方式,它显得更加时尚。制作环状加载主要有两种方式:一种方式是使用ActionScript的绘图功能动态绘制圆环,需要用到一些三角函数运算,对于初学者来说较为复杂;另一种方式是使用简单的时间轴动画来实现。本例中,采用后一种方式来进行制作。

这里仍然将时间轴动画放在mProgress元件中。为了制作环形的动画效果,需要将整个动画过程分为两段。第一段动画是从0%到50%的进度动画,创建旋转矩形对右半侧环形的遮罩,如图1.49~图1.52所示。

图1.49 第一段遮罩1

图1.50 第一段遮罩2

图1.51 第一段遮罩3

图1.52 第一段遮罩4

第二段动画是从50%到100%的进度动画,创建旋转矩形对左半侧环形的遮罩,如图1.53~图1.56所示。

图1.53 第二段遮罩1

图1.54 第二段遮罩2

图1.55 第二段遮罩3

图1.56 第二段遮罩4

制作好的时间轴动画由两组遮罩图层组成,共为50帧,如图1.57所示。最后,创建一个代码图层,在第一帧上添加stop(),使元件动画在最开始时停止播放。

图1.57 环状动画的遮罩图层

·注意·

时间轴动画的制作方法并不在本书的主要探讨范围内。如果读者在动画制作中存在任何问题,可以参考相关的Flash动画制作书籍。

控制加载的主代码和上一个案例完全相同,当图片加载时,mProgress元件将按照加载进度向后播放。测试影片,现在就能看到环状的加载效果,如图1.58~图1.63所示。整个案例非常简单,在没有用到任何三角函数算法的前提下实现了环状加载效果,即使是初学者也能够很容易地掌握和运用。

图1.58 环状加载1

图1.59 环状加载2

图1.60 环状加载3

图1.61 环状加载4

图1.62 环状加载5

图1.63 环状加载6

1.5 Flash进度加载之——文件自身加载

源文件位置 资源下载 > 源文件 > 第1章 > 05

视频位置 资源下载 > 视频 > 第1章 > 05

难易指数 ★☆☆☆☆

学习目的 掌握在Flash中制作文件自身加载进度的技巧

1.5.1 实现效果

前面制作的案例都是针对外部文件的加载效果。事实上,当单个swf的文件体积较大时,下载也需要一定的时间,设计师往往需要为其自身制作加载效果,以确保swf在完全下载之后再播放和显示主要内容。本例中,将制作一个简单的公司历史介绍网站。站点由两页组成,第一页是loading页面,以百分比方式显示swf自身的加载进度,如图1.64所示。

当swf文件加载完毕后,将跳转到公司的介绍页面。通常一个网站存在很多张内页面,在本例中只制作了其中一张页面作为演示,如图1.65所示。

图1.64 loading页面

图1.65 内页面

1.5.2 制作步骤

1.5.2.1 制作loading页面和内页面

01新建一个Flash文件。首先,在第一帧制作loading页面。将制作好的loading页面背景导入Flash中,并绘制一个文本框用以显示百分比进度,文本框舞台实例命名为txt,如图1.66所示。

图1.66 网站loading页面

·注意·

在loading页面的百分比文本框中使用了特殊字体。凡是在Flash的动态文本框中用到特殊字体时,都需要嵌入相应字体,以确保文字的正确显示。字体的嵌入方法请参考本书1.2.2.1小节。

02在时间轴面板中新建空白关键帧,即图层1的第2帧。在该帧中制作内页面,如图1.67所示。

图1.67 网站内页面

03最后,在图层1之上创建新的图层,命名为“as”。as图层将被用于专门编写代码,如图1.68所示。

图1.68 创建as图层

1.5.2.2 制作加载代码

接下来,制作加载代码来实现自身加载效果。总体的制作思路是,swf文件在开始播放时将停止在第一帧,此时不断检测自身的加载进度,并以百分比的形式将进度显示在第一帧的txt文本框中。当加载结束后,swf文件跳转到第二帧,完成内页面显示。

在时间轴面板中选择as图层的第一帧,在动作面板中输入如下代码:

    //首先,让文件在第一帧停止播放
    stop();
    //初始化txt文本框显示
    txt.text = "0%";
    //为文件自身注册"下载中"和"下载完毕"事件侦听
    this.loaderInfo.addEventListener(Event.COMPLETE, completeHandler);
    this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
    //当文件正在下载时,不断触发progressHandler函数来刷新百分比进度显示
    function progressHandler(event:ProgressEvent):void {
        txt.text = Math.round(event.bytesLoaded/event.bytesTotal*100)+"%";
    }
    //当文件下载完毕后,跳转到第二帧显示
    function completeHandler(event:Event):void{
        this.gotoAndStop(2);
    }

·经验·

和加载图片时需要通过Loader的contentLoaderInfo属性来获取信息不同,文件自身的加载进度可以通过其loaderInfo属性获取。因此,代码中注册事件侦听的对象为this.loaderInfo。

测试影片,在“模拟下载”模式下即可看到以百分比形式显示的下载进度效果,如图1.69所示。

图1.69 实际运行效果

1.5.3 案例延伸 滚动数字加载

源文件位置 资源下载 > 源文件 > 第1章 > 05

学习目的 掌握使用滚动数字表示加载进度的制作技巧

难易指数 ★☆☆☆☆

在许多场合下,需要制作特殊的加载进度效果。比如某个公司100周年纪念时,希望在网站加载时显示的是从其创办开始至今的所有年份的滚动数字,以此代替百分比进度。当用户在下载时看到屏幕上年份数字的增长,容易产生一种回顾历史的强烈感觉。

假设这个公司创立于1913年,目前需要制作其100周年,即到2013年的数字滚动。只需要做一些简单的换算,就能够实现这样的效果。其主要代码如下:

      stop();
      //初始化起止年份
      var startYear:Number = 1913;
      var endYear:Number = 2013;
      //定义一个变量来储存当前显示的年份数值
      var curYear:Number = startYear;
      var loadingProgress:Number = 0;
      txt.text = String(startYear);

      this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
      this.addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);

      function progressHandler(event:ProgressEvent):void {
          loadingProgress = event.bytesLoaded/event.bytesTotal;
      }
      function onEnterFrameHandler(event:Event):void {
          //将下载进度换算为相应的年份值,与当前显示的年份值进行比较
          if (curYear < startYear+Math.round(loadingProgress*(endYear-startYear)))
      {
              curYear++;
          }
          txt.text = String(curYear);
          //当下载完毕并且当前年份值已经显示为终止年份时,跳转到主页面
          if (curYear == endYear && loadingProgress >= 1) {
              this.removeEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
              this.gotoAndStop(2);
          }
      }

·注意·

由于文本的刷新在与加载进度并不相关的enterframe事件中进行,当文本框中显示的数字为终止年份值时,有可能文件并未完全下载或已初始化完毕。因此,在判断下载完毕的代码中,这里还加入了loadingProgress的数值判断,以确保代码的正常运行。

测试影片,可以看到伴随着加载的进度,屏幕上的数字从1913开始跳动,不断增加,如图1.70~图1.71所示。当文件加载完毕时,数字停止在2013,并切换到内页面显示。

图1.70 数字滚动效果1

图1.71 数字滚动效果2

1.6 Flash进度加载之——多文件加载

源文件位置 资源下载 > 源文件 > 第1章 > 06

视频位置 资源下载 > 视频 > 第1章 > 06

难易指数 ★★☆☆☆

学习目的 掌握在Flash中简单加载多个文件的技巧

1.6.1 实现效果

之前制作的相册都只含有一张图片,更复杂一些的情况是相册中含有多张图片。本例中,将同时在相册中加载8张图片,如图1.72所示。实际上,多文件加载并不复杂,只需要不断重复加载一张图片的步骤即可。

图1.72 多文件加载效果

1.6.2 制作页面背景

1.6.2.1 制作页面背景

新建一个Flash文件。将制作好的页面背景导入Flash中,如图1.73所示。

图1.73 导入页面背景

在与Flash源文件相同的路径下,创建新文件夹,命名为images。在images文件夹下,放置8张准备加载到Flash中的图片,分别命名为00.jpg,01.jpg,02.jpg, …,07.jpg。

1.6.2.2 制作图片加载

如果像之前加载单张图片那样逐个创建容器,制作加载,代码将非常冗长,也耗时耗力。更佳的方案是通过代码循环制作多文件加载,这样所有的代码只需要创建一次就行了。在Flash动作面板中输入如下代码:

    //循环8次,分别加载8张图片
    for (var i:Number=0; i<8; i++) {
        //为每张图片创建容器
        var mc:MovieClip = new MovieClip();
        //计算每张图片容器的x、y位置,形成四列的排列效果
        mc.x = 68+(i%4)*221;
        mc.y = 174 + Math.floor(i/4)*136;
        addChild(mc);
        //调用loadImage函数加载图片
        loadImage(mc, "images/0"+i+".jpg");
    }

·经验·

符号%在ActionScript中被称为模运算符,其功能是求两个数的余数。在排列多行多列元素时,它正好能派上用场,因为元素的横向列数可以通过其索引值与列数求模的余数来获得。

·注意·

如果读者想了解更多关于代码循环方面的基础知识,可以浏览本书配套资源文件中“ActionScript 3.0应用视频手册”的“循环语句”部分。

在以上代码中,通过for循环创建了8个MovieClip对象,并将这些对象排列成两行四列,定位到相册中每张图片的对应位置。最后,调用了一个名为loadlmage的函数,向其中传递了2个参数,分别是MovieClip对象和需要加载的图片文件的路径。接下来,制作loadlmage函数来实现在MovieClip中加载图片。在动作面板中输入如下代码:

    //传递的参数分别为容器和需要加载的图片路径
    function loadImage(holder:MovieClip , url:String) {
        //创建Loader对象,添加到每个容器中,并加载相应图片
        var loader:Loader = new Loader();
        loader.load(new URLRequest(url));
        holder.addChild(loader);
        holder.alpha = 0;
        //侦听该图片加载完毕事件
        loader.contentLoaderInfo.addEventListener(Event.INIT, initHandler);
    }
    //当图片加载完毕时,使容器以淡入方式显示
    function initHandler(event:Event):void {
        TweenLite.to(event.target.loader.parent, 1, {alpha:1});
    }

·注意·

如果读者想了解更多关于函数方面的基础知识,可以浏览本书配套资源文件中“ActionScript 3.0应用视频手册”的“初涉函数”和“函数的参数与返回值”部分。

现在,测试影片,就能看到8张图片陆续被加载到相册中,如图1.74所示。

图1.74 影片测试效果

·经验·

要在加载事件触发的函数中获取对容器的引用,如在上述代码中引用之前定义的MovieClip对象,可以使用event.target. loader.parent的表达式。其中,event.target为包含加载信息的LoaderInfo对象,其loader属性为加载图片的Loader容器。由于Loader对象被放入MovieClip对象中显示,因此其parent属性即为MovieClip对象本身。

1.6.3 案例延伸 BulkLoader加载

源文件位置 资源下载 > 源文件 > 第1章 > 06

学习目的 掌握使用BulkLoader加载多个文件的技巧

难易指数 ★★☆☆☆

在多个文件加载时,如果要制作其总体百分比进度,需要采取略为不同的方法。总体百分比进度的计算公式是将所有已加载文件的字节数除以所有已获取文件的总字节数。由于多个文件的加载不是同时进行的,而是存在先后顺序,有可能出现加载时总体百分比进度却不断减小的问题。要解决这样的问题,对于初学者而言还是比较困难的。这里介绍一款Flash多文件加载类库:BulkLoader。该类库可以让用户轻松地完成多文件加载工作,并且能够在加载中给出精确的总体百分比进度。

·经验·

读者可以在GitHub上获取BulkLoader,地址是https://github.com/arthur-debert/BulkLoader

在之前案例的基础上,添加一个名为tLoading的文本框以显示总体进度。在动作面板中输入如下代码:

      import com.greensock.*;
      //导入BulkLoader
      import br.com.stimuli.loading.BulkLoader;
      import br.com.stimuli.loading.BulkProgressEvent;
      //创建一个BulkLoader对象
      var bulkLoader:BulkLoader = new BulkLoader("myloader");
      //向bulkLoader中添加需要加载的图片路径
      for (var i:Number=0; i<8; i++) {
          bulkLoader.add("images/0"+i+".jpg", {id:"img"+i});
      }
      //当所有文件加载完毕时触发onAllItemsLoaded函数
      bulkLoader.addEventListener(BulkLoader.COMPLETE, onAllItemsLoaded);
      //当下载进行时触发onAllItemsProgress函数
      bulkLoader.addEventListener(BulkLoader.PROGRESS, onAllItemsProgress);
      //开始加载
      bulkLoader.start();
      //下载进行时,刷新百分比进度显示
      function onAllItemsProgress(e:BulkProgressEvent):void {
          tLoading.text = Math.round(e.percentLoaded*100)+"%";
      }
      //所有图片加载完毕时,从bulkLoader中取出每张图片并显示到舞台中
      function onAllItemsLoaded(e:Event):void {
          tLoading.text = "100%";
          for (var i:Number=0; i<8; i++) {
              var mc:MovieClip = new MovieClip();
              mc.x = 68+(i%4)*221;
              mc.y = 174 + Math.floor(i/4)*136;
              mc.addChild(bulkLoader.getBitmap("img"+i));
              addChild(mc);
          }
      }

从以上代码中可以看到,BulkLoader的使用非常简便。首先,创建一个BulkLoader对象,然后将需要加载的图片路径添加到BulkLoader中,最后执行start命令,BulkLoader就开始加载这些文件。在加载过程中,获取并显示总体加载进度也非常便利。测试影片,在下载模式下可以看到多个图片的总体下载进度显示,如图1.75所示。

图1.75 多个文件总体下载进度效果

1.7 Flash进度加载之——XML加载

源文件位置 资源下载 > 源文件 > 第1章 > 07

视频位置 资源下载 > 视频 > 第1章 > 07

难易指数 ★★☆☆☆

学习目的 掌握在Flash中加载XML文件的技巧

1.7.1 实现效果

在之前案例中,所有加载的图片的文件路径都直接写在了ActionScript代码中。这意味着,一旦需要加载另外一张图片,就需要再次打开Flash软件,修改代码中的相应路径,再重新发布文件。这样的步骤比较繁琐,有没有更简便的方式来进行维护和管理呢?答案就是在Flash中制作数据交互,用动态数据来管理这些信息。

Flash中的数据交互主要有两种形式:XML和JSON。这里将通过一个专辑信息显示器,介绍Flash中XML数据的加载和使用。案例的显示效果如图1.76所示。

图1.76 案例显示效果

1.7.2 制作步骤

1.7.2.1 制作页面背景和文本框

01新建一个Flash文档,导入页面背景,并在页面中绘制3个文本框,分别命名为tTitle、tName和tDescription,如图1.77所示。

图1.77 案例显示效果

023个文本框分别用于放置专辑的标题、歌手名和详细介绍,其文字大小依次减小。页面左侧是专辑的封面展示区域,目前显示为空白,将在后续制作中通过加载外部图片进行显示。专辑的封面图片如图1.78所示,其访问路径为“images/albumcover.jpg”。

图1.78 专辑的封面图片

1.7.2.2 制作XML文件

接下来,需要制作XML数据文件。XML的编辑和保存非常方便,用户可以使用Windows系统中普通的记事本软件,也可以使用类似Notepad++的专业编辑工具。在XML中,在data主节点下创建title、name、description和image4个子节点,分别用于放置专辑的标题、歌手名、介绍信息和图像。XML代码如下:

    <? xml version="1.0" encoding="utf-8"? >
    <data>
        <title>Brothers in Arms</title>
        <name>Dire Straits</name>
        <description>Brothers in Arms is the fifth studio album by British rock band Dire Straits.</
    description>
        <image>images/albumcover.jpg</image>
    </data>

·经验·

当XML内容中含有“<”和“&”这样的特殊字符时,可通过CDATA进行转义。如类似<name>内<容</name>这样有问题的XML语句,可以修改为<name><! [CDATA[内<容]]></name>。

编辑好内容后,将该文件另存为UTF-8编码格式的xml文件,这样就准备好XML格式的数据文件了。

1.7.2.3 制作XML加载代码

与加载图片的不同之处在于,在Flash中加载XML需要通过URLLoader来实现。因此,首先需要创建一个URLLoader对象。在动作面板中输入如下代码:

    //定义xml的加载对象
    var loader_xml:URLLoader = new URLLoader();

·经验·

在Flash中,所有从外部加载进来并能够在屏幕中显示出来的文件,如SWF、JPG、PNG、GIF文件等,都只能通过Loader对象进行加载。除此之外,XML、JSON、TXT等数据文件则需要通过URLLoader对象进行加载。

接下来,编写一个函数来加载xml文件。加载的动作通过调用URLLoader对象的load方法来完成,这和Loader对象的使用方法基本相同。在动作面板中输入如下代码:

    //加载xml文件
    function loadXML() {
        var url:URLRequest =  new URLRequest("xml/7.xml");
        loader_xml.load(url);
        //当加载xml完成时触发xmlLoaded函数
        loader_xml.addEventListener(Event.COMPLETE, xmlLoaded);
    }

然后,制作xml文件加载完毕的处理函数。在动作面板中输入如下代码:

    function xmlLoaded(e) {
        //定义一个xml对象
        var xml:XML;
        //将加载的数据转换为XML对象
        xml = new XML(loader_xml.data);
        //提取xml中的专辑标题、歌手、简介信息,显示在相应的文本框中
        tTitle.text = xml.title[0];
        tName.text = xml.name[0];
        tDescription.text = xml.description[0];
    }
    //执行loadXML函数,开始加载xml
    loadXML();

在以上代码中创建了一个XML对象,并将加载的XML数据转换为XML。在此之后,就可以从XML中提取各种信息了。此外,这里的XML文件中只含有一张专辑的信息,在调取每种信息时只需要获取XML节点中的第一个值即可。如xml.title[0]即表示取xml中第一个title节点的值。测试影片,可以看到文字被填写在Flash的相应文本框中,如图1.79所示。

图1.79 在文本框中显示XML数据

·注意·

如果读者想了解更多关于XML处理方面的基础知识,可以浏览本书配套资源文件中“ActionScript 3.0应用视频手册”的“XML对象”部分。

最后,还需要制作专辑封面图片的加载动作,此时可以使用上一个案例中制作好的loadlmage函数来完成图片加载。在xmlLoaded函数中,添加ActionScript代码如下:

    //以下代码放置于xmlLoaded函数中
    //创建一个容器来加载封面图片
    var mc:MovieClip = new MovieClip();
    mc.x = 121;
    mc.y = 73;
    addChild(mc);
    //加载封面图片,loadImage函数下略,可参考前一节内容
    loadImage(mc, xml.image[0]);

测试影片,现在就能够看到XML加载后的数据效果了,如图1.80所示。

图1.80 最终测试效果

1.7.3 案例延伸 JSON加载

源文件位置 资源下载 > 源文件 > 第1章 > 07

学习目的 掌握在Flash中加载JSON数据的技巧

难易指数 ★★☆☆☆

在很长时间之内,XML都是在Flash中实现数据交互的唯一方法。然而,JSON的出现改变了这一状况。相比XML, JSON的内容更加简洁,数据加载起来更快。在过去,要在Flash中使用JSON,只能通过自己编写处理代码,或者通过第三方类库来实现。如今,Adobe在Flash Player 11之后的版本中都提供了原生的JSON支持,这使得用户在Flash中处理JSON数据变得更加方便了。

首先,制作一个包含JSON数据的文件,将其命名为json.php。其内容代码如下:

    {
        "title": “Singing in the sky",
        "name": "Sky Singer",
        "description": "Singing in the sky, Skinned our hearts and skinned our knees.",
        "image":"images/albumcover2.jpg"
    }

·经验·

和XML相比,JSON的内容是不是更加精简呢?如果读者想了解更多有关JSON的内容,可以访问网站http://www.json.org

JSON加载和XML加载的方式几乎相同,不同之处在于数据的处理。加载好的JSON数据需要转换为Object对象,所有的数据都可以在对象中进行获取。JSON的加载代码如下:

    //定义JSON的加载对象
    var loader_json:URLLoader = new URLLoader();
    //定义一个对象来储存JSON数据
    var jsonData:Object;
    //加载JSON文件
    function loadJSON() {
        loader_json.load(new URLRequest("json.php"));
        //当加载JSON完成时触发xmlLoaded函数
        loader_json.addEventListener(Event.COMPLETE, jsonLoaded);
    }
    function jsonLoaded(e) {
        //将加载的数据转换为JSON对象
        jsonData = JSON.parse(loader_json.data);
        //提取JSON中的专辑标题、歌手名、简介信息,显示在相应的文本框中
        tTitle.text = jsonData.title;
        tName.text = jsonData.name;
        tDescription.text = jsonData.description;
        //创建一个容器来加载封面图片
        var mc:MovieClip = new MovieClip();
        mc.x = 121;
        mc.y = 73;
        addChild(mc);
        //加载封面图片
        loadImage(mc, jsonData.image);
    }
    //加载图片的函数
    function loadImage(holder:MovieClip , url:String) {
        var loader:Loader = new Loader();
        loader.load(new URLRequest(url));
        holder.addChild(loader);
    }
    //执行loadJSON函数,开始加载json
    loadJSON();

测试影片,现在就能看到JSON数据的加载效果了,如图1.81所示。

图1.81 JSON加载效果

·注意·

使用有Flash Player 11以上的版本才支持原生JSON功能,如果试图用低版本Flash Player打开资源文件中的相应swf文件,将有可能报错。

1.8 Flash进度加载之——动态页面加载

源文件位置 资源下载 > 源文件 > 第1章 > 08

视频位置 资源下载 > 视频 > 第1章 > 08

难易指数 ★☆☆☆☆

学习目的 掌握在Flash中与动态页面进行数据交互的技巧

1.8.1 实现效果

在制作Flash互动应用时,不仅需要从服务器端单向下载XML、JSON数据,往往还需要向服务器发送数据,并从接受数据的动态页面中取得服务器返回的数据。本案例就将介绍这样的数据双向交互功能。

案例的呈现方式是一个简单的注册表单。表单由两个输入文本框构成,供用户输入姓名,如图1.82所示。

当用户在表单中填写好信息并提交后,将根据服务器返回的数据显示是否注册成功,如图1.83所示。

图1.82 姓名表单

图1.83 数据提交后效果

1.8.2 制作步骤

1.8.2.1 制作页面背景和文本框

01新建一个Flash文档,导入页面背景,如图1.84所示。

图1.84 导入页面背景

02在输入表单的相应位置绘制两个文本框,文本框类型为输入文本,分别将其舞台实例命名为tFirstName和tLastName,如图1.85所示。这两个文本框分别用于输入用户的名和姓。

图1.85 制作输入文本框

03在表单下方,再制作一个动态文本框,将文本颜色设置为红色,舞台实例命名为tMessage。该文本框将用于显示服务器返回的信息。在tMessage文本框右侧制作一个提交按钮,按钮实例命名为bSubmit,如图1.86所示。

图1.86 制作动态文本框

1.8.2.2 制作表单提交代码

接下来,需要制作表单代码来提交信息。假设服务器接受数据的动态页面地址为postdata.php,在动作面板中输入如下代码:

    var loader:URLLoader = new URLLoader();
    var url:URLRequest =  new URLRequest("postdata.php");
    //创建URLVariables对象来向服务器传输变量
    var values:URLVariables = new URLVariables();
    //当提交按钮按下时,触发submit函数
    bSubmit.addEventListener(MouseEvent.MOUSE_DOWN, submit);
    function submit(e:MouseEvent):void{
        //判断表单的两个文本框是否已填写
        if(tFirstName.text && tLastName.text){
            //设置以POST方式向服务器传输数据
            url.method = URLRequestMethod.POST;
            //设置向服务器传输的变量的值
            values.firstname = tFirstName.text;
            values.lastname = tLastName.text;
            url.data = values;
            //使用load方法加载动态页面并POST数据
            loader.load(url);
            loader.addEventListener(Event.COMPLETE, jsonLoaded);
        }
    }

从以上代码可以看到,通过动态页面向服务器端传送数据,与从服务器端加载XML或JSON数据是几乎相同的,只不过在URLRequest对象中定义了数据传输的格式,并附加了一个URLVariables对象来传输变量。以上代码以POST方式向postdata.php发送了两个变量,分别为firstname和lastname。

1.8.2.3 接收JSON数据

假设服务器上的动态页面postdata.php接收到数据后,将数据保存到数据库中。如果这些操作顺利完成,postdata.php将返回一个JSON对象,告诉Flash该信息已经顺利上传到数据库中。返回的JSON数据如下:

    {
        "status": 0,
        "message": "Your message has been successfully uploaded! "
    }

其中,JSON对象中的status表示返回的操作状态,0表示操作成功,1表示操作失败;message表示返回给Flash的描述信息。接下来所要做的是获取动态页面的返回数据,并通过jsonLoaded函数将这些信息显示在Flash中。

之前的案例中已经介绍了使用Flash中的原生JSON解析功能。然而,由于该功能只在Flash Player 11以上的版本中有效,如果想要确保在其他版本的Flash Player中也能正常操作JSON,需要使用一些第三方类库。在此,将使用as3corelib提供的JSON类库。读者可以在GitHub中获取这个类库,下载地址为https://github.com/mikechambers/as3corelib。在动作面板中输入如下代码:

    //导入JSON类库
    import com.adobe.serialization.json.JSON;
    function jsonLoaded(e:Event):void {
        //判断JSON数据中status数值是否为0,若为0表示操作成功
        if (String(JSON.decode(loader.data).status)=="0") {
            //当操作成功时,在tMessage文本框中显示JSON中的message信息
            tMessage.text = String(JSON.decode(loader.data).message);
        } else {
            //当操作不成功时,输出错误信息
            tMessage.text = "something wrong...";
        }
    }

需要注意的是,与操作原生JSON功能不同,as3corelib的JSON类库使用decode方法来解析JSON数据。测试影片,在表单中填写好信息,如图1.87所示。

单击SUBMlT按钮提交数据,在tMessage文本框中将显示从动态页面中回调的message信息。当postdata.php返回的status数值为1时,表单将输出错误信息,如图1.88所示。

图1.87 在表单中填写信息

图1.88 输出错误信息的情况

·注意·

当使用as3corelib提供的JSON类库,并在Flash CS6中选择Flash Player 11发布SWF文件时,将和Flash自带的JSON类发生命名冲突。此时需要将JSON进行完整引用,如获取status信息需要写为com.adobe.serialization.json.JSON.decode(loader.data).status。

1.8.3 案例延伸 GET方式传输数据

源文件位置 资源下载 > 源文件 > 第1章 > 08

学习目的 掌握在Flash中使用GET方式传输数据的技巧

难易指数 ★☆☆☆☆

上一个案例中使用了POST的方式向动态页面传输数据。然而,在许多情况下,动态页面会通过GET方式接收数据。此时,只需要修改URLRequest对象的method属性为GET即可。代码如下:

      function submit(e:MouseEvent):void {
          if (tFirstName.text && tLastName.text) {
              //用GET方式向服务器传输数据
              url.method = URLRequestMethod.GET;
              values.firstname=tFirstName.text;
              values.lastname=tLastName.text;
              url.data= values;
              loader.load(url);
              loader.addEventListener(Event.COMPLETE, jsonLoaded);
          }
      }

测试影片,在表单中输入文本,如图1.89所示。

当提交表单时,数据会以postdata.php? firstname=Liang&lastname=Rushui的方式发送到动态页面,这样的数据传输方式被称为GET方式。最终数据回调的效果与之前的POST方式相同,如图1.90所示。

图1.89 在表单中填写信息

图1.90 数据回调效果

·注意·

以上案例的测试需要WEB服务器端支持,如在本地电脑中测试,可以安装IIS或Apache,然后通过Localhost进行访问。

1.9 Flash进度加载之——SWF加载

源文件位置 资源下载 > 源文件 > 第1章 > 09

视频位置 资源下载 > 视频 > 第1章 > 09

难易指数 ★★☆☆☆

学习目的 掌握在Flash中加载外部SWF文件的技巧

1.9.1 实现效果

在本章第5节中,曾经介绍了SWF文件的自身加载。在开发迷你站点之类的Flash互动应用时,由于站点的整体文件尺寸很大,为了便于更快加载,通常将站点分割成一个主SWF与多个子SWF的形式,在主文件中按需加载各个子文件,这就涉及Flash的外部SWF文件加载。

在本例中,将制作一个主SWF文件和一个被加载的子SWF文件。当加载正在进行时,舞台中将显示为加载图标,如图1.91所示。

图1.91 加载进行效果

当加载结束时,将播放并显示子SWF文件的内容,如图1.92~图1.95所示。

图1.92 子文件内容显示1

图1.93 子文件内容显示2

图1.94 子文件内容显示3

图1.95 子文件内容显示4

1.9.2 制作步骤

1.9.2.1 制作主文件

一个Flash交互应用的主文件又常常被称为“外壳”文件,或“Shell”文件。顾名思义,主文件实际上只是一个壳,并没有太多的内容,它的功能主要是用于加载其他子文件。当用户访问Flash应用时,首先下载这个壳文件,然后在其基础上再加载包含各种内容的子文件。

01新建一个Flash文档,将其命名为shell.fla。在该文件中制作页面背景,如图1.96所示。

图1.96 制作页面背景

02然后,在页面中央制作一个旋转的动画元件,作为“加载中”的状态标志,如图1.97所示。该元件的舞台实例命名为mRing。

图1.97 “加载中”动画元件

现在就完成了主文件的制作。接下来,将制作被加载的子文件。

·经验·

这里希望壳文件的体积越小越好,以便其尽快被用户下载。在制作时,也应该遵循这一原则,除与加载相关的元素外,尽量不在壳文件中加入其他增加文件大小的内容。

1.9.2.2 制作被加载的子文件

01新建一个Flash文档,将子文件中的各种页面元素制作并排列在舞台上,如图1.98所示。

图1.98 子文件页面元素

02接着,制作这些元素的时间轴动画。页面中共有三种元素,将其放置在三个图层中分别制作动画,如图1.99所示。

图1.99页面元素时间轴动画

03然后,新建一个图层,用于编写ActionScript代码。在动画的第一帧和最后一帧创建空白关键帧,分别在这两帧中写入stop()代码,使动画在开始和结束时均停止,如图1.100所示。

图1.100 创建代码图层

·经验·

这里添加的stop()代码将使子文件在加载完毕并初始化后停留在第一帧。此时动画的第一帧是留空的,将不会显示任何内容,直到子文件播放动画时,再开始显示内容。

04最后,保存子文件,将其命名为mask.swf,并测试影片,生成SWF文件。由于文件在一开始就停止播放,如果想要预览子文件的显示效果,需要在测试窗口中单击鼠标右键,选择“播放”命令进行手动播放。测试效果如图1.101所示。

图1.101子文件测试结果

1.9.2.3 制作加载代码

接下来,需要在主文件编写代码来加载子文件。回到shell.fla,在动作面板中创建如下代码:

    import com.greensock.*;
    //创建一个子文件的显示容器
    var mc:MovieClip = new MovieClip();
    var loader:Loader = new Loader();
    //加载子文件
    loader.load(new URLRequest("mask.swf"));
    mc.addChild(loader);
    addChild(mc);
    //侦听子文件的加载完毕事件
    loader.contentLoaderInfo.addEventListener(Event.INIT, initHandler);
    //当子文件加载完毕时,从子文件第二帧开始播放动画,并淡出下载中标志
    function initHandler(event:Event):void {
        event.target.content.gotoAndPlay(2);
        TweenLite.to(mRing, 1, {alpha:0});
    }

·经验·

Flash在其参考手册中提出:“当加载由Flash Professional生成的SWF文件时,应使用fl.display.ProLoader而非flash.display. Loader”。然而,事实上,ProLoader主要在类似加载使用了TLF文本的SWF等情况下有别于Loader,这些都是在一般项目中较为少见的情形。而一旦使用ProLoader,必须使用Flash CS5.5以上版本才能正确发布文件。在团队协作中,如果还有成员使用之前的版本,就会产生问题。在没有太大区别的情况下,建议继续使用Loader。本书的相关案例也都使用Loader而非ProLoader。

在以上代码中,用Loader对象来加载子SWF,当加载完毕时开始播放子文件。代码的重点在于如何在主文件中控制子文件的时间轴动画,其方法是通过event. target.content的方式获得对子文件对象的引用。测试影片,现在就能看到子文件的加载和播放效果了,如图1.102所示。

图1.102 最终测试效果

·经验·

事实上,在文件加载过程中,加载完毕事件应该为Event.COMPLETE,而非Event.INIT。然而,Event.COMPLETE罕为使用,绝大多数情况下都使用Event.INIT事件。这是因为当COMPLETE事件触发时,文件虽然已经下载完毕,但还没有完成初始化,因此不能对文件进行任何操作,也不能获取文件的任何属性。类似本例中控制子文件的时间轴播放,只能放在INIT事件触发的函数中进行。

1.9.3 案例延伸 SWF加载切换

源文件位置 资源下载 > 源文件 > 第1章 > 09

学习目的 掌握在Flash中加载和切换多个SWF文件的技巧

难易指数 ★★★☆☆

上一案例中,在主文件中只加载了一个子文件,如何实现多个子文件的切换加载呢?首先,需要制作一个函数,通过传递不同的参数来加载不同的子文件,这类似于在制作多文件加载时用到的loadlmage函数。创建一个名为openSec的函数,代码如下:

    var mc:MovieClip = new MovieClip();
    addChild(mc);
    //openSec函数用于控制子文件的加载
    function openSec(target:String) {
        mRing.alpha = 1;
        //清空mc,避免加载的子文件重叠在一起
        if (mc.numChildren > 0) {
            var loop:Number = mc.numChildren;
            for(var i:Number = 0; i < loop; i++){
                mc.removeChildAt(0);
            }
        }
        var loader:Loader = new Loader();
        //根据target参数判断加载哪个子文件
        if (target=="main") {
            loader.load(new URLRequest("mask.swf"));
        } else if (target=="sub") {
            loader.load(new URLRequest("mask_sub.swf"));
        }
        mc.addChild(loader);
        loader.contentLoaderInfo.addEventListener(Event.INIT, initHandler);
    }
    openSec("main");

·经验·

在移除子文件的代码中,使用了mc.removeChildAt(0)的做法。如果mc中有3个元素,则一共移除3次,每次都移除最底层的元素,这样就能将mc中的元素彻底移除干净。读者也可以思考一下,为什么在此不使用mc.removeChildAt(i)。

接下来,需要给子文件设置一个变量,使其能够方便地引用主文件。在initHandler函数中创建如下代码:

    function initHandler(event:Event):void {
        event.target.content.gotoAndPlay(2);
        //设置子文件的父容器引用变量
        event.target.content.app = this;
        TweenLite.to(mRing, 1, {alpha:0});
    }

以上代码中,设置了子文件的app属性,并将其指向主文件本身。这样就能通过该属性在文件之间进行通信。在mask.fla中,添加一个“MORE”按钮,如图1.103所示。

图1.103 添加“MORE”按钮

设置按钮的舞台实例名为bMore,为其创建事件侦听。当单击该按钮时,将调用主文件的openSec函数,加载mask_sub.swf。代码如下:

    bMore.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownHandeler);
    function onMouseDownHandeler(e:MouseEvent):void{
        if(this.app){
            this.app.openSec("sub");
        }
    }

创建另一个子文件,将其命名为mask_sub.fla。与mask.fla的制作相同,在该文件中导入页面元素,创建动画,设置起始关键帧的stop()语句,最后在舞台上也放置一个“BACK”按钮,用以控制子文件切换,如图1.104所示。

图1.104 制作mask_sub.fla

将“BACK”按钮的舞台实例命名为bBack,也为其创建事件侦听,代码如下:

    bBack.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownHandeler);
    function onMouseDownHandeler(e:MouseEvent):void{
        if(this.app){
            this.app.openSec("main");
        }
    }

发布mask.swf和mask_sub.swf。现在,就能够通过shell.swf来加载和切换这两个文件了。测试影片时,将默认加载mask.swf,如图1.105所示。

当单击MORE按钮时,将加载并显示mask_sub.swf,如图1.106所示。读者也可以在mask_sub.swf中单击BACK按钮,返回并加载mask.swf。

图1.105 mask.swf加载效果

图1.106 mask_sub加载效果

1.10 Flash进度加载之——站点加载

源文件位置 资源下载 > 源文件 > 第1章 > 10

视频位置 资源下载 > 视频 > 第1章 > 10

难易指数 ★★☆☆☆

学习目的 掌握在Flash中制作站点加载的技巧

1.10.1 实现效果

上一节中介绍了SWF外部文件的加载,以及对所加载文件的简单控制。在实际制作站点时,通常还需要考虑到数据的来源,以及如何在主文件和子文件中共享数据等。本小节将对这样的架构做进一步的探讨。

本例中,在主SWF文件中加载一个XML文件,作为站点的动态内容来源,并根据加载的内容在子SWF文件中设置相应的文字显示,如图1.107所示。

图1.107 案例运行效果

上图中的所有背景元素、文本框均为子SWF文件中的元素,在文本框中显示的文字内容来源于主SWF文件所加载的数据。

1.10.2 制作步骤

1.10.2.1 制作主文件

新建一个Flash文档,命名为shell.fla,该文件将作为站点的主文件。在shell.fla中制作一个带有“LOADING”字样的元件,实例命名为“mLoading”,如图1.108所示。mLoading元件将用于显示子文件的下载状态。

图1.108 shell.fla

1.10.2.2 制作子文件

再新建一个Flash文档,命名为content.fla,该文件将作为站点的子文件。制作好页面背景,然后在舞台上绘制两个动态文本框,分别用来放置页面的标题和详细内容,如图1.109所示。将两个文本框分别命名为tTitle和tDescription。测试影片,生成content.swf文件。

图1.109 在content.fla中绘制文本框

1.10.2.3 制作XML文件

接下来,制作站点的数据文件。新建一个XML文件,命名为conf.xml。其内容如下:

    <? xml version="1.0" encoding="utf-8"? >
    <data>
        <title>Visit My Forest</title>
        <description>A forest, also referred to as a wood or the woods, is an area with a high density
    of trees. As with cities, depending on various cultural definitions, what is considered a forest may
    vary significantly in size and have different classifications according to how and of what the forest is
    composed.</description>
    </data>

conf.xml中包含两个节点,分别为title和description。这两种数据将分别显示在子文件中的相应文本框中。

1.10.2.4 制作加载代码

接下来,回到shell.fla,制作数据文件和子文件的加载。一般来说,由于数据文件中能够包含配置信息,是首先需要加载的对象。在动作面板中输入如下代码:

    var loader_xml:URLLoader = new URLLoader();
    //加载XML文件
    function loadXML() {
        var url:URLRequest = new URLRequest("conf.xml");
        loader_xml.load(url);
        loader_xml.addEventListener(Event.COMPLETE, xmlLoaded);
    }
    loadXML();

当XML加载完毕后,将触发xmlLoaded函数。此时,再进行子文件content.swf的加载。在动作面板中输入如下代码:

    var loader:Loader = new Loader();
    var mc:MovieClip = new MovieClip();
    mc.addChild(loader);
    this.addChild(mc);
    var xml:XML;
    //当XML文件加载完毕时,加载子文件
    function xmlLoaded(e) {
        xml = new XML(loader_xml.data);
        loader.load(new URLRequest("content.swf"));
        loader.contentLoaderInfo.addEventListener(Event.INIT, initHandler);
    }

当content.swf加载完毕时,将触发initHandler函数。此时,在加载好的子文件中,设置其内容显示。在动作面板中输入如下代码:

    //当子文件加载完毕时,设置子文件中的内容显示
    function initHandler(event:Event):void {
        mLoading.visible = false;
        event.target.content.tTitle.text = xml.title[0];
        event.target.content.tDescription.text = xml.description[0];
    }

现在,测试影片,就能够看到XML内容被填入子文件的文本框中,如图1.110所示。

图1.110 案例运行效果

·经验·

为了使XML能够最大限度地配置Flash中的各种功能,常常还将子文件的路径写入XML中,通过XML中的路径信息来加载对应的文件。这样,一旦content.swf的文件名发生变化,只需要修改XML即可,不需要重新发布主文件。

1.10.3 案例延伸 站点数据传递

源文件位置 资源下载 > 源文件 > 第1章 > 10

学习目的 掌握在Flash中向站点的子文件传输数据的技巧

难易指数 ★★☆☆☆

在上一案例中,直接在主文件中设置了子文件中的数据显示。从代码维护的角度来说,这是不太合理的,很可能在一段时间之后会忘记控制子文件的代码放在哪里了。较好的方式是主文件将数据传递给子文件,由子文件来控制自己的内容显示,这样任何时候要修改这些功能,只需要在子文件自身中寻找控制代码即可。

要将数据传递给子文件,只需要在子文件加载完毕时,给子文件设置一个变量即可。修改initHandler函数,代码如下:

      function initHandler(event:Event):void {
          mLoading.visible = false;
          //创建一个对象,在对象中存储数据
          var _data:Object = new Object();
          _data.title = xml.title[0];
          _data.description = xml.description[0];
          //将数据传输给子文件
          event.target.content.mydata = _data;
          //调用子文件中的setText函数刷新显示
          event.target.content.setText();
      }

在以上代码中,用一个Object对象作为数据的载体,将数据传输给子文件,然后调用一个子文件中的setText函数来显示内容。在子文件中制作这个函数,代码如下:

      function setText() {
          //判断父文件传递过来的数据对象是否存在
          if (this.mydata) {
              //设置文本显示
              tTitle.text = this.mydata.title;
              tDescription.text = this.mydata.description;
          }
      }

现在,测试影片,在子文件中就将显示父文件传递的数据信息,如图1.111所示。

图1.111 案例运行效果

1.11 Flash进度加载之——本地文本文件加载

源文件位置 资源下载 > 源文件 > 第1章 > 11

视频位置 资源下载 > 视频 > 第1章 > 11

难易指数 ★★★☆☆

学习目的 掌握在Flash中制作本地文本文件加载的技巧

1.11.1 实现效果

在as2.0的年代里,很难想象可以直接通过Flash打开和读取电脑中的各种文件,直到迎来了as3.0。ActionScript 3.0的本地文件操作功能使用户能够直接使用Flash来制作功能强大的本地应用。本例中,将制作本地文本文件的加载功能,其界面如图1.112所示。

单击BROWSE按钮,选择并打开一个本地txt文件,文件内容将被读取并显示在Flash中,如图1.113所示。

·经验·

试想一下,如果要制作一个通信录文件上传功能,传统的方式是将通信录文本文件上传到服务器,由服务器读取文件的内容并进行处理。而通过本地文本文件加载功能,可以在Flash中直接获取通信录中的文本内容,并对数据进行预处理,如分析每一条记录是否符合手机号码规则等,最后将数据直接上传保存到服务器的数据库中。这样数据的操作将变得更加简便,也减小了服务器的压力。

图1.112 案例界面效果

图1.113 文本打开效果

1.11.2 制作步骤

1.11.2.1 制作基本元素

01首先,新建一个Flash文档,制作页面背景,如图1.114所示。

图1.114 制作页面背景

02制作两个按钮,分别为“BROWSE”和“CLEAR”,如图1.115所示。将两个按钮实例分别命名为bBrowse和bClear,其功能分别为浏览文件和清除文件。

图1.115 制作按钮

03最后,创建动态文本框,用来显示文本文件内容,如图1.116所示。文本框实例命名为tf。

·注意·

由于文本文件中可能含有中文字符,用户需要在文本框中嵌入相应字体的所有中文字符,以确保其正常显示。中文字库比较庞大,以这种方式导出的SWF文件相应也会较大。另外一种做法是将动态文本框的字体设置为“宋体”,并使用设备文本的显示方式,其缺点是字体不够美观。

图1.116 创建tf文本框

1.11.2.2 制作文本文件加载

要打开一个本地文件,首先需要通过Flash打开一个本地文件对话框,以便于选择目标文件。可以使用FileReference对象来实现这样的功能。在动作面板中输入如下代码:

    //导入FileReference类
    import flash.net.FileReference;
    //创建一个FileReference对象
    var fileReference:FileReference = new FileReference();
    //创建一个文件类型过滤对象
    var fileFilter:FileFilter = new FileFilter("文本文件", "*.txt");
    //当按下BROWSE按钮时,弹出文件对话框,供用户选择要打开的文件
    bBrowse.addEventListener(MouseEvent.MOUSE_DOWN, browseFile);
    function browseFile(e:MouseEvent) {
        //通过使用fileFilter来限制用户只能选择txt文本文件
        fileReference.browse([fileFilter]);
    }

测试影片,当单击BROWSE按钮时,将打开操作系统的文件对话框,如图1.117所示。由于FileFilter对象的限制,在对话框中只能选择txt后缀的文本文件。

图1.117 文件对话框

接下来,需要加载在对话框中选择的文件。在动作面板中输入如下代码:

    fileReference.addEventListener(Event.SELECT, onSelectFile);
    fileReference.addEventListener(Event.COMPLETE, onFileComplete);
    //当用户在文件对话框中选择某个文件后,在Flash中加载该文件
    function onSelectFile(event:Event):void {
        fileReference.load();
    }
    //当文件加载完毕时,显示文本内容
    function onFileComplete(event:Event):void {
        //在tf文本框中显示打开文件的名称
        tf.htmlText = "opening: " + fileReference.name + "<br>";
        //加载的文本数据为二进制数据,需要将其转换为GB2312编码的字符串
        var bytes:ByteArray = fileReference.data;
        var newtext:String=fileReference.data.readMultiByte(fileReference.data.length, "gb2312");
        //在tf文本框中显示文本内容
        tf.appendText(newtext);
    }

在以上代码中,文件的选择和加载都可以通过为FileReference对象注册事件侦听来实现,加载好的文件数据可以通过fileReference.data来获取,只需将其由二进制数据转换为正确编码的字符串,就可以显示在文本框中了。测试影片,选择并打开一个本地txt文件,文本加载效果如图1.118所示。

图1.118 文本打开效果

最后,为CLEAR按钮添加清空文本框显示的功能即可。在动作面板中输入如下代码:

    bClear.addEventListener(MouseEvent.MOUSE_DOWN, clearTF);
    //当单击CLEAR按钮时,清空文本显示
    function clearTF(e){
        tf.text = “”;
    }

再次测试文件。打开文本文件后,通过单击CLEAR按钮,就能够清空文本框显示了,如图1.119所示。

图1.119 文本清空效果

1.11.3 案例延伸 UTF-8编码文本文件加载

源文件位置 资源下载 > 源文件 > 第1章 > 11

学习目的 掌握在Flash中加载以UTF-8格式编码的文本文件的技巧

难易指数 ★★★☆☆

上一案例中加载的是以ANSl形式编码的文本文件,即Windows的记事本软件默认的保存格式。然而,当试图加载UTF-8编码的文本文件时,中文字符将会出现乱码,如图1.120所示。

图1.120 中文字符乱码

UTF-8是一种常见的编码格式,尤其是在制作带有多国语言的Flash应用时,必须使用UTF-8编码来统一处理不同种类的语言文字。那么,如何能够在Flash中正常打开UTF-8编码的文本文件呢?在之前案例的基础上,只需要改变二进制数据转换为字符串的编码方式即可。修改onFileComplete函数,代码如下:

      function onFileComplete(event:Event):void {
          tf.htmlText = "opening: " + fileReference.name + "<br>";
          var bytes:ByteArray = fileReference.data;
          //以UTF-8格式转换二进制数据
          var newtext:String = fileReference.data.readUTFBytes(fileReference.data.length);
          tf.appendText(newtext);
      }

测试影片,在影片中打开UTF-8编码的文本文件,现在就不会发生中文乱码问题了。

1.12 Flash进度加载之——本地图像文件加载

源文件位置 资源下载 > 源文件 > 第1章 > 12

视频位置 资源下载 > 视频 > 第1章 > 12

难易指数 ★★★☆☆

学习目的 掌握在Flash中制作本地图像文件加载的技巧

1.12.1 实现效果

Flash的文件操作不仅限于文本文件,还可以实现对图像文件的加载。根据这个特性,完全可以在Flash中制作基于本地图像文件的各种应用。本例中将制作一个简单的图像浏览器,其界面如图1.121所示。

单击BROWSE按钮,可以选择一张本地的图片文件,将其加载到图像浏览器中,如图1.122所示。

图1.121 图像浏览器界面

图1.122 图像加载效果

该图像浏览器能够加载JPG、PNG、GlF等多种格式的图像文件。在此基础上,还能够进一步制作图片拼接、图片调色之类的本地图像处理应用。

·注意·

低版本的Flash开发软件由于其内置Flash Player版本限制,不支持一些本地图像文件处理操作。制作本案例时,请确保使用的是Flash CS5以上的开发版本。

1.12.2 制作步骤

1.12.2.1 制作界面元素

01新建Flash文档。首先,制作界面背景,如图1.123所示。

图1.123 界面背景

02制作一个按钮,用来浏览本地电脑中的图像文件,如图1.124所示。将按钮实例命名为bBrowse。

图1.124 bBrowse按钮

03制作一个影片剪辑,作为加载图片的容器。并绘制一个黑色矩形,对影片剪辑进行遮罩,使显示的图片不会超出矩形范围,如图1.125所示。将影片剪辑实例命名为mHolder。

图1.125 制作影片剪辑及其遮罩

接下来,将通过编写代码来实现在mHolder中加载本地图像文件的效果。

1.12.2.2 制作文本文件加载

打开本地图像文件的方法与文本文件基本相同,都是通过单击BROWSE按钮,调用FileReference来显示文件对话框。当用户在对话框中选择了某个图像文件后,再调用FileReference的load方法来加载该文件。在动作面板中输入如下代码:

    var refF:FileReference = new FileReference();
    var fileFilter:FileFilter = new FileFilter("Images", "*.png; *.gif; *.jpg");
    var loader:Loader = new Loader();
    bBrowse.addEventListener(MouseEvent.MOUSE_DOWN, browseImage);
    function browseImage(e:MouseEvent):void {
        refF.browse([fileFilter]);
        refF.addEventListener(Event.SELECT, onSelectFile);
    }
    function onSelectFile(e:Event):void {
        refF.load();
        refF.addEventListener(Event.COMPLETE, onComplete);
        //移除refF的SELECT事件侦听
        refF.removeEventListener(Event.SELECT, onSelectFile);
    }
    function onComplete(e:Event):void {
        //移除refF的COMPLETE事件侦听
        refF.removeEventListener(Event.COMPLETE, onComplete);
        //使用Loader对象以二进制方式加载位图数据
        loader.loadBytes(refF.data);
        //显示图像
        mHolder.addChild(loader);
    }

当图像文件的数据通过FileReference对象加载完毕后,其当前状态为二进制数据,需要通过Loader对象的loadBytes方法来加载二进制图像数据。然后,将Loader对象添加到mHolder容器中,使图像显示在舞台上。

·经验·

以上代码中,并没有像上一个案例那样,在一开始就为FileReference对象注册SELECT和COMPLETE事件侦听,而是在用户单击BROWSE按钮后,再注册SELECT事件侦听。当用户在文件对话框中选择了某个文件后,移除SELECT事件侦听,同时注册COMPLETE事件侦听。当文件成功加载到Flash中后,再移除COMPLETE事件侦听。这样按实际需求来动态添加和移除事件侦听的方式,能够使代码更加清晰和便于维护,避免代码BUG的产生。

测试影片,单击BROWSE按钮,此时将弹出文件对话框。由于FileFilter对象的限定,在对话框中只能选择JPG、PNG、GlF类型的图像文件,如图1.126所示。

图1.126 文件对话框

选择要打开的图像文件,图像就被加载并显示在舞台中,如图1.127所示。

图1.127 图像加载效果

1.12.3 案例延伸 本地图像文件处理

源文件位置 资源下载 > 源文件 > 第1章 > 12

学习目的 掌握在Flash中对加载的本地位图进行图像处理的技巧

难易指数 ★★★☆☆

使用Flash做一个纯粹的图像浏览器似乎有点死板,不妨发挥一下创意,在打开的位图文件中做一些简单的图像处理。比如,在每张打开的图像上都添加“雪花”效果。首先,修改上一案例的onComplete函数,代码如下:

      function onComplete(e:Event):void {
          refF.removeEventListener(Event.COMPLETE, onComplete);
          loader.loadBytes(refF.data);
          //侦听Loader的加载完毕事件
          loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete);
      }

要制作“雪花”效果,需要对位图进行图像处理,因此在代码中,没有像上一例那样直接将Loader对象显示在mHolder中,而是等待Loader的图像加载完毕后,进一步执行图像处理功能。接下来,创建onLoadComplete函数,代码如下:

    //当Loader对象的位图数据加载完毕时,显示图像
    function onLoadComplete(e:Event):void {
        var pt:Point = new Point(0, 0);
        //创建一个BitmapDat位图对象,宽度和高度与所加载的位图相同
        var tempData:BitmapData = new BitmapData(loader.width, loader.height);
        //在BitmapData中绘制位图
        tempData.draw(loader);
        //溶解位图
        tempData.pixelDissolve(tempData, tempData.rect, pt, Math.random(), 20000, 0x99FFFFFF);
        //将BitmapData位图转换为可显示的Bitmap对象
        var bitmap:Bitmap = new Bitmap(tempData);
        //将Bitmap对象显示在mHolder容器中
        mHolder.addChild(bitmap);
    }

以上代码中创建了tempData位图对象,将Loader中的位图绘制到tempData中。然后对位图进行溶解处理,产生“雪花”效果。最后,将位图转换为Bitmap显示对象,添加到mHolder容器中。

测试影片,现在在图像浏览器中打开图片,就能够看到雪花效果了,如图1.128所示。

图1.128 图片雪花效果

·经验·

位图的pixelDissolve(溶解)方法能够产生类似雪花的效果。该方法共有6个参数:要溶解的位图、位图的溶解区域大小、溶解区域的起始点、一个随机数来产生随机的溶解效果、溶解的像素点数量以及溶解点的颜色值。