分类
Flash professional

使用“文档类”

虽然我们仍然可以将 AS3 代码写在时间轴上,但为了使我们的代码能够更好地被重用,最好的方法是将代码写在专门的 AS3 文档中。

在 AS3 中有引入了一新的概念:文档类(document class)。基本上可以说,一个文档类(document class)就是一个扩展了的精灵(Sprite)或影片剪辑(MovieClip)类,并且它将做为你的 SWF 的主类。当 SWF 被载入时,这个类的构造函数将会被调用。那将是你想要让影片做什么的进入点,如创建附加的影片剪辑,绘制图表,预载素材,等等。

文档类的基本结构是:

分类
Flash professional

如何使影片剪辑运动起来?

如果我们想影片剪辑运动起来,并给它设置一特定的速度运动,这时就需要用到ENTER_FRAME事件了。例如,你可以制作一个狗狗的影片剪辑,类名为Gougou,下面,我们就通过一小段程序复制库中Gougou的一个副本,并且让他每帧移动一个像素,代码如下:

  1. var gou1:Gougou = new Gougou();
  2. gou1.x = 50;
  3. gou1.y = 500;
  4. addChild(gou1);
  5. addEventListener(Event.ENTER_FRAME, gou1zou);
  6. function gou1zou(e:Event) {
  7. gou1.x++;
  8. }

现在,测试影片可以看到,这个gou1开始从屏幕坐标(50,500)处每帧以一个像素的速度水平向右移动,如果想让该影片剪辑每次移动3个像素的话,代码改为
gou1.x+=3; 即可。
注意:你还可以通过改变舞台属性面板上的帧频来控制对象的运动速度,系统默认值为每秒24帧,你可以更改该值为[1,120]内的任意数。事实上,你如果选择了帧频为
120的话,并不意味着影片每秒运行120帧,如果该影片剪辑比较大,并且你的机器比较慢,那么,他将达不到每秒120帧。

在游戏的过程中,我们经常遇到任务行走,这个问题的flash中怎么解决的呢?首先假设该影片剪辑有30帧,从第二帧到第30帧为步行的一个循环,每帧代表不同的步进,第一帧作为站立的位置被保留。制作完成以后,在时间轴内输入下面的帧频事件和帧频函数,在函数内,我们将要创建该角色每帧在水平位置移动3像素,后面的条件代码是检测该影片剪辑的当前帧数,如果为30帧的话,它将要返回的第二帧继续运动,否则,它继续下面的一帧。源代码如下:

  1. var gou2:Gougou = new Gougou ();
  2. gou2.x = 50;
  3. gou2.y = 400;
  4. addChild(gou2);
  5. addEventListener(Event.ENTER_FRAME, gou2zou);
  6. function gou2zou(event:Event)
  7. {
  8. gou2.x += 3;
  9. if (gou2.currentFrame == 30)
  10. {
  11. gou2.gotoAndStop(2);
  12. } else
  13. {
  14. gou2.gotoAndStop(gou2.currentFrame+1);
  15. }
  16. }
进一步的代码:
  1. var gou1:Gougou = new Gougou();
  2. gou1.x = 50;
  3. gou1.y = 500;
  4. addChild(gou1);
  5. addEventListener(Event.ENTER_FRAME, gou1zou);
  6. function gou1zou(event:Event) {
  7. gou1.x+=3;
  8. }
  9. var gou2:Gougou = new Gougou ();
  10. gou2.x = 50;
  11. gou2.y = 400;
  12. addChild(gou2);
  13. addEventListener(Event.ENTER_FRAME, gou2zou);
  14. function gou2zou(event:Event)
  15. {
  16. gou2.x += 3;
  17. if (gou2.currentFrame == 30)
  18. {
  19. gou2.gotoAndStop(2);
  20. } else
  21. {
  22. gou2.gotoAndStop(gou2.currentFrame+1);
  23. }
  24. }
  25. for(var i=0;i<10;i++){
  26. var xGougou:Gougou=new Gougou();
  27. xGougou.x=50*i+50;
  28. xGougou.y=400;
  29. xGougou.z=150*i+50;
  30. xGougou.scaleX=.8;
  31. xGougou.scaleY=.8;
  32. xGougou.j=i
  33. addChild(xGougou);
  34. xGougou.addEventListener(Event.ENTER_FRAME, gou3zou);
  35. function gou3zou(event:Event) {
  36. (event.target).x+=(event.target).j+3;
  37. }
  38. }

分类
Flash professional

AS3 快速入门

编程基础

因为 ActionScript 是一种编程语言,所以,如果您首先了解几个通用的计算机编程概念,则会对您学习 ActionScript 很有帮
助。
计算机程序的用途
首先,对计算机程序的概念及其用途有一个概念性的认识是非常有用的。计算机程序主要包括两个方面:
• 程序是计算机执行的一系列指令或步骤。
• 每一步最终都涉及到对某一段信息或数据的处理。
通常认为,计算机程序只是您提供给计算机并让它逐步执行的指令列表。每个单独的指令都称为语句。正如您将在本手册中看
到的那样,在 ActionScript 中编写的每个语句的末尾都有一个分号。
实质上,程序中指令所做的全部事情是操作存储在计算机内存中的一些数据位

分类
Flash professional

AS3 简介

ActionScript 3.0 的功能大大超越了 ActionScript 的早期版本,它旨在方便创建拥有大型数据集和面向对象的可重用代码库的高度复杂应用程序。由于它使用了新型的虚拟机 AVM2 ,ActionScript 3.0 代码的执行速度可以比旧式 ActionScript 代码快 10 倍。你可以使用ActionScript 3.0 代码来实现任何目的,从简单的图形动画到复杂的客户端-服务器事务处理系统都可以通过它来实现。

分类
Flash professional

as2简介

分类
Flash professional

匹配游戏制作

匹配游戏制作

游戏玩法:

开始游戏后,有若干张背景卡片,其中有两张是相同的。当鼠标点击任意一张卡片后,该卡片自动翻转,然后再点击下一张卡片,翻转后若两张卡片相同,分数加100分,并在屏幕上移除这两张卡片;若不相同,分数会减5分;待所有的卡片都匹配完成后,游戏结束,最后显示出所得分数和所用时间。

制作步骤(主要分成游戏元素的组合,游戏代码的实现两部分):

分类
Flash professional

Flash CS4 Professiona 的组件

Flash CS4 Professiona 的组件

Adobe® Flash® CS4 Professional 组件是带参数的影片剪辑,您可以修改它们的外观和行为。组件可以是一个简单的用户界面控件(如 RadioButton 或 CheckBox),也可以包含内容(如 List  或 DataGrid)。

组件使您可以方便而快速地构建功能强大且具有一致外观和行为的应用程序。您可以使用Flash 组件实现这些控件,而不用创建自定义按钮、组合框和列表。只需将这些组件从“组
件”面板拖到应用程序文档中即可。您还可以方便地自定义这些组件的外观和直观感受,从而适合您的应用程序设计。

即使对 ActionScript 没有深入的理解您也可以进行所有这些工作,还可以使用 ActionScript 3.0 修改组件的行为或实现新的行为。每个组件都有一组唯一的 ActionScript 方法、属性和事件,它们构成了此组件的“应用程序编程接口”(API)。API 允许您在应用程序运行时创建并操作组件。

