Flash中代码的几种应用方式

自从Flash进入了AS3.0时代,ASer们编写代码的地方就不仅仅局限于Flash IDE的动作面板中了,我们可以用任意的编辑器,编写AS类文件,作为文档类或连接到FIash IDE中。那么这几种方法到底有什么区别?我们该如何取舍呢?

如果你是在一个专业游戏公司里做ASer,可能不用考虑这个问题,但是对于独立开发者,以及像我这样自学的菜鸟,总结一些这些技巧是很有利于技术成长的!

我总结的主要有下面几种应用ActionScript代码的方式:

  • 基于舞台时间轴的代码
  • 基于元件时间轴的代码
  • 文档类中的代码
  • 为AS导出的代码

下面我们会讨论这4种方法,并分别用这4种方法创建下面示例中的效果。矩形在舞台中来回移动。

2.1codeManage

基于舞台时间轴的代码

2.2codeManage

这个方法可以追溯到AS1.0和AS2.0时代,就是在Flash IDE中把代码写在帧的动作面板中,当Flash播放到不同的帧时,对应的帧代码将被运行。

要实现示例中的效果,我需要创建2帧,在第1帧中加入下面的代码,第2帧不用填写代码。Flash播放到第2帧后,会从第1帧开始重新播放,然后又到第2帧,又返回第1帧…这样第1帧里的代码就会反复运行(请参考源码Demo1)。如下:

import flash.events.MouseEvent;

var speed:Number;

rect.buttonMode = true;
if((rect.x+rect.width/2)>stage.stageWidth)
{
	rect.x = stage.stageWidth - rect.width/2;
	speed = -5;
}
if((rect.x - rect.width/2)<0){
	rect.x = rect.width/2;
	speed = 5;
}
rect.x+=speed;

rect.addEventListener(MouseEvent.CLICK,onClick);
function onClick(e:MouseEvent):void{
	rect.parent.removeChild(rect);
}

 优点:

1. 可视化编辑与编码,适合初学者。不同帧里的元件和页面通常是不同的,我们可以针对当前页面中的元件进行编码,代码和元件通过帧对应起来,所见即所得,简单易懂,非常适合初学者。

缺点:

1. 元件的实例名称不易管理。这个方法中的代码通常用IDE中实例名称来获取元件,这样在拥有大量元件和代码的项目中,当需要修改元件名称时往往会牵一发而动全身,而且如果有成千上百的元件,命名也不是件简单的事情。
2. 代码不易管理。代码时基于帧的,那么当我们用gotoAndStop函数进行跳帧的时候,目标帧中的代码会再次运行,这会导致变量、函数、命令的重复声明和运行,特别是有removeChild、removeEventListener类似的代码时,容易出现运行时错误。另外还有内存溢出的风险。

基于元件时间轴的代码

2.3codeManage

主时间轴的效果类似,同样播放到某一帧后,运行对于帧中的代码。不同的是,因为它是基于元件的代码,所可以实现元件行为的自我控制,例如在元件的帧中添加下面的代码(请参考源码Demo2):

var speed:Number;

if((this.x+this.width/2)>stage.stageWidth)
{
	this.x = stage.stageWidth - this.width/2;
	speed = -5;
}
if((this.x - this.width/2)<0){
	this.x = this.width/2;
	speed = 5;
}
this.x+=speed;

把这元件拖至舞台后,舞台时间轴中无需填写任何代码,无需为元件设置实例名称,就可以实现上例中相同的效果。

文档类中的代码

2.4codeManage

将代码编写到一个as类文件中(这个类必须继承MoveiClip或Sprite类),然后将此类设置为Flash文件的文档类。

这是现在非常流行的一种做法,和在Flash Builder或Flash Develop的ActionScript项目中的Main类一样,整个项目依文档类为唯一的入口,完成编译和发布。

优点:

1. 可以应用第三方代码编辑器。因为as代码单独在一个类文件中,所以我们可以应用Flash Builder、Flash Develop、FDT等许多优秀的代码编辑器和IDE进行编码,以及代码高亮、代码提示、编辑错误提示等等利于编码的功能。
2. 避免了跳帧带来的运行时错误。如果Flash中只有一帧的内容,那么文档类中的代码和基于帧的代码就没有太大差异了。因此也就没有了跳帧导致的代码重复运行和运行时错误的问题啦。

缺点:

1. 不利于可视编辑与编码。因为AS代码单独在一个类文件中,代码编辑器可以不是Flash IDE,所以元件与代码的关联性就降低了,这对于习惯了用代码引用元件示例名称(实际上,不建议这么做)的初学者来说,很难适应这种做法。

同样是这个示例,用文档类实现的话,这个类的代码如下(请参考源码Demo3):

package  {
	import flash.display.MovieClip;
	import flash.events.Event;

	public class Demo3 extends MovieClip{

		public function Demo3() {
			trace("hello");
			init();
		}
		private var speed:Number=5;
		private function init():void{

			rect.buttonMode = true;
			rect.addEventListener(Event.ENTER_FRAME,loop);
		}
		private function loop(e:Event):void{
			if((rect.x+rect.width/2)>stage.stageWidth)
			{
				rect.x = stage.stageWidth - rect.width/2;
				speed *= -1;
			}
			if((rect.x - rect.width/2)<0){
				rect.x = rect.width/2;
				speed *= -1;
			}
			rect.x+=speed;
		}

	}

}

如果我们在舞台上只保留一帧,然后把init()函数里的代码和loop函数复制到帧代码中,效果也是一样的。

为AS导出的代码

2.5codeManage

Flash IDE的元件属性面板中有一个”为外部类导出”的选项,勾选这个选项后,我们可以为这个元件指定一个外部类。这个外部类可以文档类没有什么差别,只不过它绑定到的是一个元件而不是Flash文件。

这个外部类的代码就像是只有一帧的元件里的代码,这一点跟文档类与基于舞台时间轴的代码的关系是一样的。因此基于元件时间轴的代码,用导出的外部类来实现的话,这个类的代码应该如下(请参考源码Demo4):

package  {
	import flash.display.MovieClip;
	import flash.events.Event;

	public class Demo4 extends MovieClip{

		public function Demo4() {
			init();
		}
		private var speed:Number=5;
		private function init():void{

			this.buttonMode = true;
			this.addEventListener(Event.ENTER_FRAME,loop);
		}
		private function loop(e:Event):void{
			if((this.x+this.width/2)>stage.stageWidth)
			{
				this.x = stage.stageWidth - this.width/2;
				speed *= -1;
			}
			if((this.x - this.width/2)<0){
				this.x = this.width/2;
				speed *= -1;
			}
			this.x+=speed;
		}

	}

}

 总结

通过上面的学习,我们可以发现基于时间轴的代码和外部类并不是完全不同的,我们可以用下面这张图来理解他们之间的关系。

2.6codeManage

文档类对应基于舞台时间轴的代码,但两者不可以同时使用,即舞台时间轴上编写了代码,就不可以再使用文档类,反之亦然。
外部导出的类对应基于元件时间轴的代码,同样两者不可以同时使用。

但是文档类可以引用时间轴上有代码的元件,舞台时间轴上的代码同样可以引用外部导出的类,我们可以根据实际需求,灵活的进行搭配运用。

下载源文件

联系作者

公众号:拉小登 | 微博:拉登Dony | B站:拉小登Excel

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注