23 November 2010
当将ActionScript代码输入到Actions面板之后,它将链接到FLA文件的当前选择的框架。 即使代码复杂度很高的SWF文件也能够通过只与框架脚本(framescript)共存的代码,或基于timeline框架的代码进行编译。 然而,使用框架脚本代码存在下列一些缺点:
在文本文件中编写ActionScript可以避免这些缺点。 外部文件甚至无需使用编辑工具也能进行编写,因此设计人员和开发人员能够协同工作。 标准化的结构还能够改善代码的质量并且使得未来Flash和 Flex的重用变得更为简便。
如需将FLA文件与外部ActionScript进行链接,应该定义一个document类。 为了实现这一目的,取消你已经选定的任何stage条目,然后打开Propertie面板。 该面板包含与你的文档相关的设置,其中包括背景颜色和框架速率。 它还包含一个 Document类字段。 将该字段设置为你的外部文件的名称,但不带AS扩展名。 该文件必须包含一个public类,其名称应该与AS扩展名之前的名称匹配。
例如,创建一个新的FLA然后将其另存为TestFile.fla。另外,在Flash Professional 或你喜欢的文本编辑器中,创建一个新的AS文件,然后在与你的FLA文件相同的目录中将其另存为 MyClass.as。 将下列代码输入到 MyClass.as文件中:
package
{
import flash.display.Sprite;
public class MyClass extends Sprite
{
public function MyClass() {
trace("Hello World");
}
}
}
在TestFile.fla的Properties面板中,将Document 类字段设置为 "MyClass",然后保存它。 测试该影片剪辑将使得 "Hello World" 能够追溯到 output 面板。
注意: MyClass.as中的导入语句与flash.* 命名空间的任何导入语句一样对于在timeline上编写代码不是必需的,因为 Flash Professional 能够在编译之前自动导入这些包。 由于这一情形在外部文件中不会发生,因此,导入语句对于成功编译使用来自flash.* 命名空间的类的任何外部ActionScript文件来说是必要的。
在默认情形下,在Flash文档库中的影片剪辑符号的实例不能动态创建(也就是说,必须由ActionScript创建)。 这是因为被导出用于ActionScript的每个符号需要添加到你的SWF文件空间中。 因此,为了使得一个符号在ActionScript中可用,你必须指定该符号需要被导出以便能够用于ActionScript。
按照下列步骤为 ActionScript导出一个符号:
在默认情形下,使用符号的名称填入Class字段,名称单词之间的空格删除 (例如,名称为 "Tree House"的符号应该变为 "TreeHouse")。 如果需要指定符号使用自定义类实现其操作,则必须在该字段中输入包含其包的类的全名。 如果你希望在 ActionScript中能够创建符号的实例,但不需要添加任何附加操作,则你可以保持该类的名称不变。
在改变连接设置之后,Flash将试图寻找具有在Class字段指定类的定义的一个外部ActionScript文件。 如果它找不到外部ActionScrpt 文件,则应该给出告警信息。 如果你不需要MovieClip类功能之外的附加操作,则该告警可以置之不理,因为系统将会自动为其生成一个类。自动生成的类与下列代码相似:
package
{
import flash.display.MovieClip;
public class ExampleMovieClip extends MovieClip
{
public function ExampleMovieClip() {
}
}
}
Base Class的默认值为flash.display.MovieClip。除非你正在使用一个自动生成的能够使用外部类功能的类,否则应该使用该默认值。Base Class 与扩展名不同义;如果你指定一个自己扩展另一个类的自定义类,则将这一超级类指定为 Base Class是没有必要的。 在这一情形下,使用默认值 flash.display.MovieClip即可。 然而,如果你希望两个符号:RedFish和 BlueFish, 具有相同的功能但不同的皮肤,则你可以使用相应的编辑工具创建不同的外观,然后将它们的Base Class设置为 Fish,并且在外部 Fish.as文件中使用一个Fish类,以便为这两条鱼提供功能。在编写一个自定义类时,可以使用一个自动生成的类创建一个外部文件,然后为该类添加适当的属性和方法。 例如,假定你具有一段包含一个50像素宽和50像素高的圆形物的影片剪辑符号,并且指定该符号导出到具有一个名称为Circle的类的ActionScript。 将下列代码放入Circle.as文件中,该文件与FLA文件存储于相同的目录,这些代码能够扩展MovieClip类的功能并且能够提供具有附加方法 getArea()和 getCircumference()的符号:
package
{
import flash.display.MovieClip;
public class Circle extends MovieClip
{
public function Circle()
{
}
public function getArea():Number
{
// The formula is Pi times the radius squared.
return Math.PI * Math.pow((width / 2), 2);
}
public function getCircumference():Number
{
// The formula is Pi times the diameter.
return Math.PI * width;
}
}
}
将下列代码放置于Flash文档的Frame 1的一个keyframe,它能够创建符号的一个实例,并且能够在屏幕上显示该实例。
var c:Circle = new Circle();
addChild(c);
trace(c.width);
trace(c.height);
trace(c.getArea());
trace(c.getCircumference());
该代码能够演示基于ActionScript的例示操作,它可以作为将个体asset拖拽至Stage操作的替换方法。 它能够创建一个具有影片剪辑的所有属性的circle,并且还具有在该Circle类中定义的自定义方法。
Timeline tweens在积聚的过程中,将渐渐变得难以创建和管理,特别是在它们在不同的框架上启动的情形下。 使用外部类能够简化这一过程并且使得更改操作更为简单。
例如,假定你希望制作一个下雪的动画过程。 一种可能的工作流程是使用 timeline tweens和 框架脚本。 在这一方法中,你可以制作一个雪花符号,然后提供该符号向下飘落的一系列tweens。 之后,在Stage的顶部放置若干实例。 当该影片剪辑运行时,你将看到若干向下飘落的雪花。
此刻,下雪看起来不是特别真实,因为每个雪花的外观和动画均是相同的。 你可以通过选择每个雪花并且改变其alpha属性以便增添其多样性。 你也可以复制雪花符号,制作新的飘落速度较慢或在较宽的路面飘落的雪花。 但这一制作过程存在一些缺点。 如果在创建你的最终雪花的中途,你意识到应该在最终的keyframe中将其alpha属性设置为0,以便传送一个逐渐消失的雪花,则你需要改变每个雪花影片剪辑。 尽管可以使用制作工具以这一方式添加多样性,但其优势取决于时间和手工的准确性,并且会很快变得非常耗时及未来难于更改。
利用ActionScript是这一过程的一个替代方式。 你不需要创建多个雪花影片剪辑并且在每个剪辑中保持雪花之间的不同,而只需创建一个为ActionScript导出的影片剪辑并且在其符号属性中定义一个名称为Snowflake的自定义类。 然后,创建一个ActionScript文件,该文件模仿一个自动生成的类。 最后,添加定义雪花行为的属性和方法。 编程动画可以替代许多利用制作工具制作的中间动作。
下面是一个自定义Snowflake类的范例,它使用Event.ENTER_FRAME事件来更新雪花的位置 (将该范例存储于一个名称为 Snowflake.as的文件):
package {
import flash.display.Shape;
import flash.events.Event;
import flash.filters.BlurFilter;
public class Snowflake extends Shape {
private var stageWidth:int = 550;
private var stageHeight:int = 450;
private var highestDropSpeed:uint = 16;
private var dropSpeed:int = Math.round(Math.random() * Math.random() * highestDropSpeed);
private var incrementer:int = Math.round(Math.random() * 100);
private var shades:Array = [ 0xFFFFFF, 0xCCCCCC, 0x999999, 0x666666 ];
private var windSpeed:int = 2;
public function Snowflake() {
graphics.beginFill(shades[ Math.ceil(Math.random() * shades.length) ]);
graphics.drawCircle(0,0,4);
graphics.endFill();
filters = [ new BlurFilter(1,dropSpeed,1) ];
addEventListener(Event.ENTER_FRAME,update);
reset();
}
private function reset():void {
y = Math.random() * stageHeight * -1;
x = Math.random() * stageWidth - (windSpeed*100);
scaleX = scaleY = 0.25 + (Math.random() * Math.random() * 0.75);
}
private function update(e:Event):void {
y += dropSpeed;
x += windSpeed + Math.sin(incrementer/10) * (1/(dropSpeed/3));
if (y > stageHeight) {
reset();
}
incrementer++;
}
}
}
如需创建一个下雪动画,你可以将下列代码添加至一个具有黑色背景的FLA文件中,然后将该FLA文件保存到与Snowflake.as类文件相同的目录中:
for(var i:uint; i<800; i++){
var snowflake:Snowflake = new Snowflake();
addChild(snowflake)
}
结果
如需获得本范例的源文件,请在本页面的顶部下载Snowfall.zip 。
总共能够创建800种雪花,每种雪花具有不同的大小、速度和颜色特性,并且对该外部类进行更改能够在视觉显示上获得显著不同的效果。 最终的结果是能够获得比通过利用制作工具手工创建的下雪效果更为真实。
使用Timeline创建的动画能够移植到使用Motion XML Elements的ActionScript 中,并且保留可以应用的渐落(easing)和 过滤器(filters)功能。 为了实现这一目的,你可以选择一系列包含中间动作的框架并且从Flash的Commands菜单中选择Export Motion XML。 一个基本导出XML文件的形式如下所示:
<Motion duration="10" xmlns="fl.motion.*" xmlns:geom="flash.geom.*" xmlns:filters="flash.filters.*">
<source>
<Source frameRate="31" x="0" y="0" scaleX="1" scaleY="1" rotation="0" elementType="movie clip" symbolName="Symbol 1">
<dimensions>
<geom:Rectangle left="0" top="0" width="10" height="10"/>
</dimensions>
<transformationPoint>
<geom:Point x="0" y="0"/>
</transformationPoint>
</Source>
</source>
<Keyframe index="0">
<tweens>
<SimpleEase ease="0"/>
</tweens>
</Keyframe>
<Keyframe index="9" x="10">
<tweens>
<SimpleEase ease="0"/>
</tweens>
</Keyframe>
</Motion>
通过在stage中选择一个对象以及运行Import Motion XML命令,或通过利用Animator类将Motion XML Element应用于一个显示对象,XML可以被导回至相应的制作环境中。
下面范例使用Animator类将一个Motion XML Element 赋给一个stage的显示对象,该对象的名称为box:
import fl.motion.Animator;
var motionXML:XML =
<Motion duration="10" xmlns="fl.motion.*" xmlns:geom="flash.geom.*" xmlns:filters="flash.filters.*">
<source>
<Source frameRate="31" x="0" y="0" scaleX="1" scaleY="1" rotation="0" elementType="movie clip" symbolName="Symbol 1">
<dimensions>
<geom:Rectangle left="0" top="0" width="10" height="10"/>
</dimensions>
<transformationPoint>
<geom:Point x="0" y="0"/>
</transformationPoint>
</Source>
</source>
<Keyframe index="0">
<tweens>
<SimpleEase ease="0"/>
</tweens>
</Keyframe>
<Keyframe index="9" x="10">
<tweens>
<SimpleEase ease="0"/>
</tweens>
</Keyframe>
</Motion>
var animator:Animator = new Animator(motionXML,box);
animator.play();