API 还允许您创建自己的新的自定义组件。您可以从 Adobe Exchange (网址为 http://www.adobe.com/go/flash_exchange_cn)下载由 Flash 社区成员构建的组件。有关创建组件的信息,请参阅 www.adobe.com/go/learn_fl_creating_components_cn

ActionScript 3.0 组件体系结构包括所有组件基于的类、允许您自定义外观的外观和样式、事件处理模型、焦点管理、辅助功能接口等等。

在文档中添加和删除组件

将基于 FLA 的组件从“组件”面板拖到舞台上时, Flash 会将一个可编辑的影片剪辑导入到库中。将基于 SWC 的组件拖到舞台上时, Flash 会将一个已编译的剪辑导入到库中。将组件导入到库中后,您可以将组件的实例从“库”面板或“组件”面板拖到舞台。

通过从“组件”面板拖动组件,可以将组件添加到文档中。在“属性”检查器的“参数”选项卡或“组件”检查器中的“参数”选项卡中可以设置组件每个实例的属性。

使用“组件”面板向 Flash 文档添加组件:

1. 选择“窗口” > “组件”。
2. 双击“组件”面板中的组件,或将组件拖到舞台。
3. 在舞台上选择该组件。
4. 如果看不到“属性”检查器,请选择“窗口” > “属性” > “属性”。
5. 在“属性”检查器中,输入组件实例的实例名称。
6. 单击“参数”选项卡,然后为实例指定参数。
7. 通过编辑宽度 (W:) 和高度 (H:) 的值,按需更改组件的大小。
8. 选择“控制” > “测试影片”或按 Ctrl+Enter 编译文档并查看设置的结果。

您还可以更改组件的颜色和文本格式,方法是设置组件的样式属性,或通过编辑组件的外观自定义其外观。

你也可以在 ActionScript 在运行时添加组件。

若要使用 ActionScript 在运行时将组件添加到文档,当编译 SWF 文件时,组件必须先位于应用程序的“库”(“窗口” > “库”)中。若要将组件添加到“库”中,请将组件从“组件”面板拖到“库”面板中。

您还必须导入组件的类文件,以使应用程序可以使用组件的 API。组件类文件安装在包含一个或多个类的包 中。若要导入组件类,请使用 import 语句并指定包名称和类名称。例如,您可以使用下列 import 语句导入 Button 类:

复制代码

  1. import fl.controls.Button;

若要创建组件的一个实例,必须调用组件的 ActionScript 构造函数方法。例如,下面的语句创建一个名为 aButton 的 Button 实例:

复制代码

  1. var aButton:Button = new Button();

最后一个步骤是调用静态的 addChild() 方法将组件实例添加到舞台或应用程序容器。例如,下面的语句添加 aButton 实例:

复制代码

  1. addChild(aButton);

此时,您可以使用组件的 API 动态指定组件的大小和在舞台上的位置、侦听事件,并设置属性以修改组件的行为。

删除组件

在创作时若要从“舞台”删除组件实例,只需选择该组件,然后按 Delete 键即可。这会从“舞台”删除实例,但不会从应用程序中删除该组件。

在您将组件放置在舞台上或“库”中之后,若要从 Flash 文档删除组件,您必须从“库”中删除组件及与它关联的“资源”。从“舞台”中删除组件是不够的。如果您未从“库”中删除组件,则在您编译时组件会包括在应用程序中。

从文档中删除组件:

1. 在“库”面板中,选择组件的元件。
2. 单击“库”面板底部的“删除”按钮,或从“库”面板菜单中选择“删除”。

重复这些步骤以删除所有与组件关联的资源。

例:使用 Button 组件

Button 组件是一个可调整大小的矩形按钮,用户可以通过鼠标或空格键按下该按钮以在应用程序中启动操作。可以给 Button 添加一个自定义图标。也可以将 Button 的行为从按下改为切换。在单击切换 Button 后,它将保持按下状态,直到再次单击时才会返回到弹起状态。Button 是许多表单和 Web 应用程序的基础部分。每当您需要让用户启动一个事件时,都可以使用按钮实现。例如,大多数表单都有“提交”按钮。您也可以给演示文稿添加“上一个”和“下一个”按钮。

创建具有 Button 组件的应用程序:

1. 创建一个新的 Flash 文件 (ActionScript 3.0) 文档。
2. 将一个 Button 组件从“组件”面板拖到舞台上,并在“属性”检查器中为该组件输入以下值:

■ 输入实例名称 aButton。
■ 为 label 参数输入 Show。

3. 在舞台上添加 ColorPicker,并为它指定实例名称 aCp。
4. 打开“动作”面板,在主时间轴中选择第 1 帧,然后输入以下 ActionScript 代码:

复制代码

  1. aCp.visible = false;
  2. aButton.addEventListener(MouseEvent.CLICK, clickHandler);
  3. function clickHandler(event:MouseEvent):void {
  4. switch(event.currentTarget.label) {
  5. case “Show”:
  6. aCp.visible = true;
  7. aButton.label = “Disable”;
  8. break;
  9. case “Disable”:
  10. aCp.enabled = false;
  11. aButton.label = “Enable”;
  12. break;
  13. case “Enable”:
  14. aCp.enabled = true;
  15. aButton.label = “Hide”;
  16. break;
  17. case “Hide”:
  18. aCp.visible = false;
  19. aButton.label = “Show”;
  20. break;
  21. }
  22. }

第二行代码将函数 clickHandler() 注册为 MouseEvent.CLICK 事件的事件处理函数。用户单击 Button 时,事件将发生,从而使 clickHandler() 函数根据 Button 的值执行以下操作之一:

复制代码

  1. ■ Show 使 ColorPicker 可见,并将 Button 的标签更改为 Disable。
  2. ■ Disable 禁用 ColorPicker,并将 Button 的标签更改为 Enable。
  3. ■ Enable 启用 ColorPicker,并将 Button 的标签更改为 Hide。
  4. ■ Hide 使 ColorPicker 不可见,并将 Button 的标签更改为 Show。

5. 选择“控制” > “测试影片”,运行应用程序。

使用 ActionScript 代码创建 Button:

1. 创建一个新的 Flash 文件 (ActionScript 3.0) 文档。

2. 将 Button 组件从“组件”面板拖到当前文档的“库”面板中。此操作将组件添加到库中,但不会在应用程序中显示它。

3. 打开“动作”面板,在主时间轴中选择第 1 帧,然后输入以下代码创建一个 Button 实例 :

复制代码

  1. import fl.controls.Button;
  2. var aButton:Button = new Button();
  3. addChild(aButton);
  4. aButton.label = “Click me”;
  5. aButton.toggle = true;
  6. aButton.move(50, 50);

move() 方法将按钮放在舞台的 50 (x 坐标) , 50 (y 坐标)位置。

4. 现在,添加以下 ActionScript 来创建一个事件侦听器和一个事件处理函数:

复制代码

  1. aButton.addEventListener(MouseEvent.CLICK, clickHandler);
  2. function clickHandler(event:MouseEvent):void {
  3. trace(“Event type: ” + event.type);
  4. }

5. 选择“控制” > “测试影片”。

单击按钮时, Flash 会在“输出”面板中显示消息“事件类型: 单击”。

 

创建 Greetings 应用程序

下列步骤使用 Flash 创作工具创建 FLA 文件、将组件放置在“舞台”上、向“时间轴”添加 ActionScript 代码,从而创建 Greetings 应用程序。

在 FLA 文件中创建 Greetings 应用程序:

1. 选择“文件” > “新建”。

2. 在“新建文档”对话框中,选择“Flash 文件 (ActionScript 3.0)”,然后单击“确定”。打开一个新的 Flash 窗口。

3. 选择“文件”>“保存”,将 Flash 文件命名为 Greetings.fla,然后单击“保存”按钮。

4. 在 Flash 组件面板中,选择一个 TextArea 组件,并将其拖到“舞台”上。

5. 在“属性”窗口中,选择“舞台”上的 TextArea 后,请键入 aTa 作为实例名,然后输入下列信息:

■ 输入 230 作为 W 值(宽)。

■ 输入 44 作为 H 值(高)。

■ 输入 165 作为 X 值(水平位置)。

■ 输入 57 作为 Y 值(垂直位置)。

■ 在“参数”选项卡上输入“Hello World!”作为文本参数。

6. 将 ColorPicker 组件拖到舞台上,放在 TextArea 的左侧,并为其指定实例名称“txtCp”。在“属性”检查器中输入下列信息:

■ 输入 96 作为 X 值。

■ 输入 72 作为 Y 值。

7. 将三个 RadioButton 组件拖到“舞台”上,分别为组件指定实例名称 smallRb、largerRb 和 largestRb。在“属性”检查器中为它们输入下列信息:

■ 为每个组件输入 100 作为 W 值,输入 22 作为 H 值。

■ 输入 155 作为 X 值。

■ 输入 120 作为 smallRb 的 Y 值,输入 148 作为 largerRb 的 Y 值,输入 175 作为largestRb 的 Y 值。

■ 输入 fontRbGrp 作为每个组件的 groupName 参数。

■ 在组件的“参数”选项卡输入 Small、Larger 和 Largest 作为标签。

8. 将一个 ComboBox 拖到“舞台”上,并为其指定实例名称 msgCb。在“属性”检查器中为其输入下列信息:

■ 输入 130 作为 W 值。

■ 输入 265 作为 X 值。

■ 输入 120 作为 Y 值。

■ 在“参数”选项卡上,输入“Greetings”作为提示参数。

■ 双击 dataProvider 参数的文本字段以打开“值”对话框。

■ 单击加号,然后用“Hello World!”替换标签值

■ 重复上一步骤,添加 Have a nice day! 和 Top of the Morning! 标签值

■ 单击“确定”以关闭“值”对话框。

9. 保存该文件。

10. 如果尚未打开,请通过按 F9 或从“窗口”菜单选择“动作”以打开“动作”面板。单击主时间轴的第 1 帧,然后在“动作”面板中输入下面的代码:

复制代码

import flash.events.Event;

import fl.events.ComponentEvent;

import fl.events.ColorPickerEvent;

import fl.controls.RadioButtonGroup;

var rbGrp:RadioButtonGroup = RadioButtonGroup.getGroup(“fontRbGrp”);

rbGrp.addEventListener(MouseEvent.CLICK, rbHandler);

txtCp.addEventListener(ColorPickerEvent.CHANGE,cpHandler);

msgCb.addEventListener(Event.CHANGE, cbHandler);

 

前三行导入应用程序使用的事件类。用户与组件之一进行交互时,会发生事件。接下来的五行为应用程序希望侦听的事件注册事件处理函数。用户单击 RadioButton 时发生 click 事件。用户在 ColorPicker 中选择其它颜色时发生 change 事件。用户从 ComboBox 的下拉列表选择其它问候时发生 change 事件。第四行导入 RadioButtonGroup 类以便应用程序可以为一组 RadioButton 分配事件侦听器,而不是分别为每个按钮分配侦听器。

11. 将下面一行代码添加到“动作”面板以创建 tf TextFormat 对象,应用程序使用此对象更改 TextArea 中文本的 size 和 color 样式属性。

复制代码

var tf:TextFormat = new TextFormat();

 

12. 添加下列代码以创建 rbHandler 事件处理函数。在用户单击其中一个 RadioButton 组件时,此函数处理 click 事件。

复制代码

function rbHandler(event:MouseEvent):void {

switch(event.target.selection.name) {

case “smallRb”:

tf.size = 14;

break;

case “largerRb”:

tf.size = 18;

break;

case “largestRb”:

tf.size = 24;

break;

}

aTa.setStyle(“textFormat”, tf);

}

 

此函数使用 switch 语句检查 event 对象的 target 属性,以确定哪个 RadioButton 触发了事件。currentTarget 属性包含触发事件的对象名称。根据用户单击的是哪个 RadioButton,应用程序将 TextArea 中文本的大小更改为 14、18 或 24 磅。

13. 添加下列代码以实现 cpHandler() 函数,此函数处理 ColorPicker 中的值的更改:

复制代码

function cpHandler(event:ColorPickerEvent):void {

tf.color = event.target.selectedColor;

aTa.setStyle(“textFormat”, tf);

}

 

此函数将 tf TextFormat 对象的 color 属性设置为 ColorPicker 中选定的颜色,然后调用 setStyle() 将此颜色应用到 aTa TextArea 实例中的文本。

14. 添加下列代码以实现 cbHandler() 函数,此函数处理 ComboBox 中选择的更改:

复制代码

function cbHandler(event:Event):void {

aTa.text = event.target.selectedItem.label;

}

 

此函数只是将 TextArea 中的文本替换为 ComboBox 中选择的文本(event.target.selectedItem.label)。

15. 选择“控制”>“测试影片”或按 Ctrl+Enter 编译代码,然后测试 Greetings 应用程序。

第一帧的全部代码:

复制代码

import flash.events.Event;

import fl.events.ComponentEvent;

import fl.events.ColorPickerEvent;

import fl.controls.RadioButtonGroup;

var rbGrp:RadioButtonGroup=RadioButtonGroup.getGroup(“fontRbGrp”);

rbGrp.addEventListener(MouseEvent.CLICK, rbHandler);

txtCp.addEventListener(ColorPickerEvent.CHANGE,cpHandler);

msgCb.addEventListener(Event.CHANGE, cbHandler);

var tf:TextFormat = new TextFormat();

function rbHandler(event:MouseEvent):void {

switch (event.target.selection.name) {

case “smallRb” :

tf.size=14;

break;

case “largerRb” :

tf.size=18;

break;

case “largestRb” :

tf.size=24;

break;

}

aTa.setStyle(“textFormat”, tf);

}

function cpHandler(event:ColorPickerEvent):void {

tf.color=event.target.selectedColor;

aTa.setStyle(“textFormat”, tf);

}

function cbHandler(event:Event):void {

aTa.text=event.target.selectedItem.label;

}

 

下面的部分向您演示如何使用外部的 ActionScript 类,以及其“库”中只有必需组件的 FLA文件构建相同的应用程序。

 

 

使用外部类文件创建 Greetings2 应用程序:

1. 选择“文件” > “新建”。

2. 在“新建文档”对话框中,选择“Flash 文件 (ActionScript 3.0)”,然后单击“确定”。打开一个新的 Flash 窗口。

3. 选择“文件” > “保存”,将 Flash 文件命名为“Greetings2.fla”,然后单击“保存”按钮。

4. 将下列各个组件从“组件”面板拖到“库”中:

■ ColorPicker

■ ComboBox

■ RadioButton

■ TextArea

因为编译的 SWF 文件会使用所有资源,所以您需要将资源都添加到“库”中。将组件拖到“库”面板的底部。在您将这些组件添加到“库”中时,会自动添加其它资源(List、

TextInput 和 UIScrollBox)。

5. 在“属性”窗口中,为“文档类”键入 Greetings2。

如果 Flash 显示一个“无法找到该文档类的定义”的警告,请忽略。您将按下面步骤定义 Greetings2 类。此类定义应用程序的主要功能。

6. 保存 Greetings2.fla 文件。

7. 选择“文件” > “新建”。

8. 在“新建文档”对话框中,选择“ActionScript 文件”,然后单击“确定”。打开一个新的脚本窗口。

9. 在脚本窗口中添加下列代码:

package {

import flash.display.Sprite;

import flash.events.Event;

import flash.events.MouseEvent;

import flash.text.TextFormat;

import fl.events.ComponentEvent;

import fl.events.ColorPickerEvent;

import fl.controls.ColorPicker;

import fl.controls.ComboBox;

import fl.controls.RadioButtonGroup;

import fl.controls.RadioButton;

import fl.controls.TextArea;

public class Greetings2 extends Sprite {

private var aTa:TextArea;

private var msgCb:ComboBox;

private var smallRb:RadioButton;

private var largerRb:RadioButton;

private var largestRb:RadioButton;

private var rbGrp:RadioButtonGroup;

private var txtCp:ColorPicker;

private var tf:TextFormat = new TextFormat();

public function Greetings2() {

脚本定义一个名为 Greetings2 的 ActionScript 3.0 类。脚本进行以下操作:

■ 导入我们将要在文件中使用的类。通常情况下,您可以在代码中引用其它类时添加这些导入语句,但为了简便起见,此示例将所有这些语句在一个步骤中导入。

■ 声明变量以表示我们将要添加到代码中的组件对象的不同类型。另一个变量创建 tfTextFormat 对象。

■ 为类定义构造函数 Greetings2()。我们将这些行添加到此函数中,并按下列步骤向类添加其它方法。

10. 选择“文件” > “保存”,将文件命名为“Greetings2.as”,然后单击“保存”按钮。

11. 向 Greeting2() 函数添加下列代码行:

createUI();

setUpHandlers();

}

此函数现在应该如下所示:

public function Greetings2() {

createUI();

setUpHandlers();

}

12. 在 Greeting2() 方法的右括号后添加下列代码行:

private function createUI() {

bldTxtArea();

bldColorPicker();

bldComboBox();

bldRadioButtons();

}

private function bldTxtArea() {

aTa = new TextArea();

aTa.setSize(230, 44);

aTa.text = “Hello World!”;

aTa.move(165, 57);

addChild(aTa);

}

private function bldColorPicker() {

txtCp = new ColorPicker();

txtCp.move(96, 72);

addChild(txtCp);

}

private function bldComboBox() {

msgCb = new ComboBox();

msgCb.width = 130;

msgCb.move(265, 120);

msgCb.prompt = “Greetings”;

msgCb.addItem({data:”Hello.”, label:”English”});

msgCb.addItem({data:”Bonjour.”, label:”Français”});

msgCb.addItem({data:”¡Hola!”, label:”Español”});

addChild(msgCb);

}

private function bldRadioButtons() {

rbGrp = new RadioButtonGroup(“fontRbGrp”);

smallRb = new RadioButton();

smallRb.setSize(100, 22);

smallRb.move(155, 120);

smallRb.group = rbGrp; //”fontRbGrp”;

smallRb.label = “Small”;

smallRb.name = “smallRb”;

addChild(smallRb);

largerRb = new RadioButton();

largerRb.setSize(100, 22);

largerRb.move(155, 148);

largerRb.group = rbGrp;

largerRb.label = “Larger”;

largerRb.name = “largerRb”;

addChild(largerRb);

largestRb = new RadioButton();

largestRb.setSize(100, 22);

largestRb.move(155, 175);

largestRb.group = rbGrp;

largestRb.label = “Largest”;

largestRb.name = “largestRb”;

addChild(largestRb);

}

这些行执行下列操作:

■ 实例化应用程序中使用的组件。

■ 设置每个组件的大小、位置和属性。

■ 使用 addChild() 方法将各个组件添加到舞台上。

13. 在 bldRadioButtons() 方法的右括号后,添加 setUpHandlers() 方法的下列代码:

private function setUpHandlers():void {

rbGrp.addEventListener(MouseEvent.CLICK, rbHandler);

txtCp.addEventListener(ColorPickerEvent.CHANGE,cpHandler);

msgCb.addEventListener(Event.CHANGE, cbHandler);

}

private function rbHandler(event:MouseEvent):void {

switch(event.target.selection.name) {

case “smallRb”:

tf.size = 14;

break;

case “largerRb”:

tf.size = 18;

break;

case “largestRb”:

tf.size = 24;

break;

}

aTa.setStyle(“textFormat”, tf);

}

private function cpHandler(event:ColorPickerEvent):void {

tf.color = event.target.selectedColor;

aTa.setStyle(“textFormat”, tf);

}

private function cbHandler(event:Event):void {

aTa.text = event.target.selectedItem.data;

}

}

}

这些函数定义组件的事件侦听器。

14. 选择“文件” > “保存”以保存文件。

15. 选择“控制”>“测试影片”或按 Ctrl+Enter 编译代码,然后测试 Greetings2 应用程序。

 

 

创建 Greetings 应用程序

下列步骤使用 Flash 创作工具创建 FLA 文件、将组件放置在“舞台”上、向“时间轴”添加 ActionScript 代码,从而创建 Greetings 应用程序。

在 FLA 文件中创建 Greetings 应用程序:
1. 选择“文件” > “新建”。
2. 在“新建文档”对话框中,选择“Flash 文件 (ActionScript 3.0)”,然后单击“确定”。打开一个新的 Flash 窗口。
3. 选择“文件”>“保存”,将 Flash 文件命名为 Greetings.fla,然后单击“保存”按钮。
4. 在 Flash 组件面板中,选择一个 TextArea 组件,并将其拖到“舞台”上。
5. 在“属性”窗口中,选择“舞台”上的 TextArea 后,请键入 aTa 作为实例名,然后输入下列信息:

■ 输入 230 作为 W 值(宽)。
■ 输入 44 作为 H 值(高)。
■ 输入 165 作为 X 值(水平位置)。
■ 输入 57 作为 Y 值(垂直位置)。
■ 在“参数”选项卡上输入“Hello World!”作为文本参数。

6. 将 ColorPicker 组件拖到舞台上,放在 TextArea 的左侧,并为其指定实例名称“txtCp”。在“属性”检查器中输入下列信息:

■ 输入 96 作为 X 值。
■ 输入 72 作为 Y 值。

7. 将三个 RadioButton 组件拖到“舞台”上,分别为组件指定实例名称 smallRb、largerRb 和 largestRb。在“属性”检查器中为它们输入下列信息:

■ 为每个组件输入 100 作为 W 值,输入 22 作为 H 值。
■ 输入 155 作为 X 值。
■ 输入 120 作为 smallRb 的 Y 值,输入 148 作为 largerRb 的 Y 值,输入 175 作为largestRb 的 Y 值。
■ 输入 fontRbGrp 作为每个组件的 groupName 参数。
■ 在组件的“参数”选项卡输入 Small、Larger 和 Largest 作为标签。

8. 将一个 ComboBox 拖到“舞台”上,并为其指定实例名称 msgCb。在“属性”检查器中为其输入下列信息:

■ 输入 130 作为 W 值。
■ 输入 265 作为 X 值。
■ 输入 120 作为 Y 值。
■ 在“参数”选项卡上,输入“Greetings”作为提示参数。
■ 双击 dataProvider 参数的文本字段以打开“值”对话框。
■ 单击加号,然后用“Hello World!”替换标签值
■ 重复上一步骤,添加 Have a nice day! 和 Top of the Morning! 标签值
■ 单击“确定”以关闭“值”对话框。

9. 保存该文件。
10. 如果尚未打开,请通过按 F9 或从“窗口”菜单选择“动作”以打开“动作”面板。单击主时间轴的第 1 帧,然后在“动作”面板中输入下面的代码:

复制代码

  1. import flash.events.Event;
  2. import fl.events.ComponentEvent;
  3. import fl.events.ColorPickerEvent;
  4. import fl.controls.RadioButtonGroup;
  5. var rbGrp:RadioButtonGroup = RadioButtonGroup.getGroup(“fontRbGrp”);
  6. rbGrp.addEventListener(MouseEvent.CLICK, rbHandler);
  7. txtCp.addEventListener(ColorPickerEvent.CHANGE,cpHandler);
  8. msgCb.addEventListener(Event.CHANGE, cbHandler);

前三行导入应用程序使用的事件类。用户与组件之一进行交互时,会发生事件。接下来的五行为应用程序希望侦听的事件注册事件处理函数。用户单击 RadioButton 时发生 click 事件。用户在 ColorPicker 中选择其它颜色时发生 change 事件。用户从 ComboBox 的下拉列表选择其它问候时发生 change 事件。第四行导入 RadioButtonGroup 类以便应用程序可以为一组 RadioButton 分配事件侦听器,而不是分别为每个按钮分配侦听器。

11. 将下面一行代码添加到“动作”面板以创建 tf TextFormat 对象,应用程序使用此对象更改 TextArea 中文本的 size 和 color 样式属性。

复制代码

  1. var tf:TextFormat = new TextFormat();

12. 添加下列代码以创建 rbHandler 事件处理函数。在用户单击其中一个 RadioButton 组件时,此函数处理 click 事件。

复制代码

  1. function rbHandler(event:MouseEvent):void {
  2. switch(event.target.selection.name) {
  3. case “smallRb”:
  4. tf.size = 14;
  5. break;
  6. case “largerRb”:
  7. tf.size = 18;
  8. break;
  9. case “largestRb”:
  10. tf.size = 24;
  11. break;
  12. }
  13. aTa.setStyle(“textFormat”, tf);
  14. }

此函数使用 switch 语句检查 event 对象的 target 属性,以确定哪个 RadioButton 触发了事件。currentTarget 属性包含触发事件的对象名称。根据用户单击的是哪个 RadioButton,应用程序将 TextArea 中文本的大小更改为 14、18 或 24 磅。
13. 添加下列代码以实现 cpHandler() 函数,此函数处理 ColorPicker 中的值的更改:

复制代码

  1. function cpHandler(event:ColorPickerEvent):void {
  2. tf.color = event.target.selectedColor;
  3. aTa.setStyle(“textFormat”, tf);
  4. }

此函数将 tf TextFormat 对象的 color 属性设置为 ColorPicker 中选定的颜色,然后调用 setStyle() 将此颜色应用到 aTa TextArea 实例中的文本。
14. 添加下列代码以实现 cbHandler() 函数,此函数处理 ComboBox 中选择的更改:

复制代码

  1. function cbHandler(event:Event):void {
  2. aTa.text = event.target.selectedItem.label;
  3. }

此函数只是将 TextArea 中的文本替换为 ComboBox 中选择的文本(event.target.selectedItem.label)。
15. 选择“控制”>“测试影片”或按 Ctrl+Enter 编译代码,然后测试 Greetings 应用程序。

第一帧的全部代码:

复制代码

  1. import flash.events.Event;
  2. import fl.events.ComponentEvent;
  3. import fl.events.ColorPickerEvent;
  4. import fl.controls.RadioButtonGroup;
  5. var rbGrp:RadioButtonGroup=RadioButtonGroup.getGroup(“fontRbGrp”);
  6. rbGrp.addEventListener(MouseEvent.CLICK, rbHandler);
  7. txtCp.addEventListener(ColorPickerEvent.CHANGE,cpHandler);
  8. msgCb.addEventListener(Event.CHANGE, cbHandler);
  9. var tf:TextFormat = new TextFormat();
  10. function rbHandler(event:MouseEvent):void {
  11.     switch (event.target.selection.name) {
  12.         case “smallRb” :
  13.             tf.size=14;
  14.             break;
  15.         case “largerRb” :
  16.             tf.size=18;
  17.             break;
  18.         case “largestRb” :
  19.             tf.size=24;
  20.             break;
  21.     }
  22.     aTa.setStyle(“textFormat”, tf);
  23. }
  24. function cpHandler(event:ColorPickerEvent):void {
  25.     tf.color=event.target.selectedColor;
  26.     aTa.setStyle(“textFormat”, tf);
  27. }
  28. function cbHandler(event:Event):void {
  29.     aTa.text=event.target.selectedItem.label;
  30. }
 
 
分类
Flash professional

Adding Game Effects

 Adding Game Effects

Let’s spruce up this simple matching game with some special effects. Although they won’t change the basic game play, they will make the game seem a lot more interesting to players.

Animated Card Flips

Because this animation affects the cards, and only the cards, it makes sense to put it inside the Card class.

However, we don’t have a Card class. Now it is time to create Card class.

This class will enable an animated flip of the card, rather than just changing the card instantly. It will replace all the gotoAndStop functions in the main class. Instead, it will
tell the card to fanPai. It also passes in the frame which the card should show when the flip is over. The Card class will then set up some variables, set up an event listener,
and proceed to animate the card over the next ten frames:

Card1.as

复制代码

  1. package {
  2.     import flash.display.*;
  3.     import flash.events.*;
  4.     public dynamic class Card1 extends MovieClip {
  5.         private var buS:uint;
  6.         private var fan:Boolean=false;
  7.         private var zhenS:uint;
  8.         // begin the flip, remember which frame to jump to
  9.         public function fanPai(frame:uint) {
  10.             fan=true;
  11.             buS=10;
  12.             zhenS=frame;
  13.             this.addEventListener(Event.ENTER_FRAME, bianPai);
  14.         }
  15.         // take 10 steps to flip
  16.         public function bianPai(event:Event) {
  17.             buS–;// next step
  18.             if (buS>5) {// first half of flip
  19.                 this.scaleX = .2*(buS-6);
  20.             } else {// second half of flip
  21.                 this.scaleX = .2*(5-buS);
  22.             }
  23.             // when it is the middle of the flip, go to new frame
  24.             if (buS==5) {
  25.                 this.gotoAndStop(zhenS);
  26.             }
  27.             // at the end of the flip, stop the animation
  28.             if (buS==0) {
  29.                 this.removeEventListener(Event.ENTER_FRAME, bianPai);
  30.             }
  31.         }
  32.     }
  33. }

 

 Limited Card-Viewing Time

Another nice touch to this game is to automatically turn over pairs of mismatched cards after the player has had enough time to look at them. For instance, the player chooses two cards. They don’t match, so they remain face up for the player to inspect. After two seconds, however, the cards turn over, even if the player hasn’t begun to select another pair.

To accomplish this, we’ll use a Timer. To start, we’ll need to import the Timer class into our main class:

复制代码

  1. import flash.utils.Timer;

Next, we create a timer variable at the start of the class:

复制代码

  1. private var puPaiT:Timer;

Later on in the fanPai function, we add some code right after the player has chosen the second card, not made a match, and his or her score has been decreased. This Timer code will set up the new timer, which will simply call a function when two seconds have gone by:

复制代码

  1. puPaiT = new Timer(2000,1);
  2. puPaiT.addEventListener(TimerEvent.TIMER_COMPLETE,puPai);
  3. puPaiT.start();

The TimerEvent.TIMER_COMPLETE event is triggered when a timer is done. Typically, a Timer runs a certain number of times, triggering a TimerEvent.TIMER each time. Then,
on the last event, it also triggers the TimerEvent.TIMER_COMPLETE. Because we only want to trigger a single event at some point in the future, we just set the number of  imer
events to one, and then look for TimerEvent.TIMER_COMPLETE.

When two seconds go by, the  puPai function is called. This is a new function that works just like the later part of the old clickCard function. It flips both the first and second selections back to the face-down state, and then sets the firstCard and secondCard values to null. It also removed the listener:

复制代码

  1. public function puPai(e:TimerEvent) {
  2. fpai1.fanPai(1);
  3. pai2.fanPai(1);
  4. pai1=null;
  5. pai2=null;
  6. puPaiT.removeEventListener(TimerEvent.TIMER_COMPLETE,puPai);
  7. }
复制代码

  1. package {
  2.     import flash.display.*;
  3.     import flash.events.*;
  4.     import flash.text.*;
  5.     import flash.utils.getTimer;
  6.     import flash.utils.Timer;
  7.     public class Mygame1 extends MovieClip {
  8.         private static const paiKuan:Number=84+2;
  9.         private static const paiGao:Number=125+2;
  10.         private static const jiafen:int=100;
  11.         private static const jianfen:int=-5;
  12.         private var paiX:uint=Math.floor((stage.stageWidth-340)/paiKuan);
  13.         private var paiY:uint=Math.floor((stage.stageHeight-260)/paiGao);
  14.         private var bianX:Number=(stage.stageWidth-(paiX-1)*paiKuan)/2-1;
  15.         private var bianY:Number=(stage.stageHeight-(paiY-1)*paiGao)/2-1;
  16.         private var pai1:Card1;
  17.         private var pai2:Card1;
  18.         private var cardsLeft:uint=0;
  19.         private var paiShu:uint=10;
  20.         private var fenshu:TextField;
  21.         private var defen:int;
  22.         private var geshi:TextFormat;
  23.         private var jishi:TextField;
  24.         private var kaishiT:uint;
  25.         private var youxiT:uint;
  26.         private var puPaiT:Timer;
  27.         public function Mygame1():void {
  28.             var pai:Card1=new Card1();
  29.             paiShu=pai.totalFrames;
  30.             var myCards:Array=new Array();
  31.             for (var j:uint=2; j<paiShu+2; j++) {
  32.                 myCards.push(j);
  33.             }
  34.             var cardlist:Array=new Array();
  35.             /*if (paiX*paiY/2!=0) {
  36.             paiY–;
  37.             bianY+=paiGao/2;
  38.             }*/
  39.             for (var i:uint=0; i<paiX*paiY/2; i++) {
  40.                 var r0:uint=Math.floor(Math.random()*myCards.length);
  41.                 cardlist.push(myCards[r0]);
  42.                 cardlist.push(myCards[r0]);
  43.                 myCards.splice(r0,1);
  44.             }
  45.             //trace(cardlist);
  46.             for (var x:uint=0; x<paiX; x++) {
  47.                 for (var y:uint=0; y<paiY; y++) {
  48.                     var c:Card1 = new Card1();
  49.                     c.stop();
  50.                     c.buttonMode=true;
  51.                     c.height=paiGao-2;
  52.                     c.width=paiKuan-2;
  53.                     c.x=x*paiKuan+bianX;
  54.                     c.y=y*paiGao+bianY;
  55.                     var r:uint=Math.floor(Math.random()*cardlist.length);
  56.                     c.cardface=cardlist[r];
  57.                     cardlist.splice(r,1);
  58.                     //c.gotoAndStop(c.cardface);
  59.                     addChild(c);
  60.                     cardsLeft++;
  61.                     c.addEventListener(MouseEvent.CLICK,fanPai);
  62.                 }
  63.             }
  64.             //trace(myCards);
  65.             defen=0;
  66.             fenshu = new TextField();
  67.             fenshu.width=200;
  68.             addChild(fenshu);
  69.             xiandefen();
  70.             jishi = new TextField();
  71.             jishi.x=stage.stageWidth-200;
  72.             jishi.width=200;
  73.             addChild(jishi);
  74.             kaishiT=getTimer();
  75.             youxiT=0;
  76.             addEventListener(Event.ENTER_FRAME,xianT);
  77.         }
  78.         public function fanPai(evt:MouseEvent) {
  79.             var paiN:Card1=(evt.target as Card1);
  80.             if (pai1==null) {
  81.                 pai1=paiN;
  82.                 paiN.fanPai(paiN.cardface);
  83.             } else if (pai2==null) {
  84.                 if (paiN==pai1) {
  85.                     pai1.fanPai(1);
  86.                     pai1=null;
  87.                 } else {
  88.                     pai2=paiN;
  89.                     paiN.fanPai(paiN.cardface);
  90.                     if (pai1.cardface==pai2.cardface) {
  91.                         removeChild(pai1);
  92.                         removeChild(pai2);
  93.                         pai1=null;
  94.                         pai2=null;
  95.                         defen+=jiafen;
  96.                         xiandefen();
  97.                         cardsLeft-=2;
  98.                         if (cardsLeft<2) {
  99.                             MovieClip(root).fenShu=defen;
  100.                             MovieClip(root).shiJian=fenmiaoT(youxiT);
  101.                             MovieClip(root).gotoAndStop(“gameover”);
  102.                         }
  103.                     } else {
  104.                         defen+=jianfen;
  105.                         xiandefen();
  106.                         puPaiT=new Timer(2000,1);
  107.                         puPaiT.addEventListener(TimerEvent.TIMER_COMPLETE,puPai);
  108.                         puPaiT.start();
  109.                     }
  110.                 }
  111.             } else {
  112.                 puPai(null);
  113.                 pai1=paiN;
  114.                 pai2=null;
  115.                 paiN.fanPai(paiN.cardface);
  116.             }
  117.         }
  118.         public function xiandefen() {
  119.             fenshu.text=”你的得分: “+String(defen);
  120.             geshi= new TextFormat( );
  121.             geshi.color=0xff0000;
  122.             geshi.bold=true;
  123.             geshi.size=24;
  124.             fenshu.setTextFormat(geshi);
  125.         }
  126.         public function xianT(evt:Event) {
  127.             youxiT=getTimer()-kaishiT;
  128.             jishi.text=”使用时间:”+fenmiaoT(youxiT);
  129.             geshi= new TextFormat( );
  130.             geshi.color=0xff0000;
  131.             geshi.bold=true;
  132.             geshi.size=24;
  133.             jishi.setTextFormat(geshi);
  134.         }
  135.         public function fenmiaoT(fm:int) {
  136.             var miao:int=Math.floor(fm/1000);
  137.             var fen:int=Math.floor(miao/60);
  138.             miao-=fen*60;
  139.             //var fenmiaoZ:String=fen+”:”+miao;
  140.             var fenmiaoZ:String=fen+”:”+String(miao+100).substr(1,2);
  141.             return fenmiaoZ;
  142.         }
  143.         public function puPai(e:TimerEvent) {
  144.             pai1.fanPai(1);
  145.             pai2.fanPai(1);
  146.             pai1=null;
  147.             pai2=null;
  148.             puPaiT.removeEventListener(TimerEvent.TIMER_COMPLETE,puPai);
  149.         }
  150.     }
  151. }

Sound Effects

ActionScript 3.0 makes adding sound relatively easy, although there are quite a few steps involved.

The first step is to import your sounds. I’ve created three sounds and want to bring them each into the library:

复制代码

  1. Dan.aiff
  2. Cuo.aiff
  3. Dui.aiff

After we have imported them, they need to have properties changed. Name them all after their filenames, but minus the .aiff. Also, check the Export for ActionScript option
and give them the same class name as symbol name.

Next, we set up the main game class to play the sounds at the right time. First, we need to import two new classes so that we can use sound:

复制代码

  1. import flash.media.Sound;
  2. import flash.media.SoundChannel;

Then, we create class variables to hold references to these sounds:

复制代码

  1. var yinDan:Dan = new Dan();
  2. var yinCuo:Cuo = new Cuo();
  3. var yinDui:Dui = new Dui();

I like to pass all sound playback through a single function. Let’s call it playSound and add it to the end of the class:

复制代码

  1. public function playSound(snd:Object) {
  2. var shengDao1:SoundChannel = snd.play();
  3. }

Now, when we want a sound to play, we just call playSound with the sound variable we want to use, as follows:

复制代码

  1. playSound(yinDui);
package {
    import flash.display.*;
    import flash.events.*;
    import flash.text.*;
    import flash.utils.getTimer;
    import flash.utils.Timer;
    import flash.media.Sound;
    import flash.media.SoundChannel;

    public class Mygame1 extends MovieClip {
        private static const paiKuan:Number=84+2;
        private static const paiGao:Number=125+2;
        private static const jiafen:int=100;
        private static const jianfen:int=-5;

        private var paiX:uint=Math.floor((stage.stageWidth-340)/paiKuan);
        private var paiY:uint=Math.floor((stage.stageHeight-260)/paiGao);
        private var bianX:Number=(stage.stageWidth-(paiX-1)*paiKuan)/2-1;
        private var bianY:Number=(stage.stageHeight-(paiY-1)*paiGao)/2-1;
        private var pai1:Card1;
        private var pai2:Card1;
        private var cardsLeft:uint=0;
        private var paiShu:uint=10;
        private var fenshu:TextField;
        private var defen:int;
        private var geshi:TextFormat;
        private var jishi:TextField;
        private var kaishiT:uint;
        private var youxiT:uint;
        private var puPaiT:Timer;
        var yinDan:Dan = new Dan();
        var yinCuo:Cuo = new Cuo();
        var yinDui:Dui = new Dui();

        public function Mygame1():void {
            var pai:Card1=new Card1();
            paiShu=pai.totalFrames;
            var myCards:Array=new Array();
            for (var j:uint=2; j<paiShu+2; j++) {
                myCards.push(j);
            }
            var cardlist:Array=new Array();
            /*if (paiX*paiY/2!=0) {
            paiY–;
            bianY+=paiGao/2;
            }*/
            for (var i:uint=0; i<paiX*paiY/2; i++) {
                var r0:uint=Math.floor(Math.random()*myCards.length);
                cardlist.push(myCards[r0]);
                cardlist.push(myCards[r0]);
                myCards.splice(r0,1);
            }
            //trace(cardlist);
            for (var x:uint=0; x<paiX; x++) {
                for (var y:uint=0; y<paiY; y++) {
                    var c:Card1 = new Card1();
                    c.stop();
                    c.buttonMode=true;
                    c.height=paiGao-2;
                    c.width=paiKuan-2;
                    c.x=x*paiKuan+bianX;
                    c.y=y*paiGao+bianY;
                    var r:uint=Math.floor(Math.random()*cardlist.length);
                    c.cardface=cardlist[r];
                    cardlist.splice(r,1);
                    //c.gotoAndStop(c.cardface);
                    addChild(c);
                    cardsLeft++;
                    c.addEventListener(MouseEvent.CLICK,fanPai);
                }
            }
            //trace(myCards);
            defen=0;
            fenshu = new TextField();
            fenshu.width=200;
            addChild(fenshu);
            xiandefen();
            jishi = new TextField();
            jishi.x=stage.stageWidth-200;
            jishi.width=200;
            addChild(jishi);

            kaishiT=getTimer();
            youxiT=0;
            addEventListener(Event.ENTER_FRAME,xianT);
        }
        public function fanPai(evt:MouseEvent) {
            var paiN:Card1=(evt.target as Card1);
            if (pai1==null) {
                pai1=paiN;
                playSound(yinDan);
                paiN.fanPai(paiN.cardface);
            } else if (pai2==null) {
                if (paiN==pai1) {
                    pai1.fanPai(1);
                    pai1=null;
                } else {
                    pai2=paiN;
                    paiN.fanPai(paiN.cardface);
                    if (pai1.cardface==pai2.cardface) {
                        playSound(yinDui);
                        removeChild(pai1);
                        removeChild(pai2);
                        pai1=null;
                        pai2=null;
                        defen+=jiafen;
                        xiandefen();
                        cardsLeft-=2;
                        if (cardsLeft<2) {
                            MovieClip(root).fenShu=defen;
                            MovieClip(root).shiJian=fenmiaoT(youxiT);
                            MovieClip(root).gotoAndStop(“gameover”);
                        }
                    } else {
                        playSound(yinCuo);
                        defen+=jianfen;
                        xiandefen();
                        puPaiT=new Timer(2000,1);
                        puPaiT.addEventListener(TimerEvent.TIMER_COMPLETE,puPai);
                        puPaiT.start();
                    }
                }
            } else {
                playSound(yinDan);
                puPai(null);
                pai1=paiN;
                pai2=null;
                paiN.fanPai(paiN.cardface);

            }
        }
        public function xiandefen() {
            fenshu.text=”你的得分: “+String(defen);
            geshi= new TextFormat( );
            geshi.color=0xff0000;
            geshi.bold=true;
            geshi.size=24;
            fenshu.setTextFormat(geshi);
        }
        public function xianT(evt:Event) {
            youxiT=getTimer()-kaishiT;
            jishi.text=”使用时间:”+fenmiaoT(youxiT);
            geshi= new TextFormat( );
            geshi.color=0xff0000;
            geshi.bold=true;
            geshi.size=24;
            jishi.setTextFormat(geshi);
        }
        public function fenmiaoT(fm:int) {
            var miao:int=Math.floor(fm/1000);
            var fen:int=Math.floor(miao/60);
            miao-=fen*60;
            //var fenmiaoZ:String=fen+”:”+miao;
            var fenmiaoZ:String=fen+”:”+String(miao+100).substr(1,2);
            return fenmiaoZ;
        }
        public function puPai(e:TimerEvent) {
            pai1.fanPai(1);
            pai2.fanPai(1);
            pai1=null;
            pai2=null;
            puPaiT.removeEventListener(TimerEvent.TIMER_COMPLETE,puPai);
        }
        public function playSound(snd:Object) {
            var shengDao1:SoundChannel=snd.play();
        }
    }
}

MyGame.swf (1675 K) 下载次数:6 [试播]

分类
Flash professional

游戏的封装

 游戏的封装

.fla:

create a new class variable named cardsLeft:

复制代码

  1. private var cardsLeft:uint;

Then, set it to zero just before the for loops that create the cards. And, add one to this variable for every card created:

复制代码

  1. cardsLeft = 0;
  2. for…
  3. addChild(c);
  4. cardsLeft++;
  5. }
  6. }

Then, in the clickCard function, we need to add new code when the user makes a match and the cards are removed from the screen: This goes in the clickCard function.

复制代码

  1. cardsLeft -= 2;
  2. if (cardsLeft == 0) {
  3. gotoAndStop(“gameover”);
  4. }

第一帧:(startgame)
stop();
game0Button.addEventListener(MouseEvent.CLICK,playgame1);
function playgame0(event:MouseEvent) {
    gotoAndStop(“game0”);
}

第二帧:(game0)

左上角放置 Mygame0 的实例。

第三帧:(gameover)
playAgainButton.addEventListener(MouseEvent.CLICK,playAgain);
function playAgain(event:MouseEvent) {
    gotoAndStop(“startgame”);
}

复制代码

  1. package {
  2.     import flash.display.*;
  3.     import flash.events.*;
  4.     public class Mygame0 extends MovieClip {
  5.         private static const paiKuan:Number=100+2;
  6.         private static const paiGao:Number=150+2;
  7.         private var paiX:Number=Math.floor((stage.stageWidth-200)/paiKuan);
  8.         private var paiY:uint=Math.floor((stage.stageHeight-160)/paiGao);
  9.         private var bianX:Number=(stage.stageWidth-paiX*paiKuan)/2;
  10.         private var bianY:Number=(stage.stageHeight-paiY*paiGao)/2;
  11.         private var pai1:Card;
  12.         private var pai2:Card;
  13.         private var cardsLeft:uint=0;
  14.         private var paiShu:uint=10;
  15.         public function Mygame0():void {
  16.             var pai:Card=new Card();
  17.             paiShu=pai.totalFrames;
  18.             var myCards:Array=new Array();
  19.             for (var j:uint=2; j<paiShu+2; j++) {
  20.                 myCards.push(j);
  21.             }
  22.             var cardlist:Array=new Array();
  23.             /*if (paiX*paiY/2!=0) {
  24.             paiY–;
  25.             bianY+=paiGao/2;
  26.             }*/
  27.             for (var i:uint=0; i<paiX*paiY/2; i++) {
  28.                 var r0:uint=Math.floor(Math.random()*myCards.length);
  29.                 cardlist.push(myCards[r0]);
  30.                 cardlist.push(myCards[r0]);
  31.                 myCards.splice(r0,1);
  32.             }
  33.             //trace(cardlist);
  34.             for (var x:uint=0; x<paiX; x++) {
  35.                 for (var y:uint=0; y<paiY; y++) {
  36.                     var c:Card = new Card();
  37.                     c.stop();
  38.                     c.height=paiGao-2;
  39.                     c.width=paiKuan-2;
  40.                     c.x=x*paiKuan+bianX;
  41.                     c.y=y*paiGao+bianY;
  42.                     var r:uint=Math.floor(Math.random()*cardlist.length);
  43.                     c.cardface=cardlist[r];
  44.                     cardlist.splice(r,1);
  45.                     //c.gotoAndStop(c.cardface);
  46.                     addChild(c);
  47.                     cardsLeft++;
  48.                     c.addEventListener(MouseEvent.CLICK,fanPai);
  49.                 }
  50.             }
  51.             //trace(myCards);
  52.         }
  53.         public function fanPai(evt:MouseEvent) {
  54.             var paiN:Card=(evt.target as Card);
  55.             if (pai1==null) {
  56.                 pai1=paiN;
  57.                 paiN.gotoAndStop(paiN.cardface);
  58.             } else if (pai2==null) {
  59.                 if (paiN==pai1) {
  60.                     pai1.gotoAndStop(1);
  61.                     pai1=null;
  62.                 } else {
  63.                     pai2=paiN;
  64.                     paiN.gotoAndStop(paiN.cardface);
  65.                     if (pai1.cardface==pai2.cardface) {
  66.                         removeChild(pai1);
  67.                         removeChild(pai2);
  68.                         pai1=null;
  69.                         pai2=null;
  70.                         cardsLeft-=2;
  71.                         if (cardsLeft<2) {
  72.                             MovieClip(root).gotoAndStop(“gameover”);
  73.                         }
  74.                     }
  75.                 }
  76.             } else {
  77.                 pai1.gotoAndStop(1);
  78.                 pai2.gotoAndStop(1);
  79.                 pai1=paiN;
  80.                 pai2=null;
  81.                 paiN.gotoAndStop(paiN.cardface);
  82.             }
  83.         }
  84.     }
  85. }

Adding Scoring and a Clock

Two elements commonly seen in casual games are scoring and timers. Even though the matching game concept doesn’t really need them, let’s go ahead and add them to the game anyway to make it as full-featured as we can.

Adding Scoring

To do this, we need  a special Flash class that we need to import at the start of our program:

复制代码

  1. import flash.text.*;
复制代码

  1. private static const jiafen:int = 100;
  2. private static const jianfen:int = -5;

To display the score, we need a text field.

复制代码

  1. private var fenshu:TextField;

Then, we need to create that text field and add it as a child:

复制代码

  1. fenshu = new TextField();
  2. addChild(fenshu);

The score itself will be a simple integer variable named gameScore. We’ll declare it at the start of the class:

复制代码

  1. private var defen:int;

And then we’ll set it to zero in the constructor function:

复制代码

  1. defen = 0;

In addition, it would be a good idea to immediately show the score in the text field:

fenshu.text =”你的得分: “+String(defen);

However, we realize at this point that there are at least several places in the code where we will set the text of gameScoreField. The first is in the constructor function. The second will be after the score changes during game play. Instead of copying and pasting the previous line of code in two places, let’s move it to a function of its own. Then, we can call the same function from each of the places in the code where we need to update the score:

复制代码

  1. public function xiandefen() {
  2. fenshu.text =”你的得分: “+String(defen);
  3. }

We need to change the score in two places in the code. The first is right after we find a match, just before we check to see whether the game is over:

复制代码

  1. defen += jiafen;

Then, we add an else clause to the if statement that checks for a match, and subtract points if the match is not found:

复制代码

  1. defen += jianfen;

We also put in the xiandefen() function call after each change to the score.

复制代码

  1. package {
  2.     import flash.display.*;
  3.     import flash.events.*;
  4.     import flash.text.*;
  5.     public class Mygame1 extends MovieClip {
  6.         private static const paiShu:uint=77;
  7.         private static const paiKuan:Number=100+2;
  8.         private static const paiGao:Number=100+2;
  9.         private static const jiafen:int=100;
  10.         private static const jianfen:int=-5;
  11.         private var paiX:Number=Math.floor((stage.stageWidth-40)/paiKuan);
  12.         private var paiY:uint=Math.floor((stage.stageHeight-40)/paiGao);
  13.         private var bianX:Number=(stage.stageWidth-paiX*paiKuan)/2;
  14.         private var bianY:Number=(stage.stageHeight-paiY*paiGao)/2;
  15.         private var pai1:Card1;
  16.         private var pai2:Card1;
  17.         private var fenshu:TextField;
  18.         private var defen:int;
  19.         private var geshi:TextFormat;
  20.         public function Mygame1():void {
  21.             var myCards:Array=new Array();
  22.             for (var j:uint=2; j<paiShu+2; j++) {
  23.                 myCards.push(j);
  24.             }
  25.             var cardlist:Array=new Array();
  26.             if (paiX*paiY/2!=0) {
  27.                 paiY–;
  28.                 bianY+=paiGao/2;
  29.             }
  30.             for (var i:uint=0; i<paiX*paiY/2; i++) {
  31.                 var r0:uint=Math.floor(Math.random()*myCards.length);
  32.                 cardlist.push(myCards[r0]);
  33.                 cardlist.push(myCards[r0]);
  34.                 myCards.splice(r0,1);
  35.             }
  36.             //trace(cardlist);
  37.             for (var x:uint=0; x<paiX; x++) {
  38.                 for (var y:uint=0; y<paiY; y++) {
  39.                     var c:Card1 = new Card1();
  40.                     c.stop();
  41.                     c.height=100;
  42.                     c.width=100;
  43.                     c.x=x*paiKuan+bianX;
  44.                     c.y=y*paiGao+bianY;
  45.                     var r:uint=Math.floor(Math.random()*cardlist.length);
  46.                     c.cardface=cardlist[r];
  47.                     cardlist.splice(r,1);
  48.                     //c.gotoAndStop(c.cardface);
  49.                     addChild(c);
  50.                     c.addEventListener(MouseEvent.CLICK,fanPai);
  51.                 }
  52.             }
  53.             //trace(myCards);
  54.             fenshu = new TextField();
  55.             addChild(fenshu);
  56.             fenshu.width=300;
  57.             defen=0;
  58.             xiandefen();
  59.         }
  60.         public function fanPai(evt:MouseEvent) {
  61.             var paiN:Card1=(evt.target as Card1);
  62.             if (pai1==null) {
  63.                 pai1=paiN;
  64.                 paiN.gotoAndStop(paiN.cardface);
  65.             } else if (pai2==null) {
  66.                 if (paiN==pai1) {
  67.                     pai1.gotoAndStop(1);
  68.                     pai1=null;
  69.                 } else {
  70.                     pai2=paiN;
  71.                     paiN.gotoAndStop(paiN.cardface);
  72.                     if (pai1.cardface==pai2.cardface) {
  73.                         removeChild(pai1);
  74.                         removeChild(pai2);
  75.                         pai1=null;
  76.                         pai2=null;
  77.                         defen+=jiafen;
  78.                         xiandefen();
  79.                     } else {
  80.                         defen+=jianfen;
  81.                         xiandefen();
  82.                     }
  83.                 }
  84.             } else {
  85.                 pai1.gotoAndStop(1);
  86.                 pai2.gotoAndStop(1);
  87.                 pai1=paiN;
  88.                 pai2=null;
  89.                 paiN.gotoAndStop(paiN.cardface);
  90.             }
  91.         }
  92.         public function xiandefen() {
  93.             fenshu.text=”你的得分:”+String(defen);
  94.             geshi= new TextFormat( );
  95.             geshi.color=0x0000ff;
  96.             geshi.bold=true;
  97.             geshi.size=24;
  98.             fenshu.setTextFormat(geshi);
  99.         }
  100.     }
  101. }

MyGame.swf (1668 K) 下载次数:1 [试播]

 
 
 
 
 
 
 

To have a clock, we need to use the getTimer() function. This will return the time since the Flash movie started, in milliseconds. This is a special function that requires a special Flash class that we need to import at the start of our program:

复制代码

  1. import flash.utils.getTimer;

The getTimer function measures the number of milliseconds since the Flash movie started. However, it is never useful as a raw time measurement because the player won’t ever be starting a game the instant the movie appears on his or her screen. Instead, getTimer is useful when you take two measurements and subtract the later one from the earlier one.

Now we will need some new variables. We need one to record the time the game started and one to store the game time:

复制代码

  1. private var kaishiT:uint;
  2. private var youxiT:uint;

We also need to define a new text field to display the time to the player:

复制代码

  1. private var jishi:TextField;

In the constructor function, we add a new text field to display the time. We also move to the right side of the screen so that it won’t be on top of the score display:

复制代码

  1. jishi = new TextField();
  2. jishi.x = stage.stageWidth-200;
  3. jishi.width=200;
  4. addChild(jishi);

Before the constructor function is done, we’ll want to set the gameStartTime variable. We can also set the gameTime to zero:

复制代码

  1. kaishiT = getTimer();
  2. youxiT= 0;

Now we need to figure out a way for the game time to update. we can create a Timer object, or we can  just have the ENTER_FRAME event trigger a function that updates the clock. In a default Flash movie, this will happen 24  times a second, which is certainly enough:

复制代码

  1. addEventListener(Event.ENTER_FRAME,xianT);

All that is left is to make the xianT function. It will calculate the current time based on the current value of getTimer() and the value of kaishiT.  Then, it will put it in the text field for display:

复制代码

  1. public function xianT(evt:Event) {
  2. youxiT= getTimer()-kaishiT;
  3. jishi.text = “使用时间:”+youxiT;
  4. }

or:

复制代码

  1. public function xianT(evt:Event) {
  2.             youxiT=getTimer()-kaishiT;
  3.             jishi.text=”使用时间:”+youxiT;
  4.             geshi= new TextFormat( );
  5.             geshi.color=0x0000ff;
  6.             geshi.bold=true;
  7.             geshi.size=24;
  8.             jishi.setTextFormat(geshi);
  9.         }

As you can see, the showTime function displays the number of milliseconds since the game started. Typical players don’t care about milliseconds; they want to see a normal clock, with minutes and seconds displayed as they would on a digital watch.

Let’s break this out in another function. Instead of just including the raw gameTime in the text field as in the preceding code example, we can call a function to return a nicer output:

复制代码

  1. jishi.text=”使用时间:”+fenmiaoT(youxiT);

The idea is that the old code would show this:

Time: 123726

The new code will show:

Time: 2:03

The clockTime function will take the time in raw milliseconds and convert it to minutes and whole seconds. In addition, it will format it to use a colon (:) and make sure that a zero is placed correctly when the number of seconds is fewer than ten.

The function will start off by simply dividing the number of milliseconds by 1,000 to get the number of seconds. It will then divide that by 60 to get the number of minutes.

复制代码

  1. public function fenmiaoT(fm:int) {
  2.             var miao:int=Math.floor(fm/1000);
  3.             var fen:int=Math.floor(miao/60);
  4.             miao-=fen*60;
  5.             //var fenmiaoZ:String=fen+”:”+miao;
  6.             var fenmiaoZ:String=fen+”:”+String(miao+100).substr(1,2);
  7.             return fenmiaoZ;
  8.         }
复制代码

  1. package {
  2.     import flash.display.*;
  3.     import flash.events.*;
  4.     import flash.text.*;
  5.     import flash.utils.getTimer;
  6.     public class Mygame1 extends MovieClip {
  7.         private static const paiKuan:Number=84+2;
  8.         private static const paiGao:Number=125+2;
  9.         private static const jiafen:int=100;
  10.         private static const jianfen:int=-5;
  11.         private var paiX:uint=Math.floor((stage.stageWidth-40)/paiKuan);
  12.         private var paiY:uint=Math.floor((stage.stageHeight-60)/paiGao);
  13.         private var bianX:Number=(stage.stageWidth-(paiX-1)*paiKuan)/2-1;
  14.         private var bianY:Number=(stage.stageHeight-(paiY-1)*paiGao)/2-1;
  15.         private var pai1:Card1;
  16.         private var pai2:Card1;
  17.         private var cardsLeft:uint=0;
  18.         private var paiShu:uint=10;
  19.         private var fenshu:TextField;
  20.         private var defen:int;
  21.         private var geshi:TextFormat;
  22.         private var jishi:TextField;
  23.         private var kaishiT:uint;
  24.         private var youxiT:uint;
  25.         public function Mygame1():void {
  26.             var pai:Card1=new Card1();
  27.             paiShu=pai.totalFrames;
  28.             var myCards:Array=new Array();
  29.             for (var j:uint=2; j<paiShu+2; j++) {
  30.                 myCards.push(j);
  31.             }
  32.             var cardlist:Array=new Array();
  33.             /*if (paiX*paiY/2!=0) {
  34.             paiY–;
  35.             bianY+=paiGao/2;
  36.             }*/
  37.             for (var i:uint=0; i<paiX*paiY/2; i++) {
  38.                 var r0:uint=Math.floor(Math.random()*myCards.length);
  39.                 cardlist.push(myCards[r0]);
  40.                 cardlist.push(myCards[r0]);
  41.                 myCards.splice(r0,1);
  42.             }
  43.             //trace(cardlist);
  44.             for (var x:uint=0; x<paiX; x++) {
  45.                 for (var y:uint=0; y<paiY; y++) {
  46.                     var c:Card1 = new Card1();
  47.                     c.stop();
  48.                     c.height=paiGao-2;
  49.                     c.width=paiKuan-2;
  50.                     c.x=x*paiKuan+bianX;
  51.                     c.y=y*paiGao+bianY;
  52.                     var r:uint=Math.floor(Math.random()*cardlist.length);
  53.                     c.cardface=cardlist[r];
  54.                     cardlist.splice(r,1);
  55.                     //c.gotoAndStop(c.cardface);
  56.                     addChild(c);
  57.                     cardsLeft++;
  58.                     c.addEventListener(MouseEvent.CLICK,fanPai);
  59.                 }
  60.             }
  61.             //trace(myCards);
  62.             defen=0;
  63.             fenshu = new TextField();
  64.             fenshu.width=200;
  65.             addChild(fenshu);
  66.             xiandefen();
  67.             jishi = new TextField();
  68.             jishi.x=stage.stageWidth-200;
  69.             jishi.width=200;
  70.             addChild(jishi);
  71.             kaishiT=getTimer();
  72.             youxiT=0;
  73.             addEventListener(Event.ENTER_FRAME,xianT);
  74.         }
  75.         public function fanPai(evt:MouseEvent) {
  76.             var paiN:Card1=(evt.target as Card1);
  77.             if (pai1==null) {
  78.                 pai1=paiN;
  79.                 paiN.gotoAndStop(paiN.cardface);
  80.             } else if (pai2==null) {
  81.                 if (paiN==pai1) {
  82.                     pai1.gotoAndStop(1);
  83.                     pai1=null;
  84.                 } else {
  85.                     pai2=paiN;
  86.                     paiN.gotoAndStop(paiN.cardface);
  87.                     if (pai1.cardface==pai2.cardface) {
  88.                         removeChild(pai1);
  89.                         removeChild(pai2);
  90.                         pai1=null;
  91.                         pai2=null;
  92.                         defen+=jiafen;
  93.                         xiandefen();
  94.                         cardsLeft-=2;
  95.                         if (cardsLeft<2) {
  96.                             MovieClip(root).gotoAndStop(“gameover”);
  97.                         }
  98.                     } else {
  99.                         defen+=jianfen;
  100.                         xiandefen();
  101.                     }
  102.                 }
  103.             } else {
  104.                 pai1.gotoAndStop(1);
  105.                 pai2.gotoAndStop(1);
  106.                 pai1=paiN;
  107.                 pai2=null;
  108.                 paiN.gotoAndStop(paiN.cardface);
  109.             }
  110.         }
  111.         public function xiandefen() {
  112.             fenshu.text=”你的得分: “+String(defen);
  113.             geshi= new TextFormat( );
  114.             geshi.color=0x0000ff;
  115.             geshi.bold=true;
  116.             geshi.size=24;
  117.             fenshu.setTextFormat(geshi);
  118.         }
  119.         public function xianT(evt:Event) {
  120.             youxiT=getTimer()-kaishiT;
  121.             jishi.text=”使用时间:”+fenmiaoT(youxiT);
  122.             geshi= new TextFormat( );
  123.             geshi.color=0x0000ff;
  124.             geshi.bold=true;
  125.             geshi.size=24;
  126.             jishi.setTextFormat(geshi);
  127.         }
  128.         public function fenmiaoT(fm:int) {
  129.             var miao:int=Math.floor(fm/1000);
  130.             var fen:int=Math.floor(miao/60);
  131.             miao-=fen*60;
  132.             var fenmiaoZ:String=fen+”:”+miao;
  133.             //var fenmiaoZ:String=fen+”:”+String(miao+100).substr(1,2);
  134.             return fenmiaoZ;
  135.         }
  136.     }
  137. }

MyGame.swf (1668 K) 下载次数:7 [试播]

Displaying Score and Time after the Game Is Over

This is a little tricky because the gameover screen exists on the main timeline, outside of the game movie clip. To have the  main timeline even know what the score and time are, this data needs to be sent from the game to the root level.

Just before we call the gotoAndStop command that will advance the movie to the gameover screen, we pass these two values up to root:

复制代码

  1. MovieClip(root).fenShu=defen;
  2. MovieClip(root).shiJian=fenmiaoT(youxiT);

At the root level, we need to define those new variables,  I’ve added this code to the first frame:

复制代码

  1. var fenShu:int;
  2. var shiJian:String;

Then, on the gameover frame, we use these variables to place values in new text fields:

复制代码

  1. fenshu.text = “Score: “+String(fenShu);
  2. shijian.text = “Time: “+shiJian;

We don’t need to use code to create the showScore and showTime dynamic text fields; we can simply do that on the stage with the Flash editing tools.

To simplify things here, we’re including the “Score: “ and “Time: “ strings in with the Score and Time fields. But, a more professional way to do it would be to have the words Score and Time as static text or graphics on the screen, and only the actual  score and time in the fields.

分类
Flash professional

Flash 的数组

Flash 的数组

数组保存一组相关联的数据,组织和处理这些数据。数组概念在生活中是很常见的,比如菜谱,包含姓名,地址,生日等地址本都是数组原理。

在ActionScript中,有两种数组:整型下标和联合数组,都是组织相关数据,只是访问数据的方法不同而已。

整型下标数组:

数组的每个元素都用唯一的整数下标来索引。通过下标排序,起始值为0,每个元素保存在索引指定的位置,这就像抽屉一样。

联合数组:

用字符串关键字作为每个元素的索引。

首先创建数组,有两种构造方法,

// 创建空的数组
var array:Array = new Array();

// 创建数组时指定数组长度
var array:Array = new Array(elements);

//创建数组时加入多个元素
var array:Array = new Array(element0,…elementN);

直接用数组符号也可以创建一个数组,这是很简洁的方式创建数组:
var letters:Array = [“a”, “b”, “c”];

Array 类提供了一些方法修改数组内容或者返回新的数组使用数组操作符(中括号加上下标索引)来读取和设置内容,如:

//设置第5个元素为”apples”
// (下标从0开始).
items[4] = “apples”;
// 显示第5个元素
trace(items[4]); // 显示: apples

ActionScript 并不关心数组里存的是什么类型的数据,可以是字符串,数字,布尔值和引用的类型,而且不像其他语言,同一个数组可以存不同类型的数据,例如:
var data:Array = [“a”, 2, true, new Object()];

还有点不同,数组在创建时可以不用指定数组长度。

 

 

在数组首部和尾部添加元素

push( ) 方法可在数组尾部添加元素,unshift( ) 方法可在数组首部插入元素。

Array.push( ) 方法把元素加在数组的尾部,也可以一次添加多个值:
var array:Array = new Array();
array.push(“val 1”, “val 2”);

也可以在数组指定的下标位置设置值,下标位置在0到Array .length – 1之间:
array[array.length] = “val 3”;

如果下标不存在,数组会自动扩充,扩充的空间当中,没有被赋值的自动以“undefined”填充:
var letters:Array = [“a”, “b”, “c”];
letters[5] = “f”;

通过unshift( ) 方法在数组首部插入新元素:
// 创建四个元素的数组
// “a”, “b”, “c”, “d”.
var letters:Array = new Array( );
letters.push(“a”, “b”, “c”, “d”);
// 添加”z” ,其他元素依次向下移动
letters.unshift(“z”);
for (var i:int = 0; i < letters.length; i++) {
trace(letters[i]);
}

 

 

 遍历数组成员

可利用for 循环来遍历数组,使用下标返回元素。
for循环的初始变量从0开始,结束为array.length-1,因为是从下标0开始的:
var letters:Array = [“a”, “b”, “c”];
for (var i:int = 0; i < letters.length; i++) {
trace(“Element ” + i + “: ” + letters[i]);
}
也可以降序遍历数组,循环变量从array.length-1开始到0:
var letters:Array = [“a”, “b”, “c”];
for (var i:int = letters.length – 1; i >= 0; i–){
trace(“Element ” + i + “: ” + letters[i]);
}

有很多情况需要用循环遍历所有元素,比如,获得了包含sprite的数组, 然后把每个sprite的x坐标+1:
for (var i:int = 0; i < sprites.length; i++){
sprites[i].x++;
}

也可以把数组长度存在变量中,免得每次循环都要重新计算:
var length:int = sprites.length;
for (var i:int = 0; i < length; i++){
sprites[i].x++;
}

这样做可以提高Flash 性能,因为不用每次循环都去计算长度了,但是有个前提,就是没有进行插入删除操作来改变长度值,否则就要每次计算长度才行。

用for 语句和break 语句就能找到匹配的元素。另外用ArrayUtilities.findMatchIndex( ),ArrayUtilities.findLastMatchIndex( ), 和ArrayUtilities.findMatchIndices( ) 方法。

用for循环查找第一个匹配的元素后,用break立即返回,这样就实现功能了。

break应该在if语句里进行判断,是否找到匹配元素,找到则执行break推出循环,否则继续查找。

var letters:Array = [“a”, “b”, “c”, “d”, “a”, “b”, “c”, “d”];
// 指定要搜索的内容
var match:String = “b”;
for (var i:int = 0; i < letters.length; i++) {
// 检测当前元素是否匹配
if (letters[i] == match) {
trace(“Element with index ” + i +
” found to match ” + match);
break;
}
}

也可以找到匹配的最后一个元素,这就需要倒序遍历数组:
var letters:Array = [“a”, “b”, “c”, “d”, “a”, “b”, “c”, “d”];
var match:String = “b”;
for (var i:int = letters.length – 1; i >= 0; i–) {
if (letters[i] == match) {
trace(“Element with index ” + i +
” found to match ” + match);
break;
}
}

使用自定义类ArrayUtilities 类更简单,它在ascb.util 包中,首先导入它:
import ascb.util.ArrayUtilities;
ArrayUtilities 类有三个方法来查找匹配的元素findMatchIndex( ), findLastMatchIndex( ), 和
findMatchIndices( )。findMatchIndex( ) 方法至少需要两个参数:一个指向数组的引用和需要匹
配的值,返回第一个匹配的元素下标,如果找不到返回-1:
var letters:Array = [“a”, “b”, “c”, “d”];
trace(ArrayUtilities.findMatchIndex(letters, “b”));
// 显示: 1
trace(ArrayUtilities.findMatchIndex(letters, “r”));
// 显示: -1
也可以指定搜索的起始下标作为第三个参数:
var letters:Array = [“a”, “b”, “c”, “d”, “a”, “b”, “c”, “d”];
trace(ArrayUtilities.findMatchIndex(letters, “a”, 1));
// 显示: 4
如果第三个参数为true,则返回部分匹配的元素:
var words:Array = [“bicycle”, “baseball”, “mat”, “board”];
trace(ArrayUtilities.findMatchIndex(words, “s”, true));
// 显示: 1
如果你想部分匹配又想指定起始搜索下标,可以把起始下标作为第四个参数。
findLastMatchIndex( ) 方法返回最后一个匹配的元素下标
findMatchIndices( ) 方法返回所有匹配的元素下标数组:
var letters:Array = [“a”, “b”, “c”, “d”, “a”, “b”, “c”, “d”];
trace(ArrayUtilities.findMatchIndices(letters, “b”));
// 显示: 1,5
也可以设定为部分匹配,指定第三个参数为true:
var words:Array = [“bicycle”, “baseball”, “mat”, “board”];
trace(ArrayUtilities.findMatchIndices(words, “b”, true));
// 显示: 0,1,3
ArrayUtilities 方法内部也是用for循环来实现的,现在我们看看代码,下面是findMatchIndex( ) 方法的代码:
public static function findMatchIndex(array:Array, element:Object):int {
// Use a variable to determine the index
// from which to start. Use a default value of 0.
var startingIndex:int = 0;
// By default don’t allow a partial match.
var partialMatch:Boolean = false;
// If the third parameter is a number,
// assign it to nStartingIndex.
// Otherwise, if the fourth parameter is a number,
// assign it to nStartingIndex instead.
if(typeof arguments[2] == “number”) {
startingIndex = arguments[2];
}
else if(typeof arguments[3] == “number”) {
startingIndex = arguments[3];
}
// If the third parameter is a Boolean value,
// assign it to partialMatch.
if(typeof arguments[2] == “boolean”) {
partialMatch = arguments[2];
}
// Assume no match is found.
var match:Boolean = false;
// Loop through each of the elements of the array
// starting at the specified starting index.
for(var i:int = startingIndex;
i < array.length; i++) {
// Check to see if the element either matches
// or partially matches.
if(partialMatch) {
match = (array[i].indexOf(element) != -1);
}
else {
match = (array[i] == element);
}
// If the element matches, return the index.
if(match) {
return i;
}
}
// The following return statement is only reached
// if no match was found. In that case, return -1.
return -1;
}
public static function findMatchIndices(array:Array,
element:Object, partialMatch:Boolean = false):Array {
var indices:Array = new Array( );
var index:int = findMatchIndex(array,
element,
partialMatch);
while(index != -1) {
indices.push(index);
index = findMatchIndex(array,
element,
partialMatch,
index + 1);
}
return indices;
}

splice( ) 方法删除指定位置的元素,pop( ) 删除尾部元素,shift( ) 删除首部元素。

删除指定位置的元素使用splice( ) 方法,它需要两个参数:
start:开始下标
deleteCount:删除的元素个数,如果没有定义,则从起始位置到末尾全部删除:

var letters:Array = [“a”, “b”, “c”, “d”];
//从下标1开始删除1个元素
letters.splice(1, 1);
// 显示结果,现在只剩三个
// “a”, “c”, 和”d”.
for (var i:int = 0; i < letters.length; i++) {
trace(letters [i]);
}

splice( ) 方法也返回一个新的包含删除的元素数组:
var letters:Array = [“a”, “b”, “c”, “d”];
//删除两个元素,从0位置开始
var deleted:Array = letters.splice(0, 2);
// 显示: “a”,”b”.
for (var i:int = 0; i < deleted.length; i++) {
trace(deleted[i]);
}

删除首部和尾部的元素可用shift( ) 和pop( ) 方法。shift( ) 方法删除首部第一个元素,然后返回
该元素,pop( ) 方法删除尾部的元素并返回该值:
var letters:Array = [“a”, “b”, “c”, “d”];
trace(letters.shift( ));
trace(letters.pop( ));
//显示剩下的元素
for (var i = 0; i < letters.length; i++) {
trace(letters[i]);
}

在for循环里删除原始,也要修改下标值,下面的代码演示不更新下标值变量出现的情况:
var numbers:Array = new Array(4, 10);
numbers[4] = 1;
trace(numbers); // 显示: 4,10,undefined,undefined,1
for(var i:int = 0; i < numbers.length; i++) {
if(numbers[i] == undefined) {
numbers.splice(i, 1);
}
}

trace(numbers); // 显示: 4,10,undefined,1

上面的代码本来是期望上出全部undefined 元素的,结果只删除一个,调试运行,看看发生了什
么:
1。前两个循环什么都没做,因为都不是undefined.
2。第三次找到undefined 然后删除它,这时,第4个和第5个元素下移变成了第3个和第4个元

3。下一循环检测第4个元素,也就是最后一个,这时忽略了第3个元素也就是那个undefined 元
素,因此,当删除元素,应该把小标变量-1,代码应该这样:
var numbers:Array = new Array(4, 10);
numbers[4] = 1;
trace(numbers); // 显示: 4,10,undefined,undefined,1
for(var i:int = 0; i < numbers.length; i++) {
if(numbers[i] == undefined) {
numbers.splice(i, 1);
i–;
}
}
trace(numbers); // 显示: 4,10,1

在数组中间插入元素

使用splice( ) 方法可在数组中间插入元素。

splice( ) 方法不仅可以删除元素,也可以插入元素,插入的元素放到第2个参数之后,当第2个
参数为0代表插入元素:
var letters:Array = [“a”, “b”, “c”, “d”];
//插入三个元素,起始位置为1
letters.splice(1, 0, “r”, “s”, “t”);
// letters 现在包含的元素有:
// “a”, “r”, “s”, “t”, “b”, “c”, “d”.
for (var i:int = 0; i < letters.length; i++) {
trace(letters[i]);
}

你也可以删除和插入同时执行:
var letters:Array = [“a”, “b”, “c”, “d”];
//删除2个,插入3个
letters.splice(1, 2, “r”, “s”, “t”);
// myArray 现在的元素
// “a”, “r”, “s”, “t”, and “d”.
for (var i:int = 0; i < letters.length; i++) {
trace(letters[i]);
}

转换字符串为数组

使用String.split( ) 方法可转换字符串为数组。

String 类的split( ) 方法把字符串转换为数组,但前提是字符串中含有统一的分割符,比如
Susan,Robert,Paula 字符串分割符为逗号
split( ) 方法接受两个参数:
分割符:用分割符来分割字符串,如果没定义,则把整个字符串作为数组的第一个元素
数量:分割出的最大元素个数,如果没定义,则全部放入数组。

可以使用空格符作为分割符:
var list:String = “Peter Piper picked a peck of pickled peppers”;
var words:Array = list.split(” “);

split( ) 方法在用URLLoader 对象读取数据时经常用到,比如你接受服务器的一些姓名字符串:
names=Michael,Peter,Linda,Gerome,Catherine
这是用split( ) 方法转换为数组:
// URLLoader 读取数据
var namesData:String = _loader.data;
var names:Array = namesData.split(“,”);

使用join( ) 方法可转换数组为字符串。

ActionScript 提供内建的方法join( ) 可以快速把数组转换为字符串(数组中的元素不管什么类
型都将转换为字符串),该方法接受个参数作为分隔符:
var letters:Array = [“a”, “b”, “c”];
trace(letters.join(“|”)); // 显示: a|b|c
如果不指定分隔符,默认为逗号:
var letters:Array = [“a”, “b”, “c”];
trace(letters.join()); // 显示: a,b,c

当join( ) 的分隔符为逗号,其效果和toString( ) 一样。实际上当我们直接输出数组时系统就是
调用toString( ) 方法进行转换的,例如:
var letters:Array = [“a”, “b”, “c”];
trace(letters); // 显示: a,b,c

创建数组的拷贝

使用concat( ) 方法或slice( ) 方法可创建数组的拷贝,也可以使用ArrayUtilities.duplicate( ) 方法,duplicate( )方法还可以创建递归复制。

因为数组是复合类型,因此它的比较和复制都和基本类型不同。一个变量指向数组但是实际上它并不包含数组数据,它只是指向内存中存放数组数据的位置。从优化的角度考虑,基本类型的占用空间往往很小,但是符合类型如数组可以变得很大,如果我们在日常操作中经常复制整个数组是非常不明智的,因此当你要复制数组时,ActionScript 并不是生成独立的一份拷贝,看下面的例子:

首先我们看看基本类型是怎么复制的:
// 赋值数字5给变量
var quantity:int = 5;
// 拷贝quantity的值给另一个变量newQuantity.
var newQuantity:int = quantity;
// 改变quantity的值
quantity = 29;
trace(quantity); // 显示: 29
trace(newQuantity); // 显示: 5

我们看到,两者是互不影响的,也就是说基本变量拷贝的是值

现在我们看看数组的操作,和上面的例子不同,两个变量实际上都指向了同一个数组存贮空间。当letters 变量改变数组内容时,也影响到newLetters变量:
// 赋值数组.
var letters:Array = [“a”, “b”, “c”];
// 拷贝letters 到newLetters.
var newLetters:Array = letters;
// 两个数组包含相同内容
trace(letters); // 显示: “a,b,c”
trace(newLetters); // 显示: “a,b,c”

我们看到,两者是互不影响的,也就是说基本变量拷贝的是值
现在我们看看数组的操作,和上面的例子不同,两个变量实际上都指向了同一个数组存贮空间。
当letters 变量改变数组内容时,也影响到newLetters变量:
// 赋值数组.
var letters:Array = [“a”, “b”, “c”];
// 拷贝letters 到newLetters.
var newLetters:Array = letters;
// 两个数组包含相同内容
trace(letters); // 显示: “a,b,c”
trace(newLetters); // 显示: “a,b,c”
trace(letters); // 显示: “a,b,c”
trace(newLetters); // 显示: “a,b,c”
// 改变letters的值
letters = [“d”, “e”, “f”];
//不像上面的例子,这次两个数组内容不同了.
trace(letters); // 显示: “d,e,f”
trace(newLetters); // 显示: “a,b,c”

也可以用slice( ) 方法代替concat( ), 例如:
var newLetters:Array = letters.slice(0);
concat( ) 或slice( ) 方法复制一维整型下标的数组还可以,但是如果是多维的联合数组就不行了,对于联合数组,不能使用concat( ) 或slice( ) 方法,对于多维数组,用concat( ) 或slice( )只能复制顶层的数组,内部的就不能复制了,看下面的代码:
var coordinates:Array = new Array( );
coordinates.push([0,1,2,3]);
coordinates.push([4,5,6,7]);
coordinates.push([8,9,10,11]);
coordinates.push([12,13,14,15]);
// 复制
var coordinatesDuplicate:Array = coordinates.concat( );
// 替换元素
coordinatesDuplicate[0][0] = 20;
trace(coordinates[0][0]); //显示: 20
// 替换顶层元素.
coordinatesDuplicate[1] = [21,22,23,24];
trace(coordinates[1]); // 显示: 4,5,6,7

上面的代码coordinates 是个二维数组,coordinatesDuplicate 是coordinates的复制。但是,虽然是复制,有些元素仍然引用了原始数组元素,这就意味你改变了一个,会影响另一个数组的内容。实际上从上面的代码可以看出,只复制了顶层的数组,这一部分是互不关联的。

要想完全的复制数组,需要使用递归。ArrayUtilities.duplicate( ) 方法就是这样的做法,默认下
它也只复制一层数组,当第2个参数设为true时则是递归复制:
// 创建二维数组
var coordinates:Array = new Array( );
for(var i:int = 0; i < 4; i++) {
coordinates[i] = new Array( );
for(var j:int = 0; j < 4; j++) {
coordinates[i].push(String(i) + “,” + String(j));
}
}
// 复制coordinates.
var newCoordinates:Array = ArrayUtilities.duplicate(coordinates, true) as Array;
// 替换
newCoordinates[0][0] = “a”;
// 使用toString() 方法输出
trace(ArrayUtilities.toString(coordinates));
trace(ArrayUtilities.toString(newCoordinates));
下面的例子演示用duplicate( ) 方法复制联合数组:
var coordinatesMap:Object = new Object( );
coordinatesMap.a = [{a: 1},{b: 2}, {c: 3}, {d: 4}];
coordinatesMap.b = [{a: 1},{b: 2}, {c: 3}, {d: 4}];
coordinatesMap.c = [{a: 1},{b: 2}, {c: 3}, {d: 4}];
coordinatesMap.d = [{a: 1},{b: 2}, {c: 3}, {d: 4}];
var newCoordinatesMap:Object = ArrayUtilities.duplicate(coordinatesMap, true);
newCoordinatesMap.a[0] = {r: 5};
trace(ArrayUtilities.toString(coordinatesMap));
trace(ArrayUtilities.toString(newCoordinatesMap));

两个例子可以看到,复制的数组改变不会影响原始数组。

 存储多维数据

除了一维数组,还可以创建多维数组,比如beginGradientFill() 方法(在第7章讨论)使用三个
平行数组表示colors, alphas, 和ratios ,每个数组都有相同的下标。
创建平行数组,然后操作同一下标的元素,使用平行数组,很容易访问同一下标的相关元素,
比如:
var colors:Array = [“maroon”, “beige”, “blue”, “gray”];
var years:Array = [1997, 2000, 1985, 1983];
var makes:Array = [“Honda”, “Chrysler”, “Mercedes”, “Fiat”];
// 循环这些数组,因此数组的长度相同,可以用任何一个数组的length属性,下面的例子使用了
//makes.length.
for (var i:int = 0; i < makes.length; i++) {
trace(“A ” + colors[i] + ” ” +
years[i] + ” ” +
makes[i]);
// 显示:
// A maroon 1997 Honda
// A beige 2000 Chrysler
// A blue 1985 Mercedes
// A gray 1983 Fiat
}
需要注意的是,如果改变了数组长度,必须同时修改其他数组。
另一种方法就是创建多维数组,它是数组的数组:
// 创建数组cars,然后用数组组装填充,每个元素都是数组包含3个元素(color, year, make).
var cars:Array = new Array();
cars.push([“maroon”, 1997, “Honda”]);
cars.push([“beige”, 2000, “Chrysler”]);
cars.push([“blue”, 1985, “Mercedes”]);
cars.push([“gray”, 1983, “Fiat”]);
// 循环遍历数组
for (var i:int = 0; i < cars.length; i++) {
// 显示:
// A maroon 1997 Honda
// A beige 2000 Chrysler
// A blue 1985 Mercedes
// A gray 1983 Fiat
TRace(“A ” + cars[i][0] + ” ” +
cars[i][1] + ” ” +
cars[i][2]);
}
下面的代码用二重循环遍历二维数组:
for (var i:int = 0; i < cars.length; i++) {
for (var j:int = 0; j < cars[i].length; j++) {
TRace(“Element [” + i + “][” + j + “] contains: ” +
cars[i][j]);
}
}

从上面的例子来看,很难区别cars[i][0] 和cars[i][j]。但如果任何数组的长度发生变化这时cars[i][0]这种表示就很被动,需要修改代码才行。

另外对象数组的使用也很类似,只是多了个名称属性。对象数组用名称属性代替数字下标来索引元素:
// 创建数组cars,填充对象
// 每个对象有个make 属性,year 属性和color 属性
var cars:Array = new Array();
cars.push({make: “Honda”, year: 1997, color: “maroon”});
cars.push({make: “Chrysler”, year: 2000, color: “beige”});
cars.push({make: “Mercedes”, year: 1985, color: “blue”});
cars.push({make: “Fiat”, year: 1983, color: “gray”});
// 遍历数组
for (var i:int = 0; i < cars.length; i++) {
trace(“A ” + cars[i].color + ” ” +
cars[i].year + ” ” +
cars[i].make);
}