[此文来源于互联网,牛C网只负责收集整理]

Flash高级教程,制作XML加载图片示例,而且还带分页效果。

XML图片加载示例,带分页效果:

//=========初始化==========
//页数,默认0表示第一页
var curPage_num:Number = 0;
//每页容量
var sizPage_num:Number = 15;
//每排张数
var pai_num:Number = 5;
//图片宽度、高度
var width_num:Number = 80;
var height_num:Number = 80;
//图片与图片之间的间隔
var jia_num:Number = 20;
//=============================
var url_array:Array = new Array();
this.pagedown_btn._visible = false;
this.pageup_btn._visible = false;
//=========透明函数========
function alpha_func(_mc:MovieClip) {
_mc._alpha = 5;
_mc.onEnterFrame = function() {
  this._alpha  = 5;
  this._alpha>=95 ? delete this.onEnterFrame : 闪吧;
};
}
//============MCL类===========
var _mcl:MovieClipLoader = new MovieClipLoader();
this.onLoadInit = function(_mc:MovieClip) {
_mc._txt.removeTextField();
_mc._width = 80;
_mc._height = 80;
alpha_func(_mc);
};
//=========加载进度显示==============
this.onLoadProgress = function(_mc:MovieClip, bytesLoaded:Number, bytesTotal:Number) {
_mc.createTextField("_txt", 200, 20, 10, 60, 30);
_mc._txt.textColor = 0xff0000;
_mc._txt.text = Math.floor((bytesLoaded/bytesTotal*10000)/100) "%";
};
//=========加载错误提示==============
this.onLoadError = function(_mc:MovieClip) {
_mc.createTextField("_txt", 200, 20, 10, 60, 30);
_mc._txt.textColor = 0xff0000;
_mc._txt.text = "加载失败!";
};
_mcl.addListener(this);
//===========XML加载============
var url_xml:XML = new XML();
url_xml.ignoreWhite = true;
url_xml.onLoad = function(success) {
if (success) {
  for (var d:Number = 0; d<this.firstChild.childNodes.length; d  ) {
   url_array.push(this.firstChild.childNodes[d].attributes.name);
  }
  enabled_func();
} else {
  trace("xml文档加载失败!");
}
};
url_xml.load("xml/img.xml");
var show_func:Function = function (_page:Number) {
for (var d:Number = 0; d<sizPage_num; d  ) {
  //attachMovie("pic_mc", "pic_mc" d, d 1000, {_x:20 Math.floor(d/Math.floor(Math.sqrt(sizPage_num)))*100, _y:20 d%Math.floor(Math.sqrt(sizPage_num))*100});
  attachMovie("pic_mc", "pic_mc" d, d 1000, {_x:20 d%pai_num*(height_num jia_num), _y:20 Math.floor(d/pai_num)*(width_num jia_num)});
}
for (var d:Number = 0; d<sizPage_num; d  ) {
  if (_page*sizPage_num d<=sizPage_num) {
   this.pageup_btn.enabled = false;
  } else if (_page*sizPage_num d == url_array.length-1) {
   this.pagedown_btn.enabled = false;
  } else if (_page*sizPage_num d>=url_array.length) {
   break;
  } else {
   this.pageup_btn.enabled = true;
   this.pagedown_btn.enabled = true;
  }
  _mcl.loadClip(url_array[_page*sizPage_num d], this["pic_mc" d]);
}
};
function enabled_func() {
this.pagedown_btn._visible = true;
this.pageup_btn._visible = true;
show_func(curPage_num);
this.pagedown_btn.onRelease = function() {
  if (curPage_num<Math.floor(url_array.length/sizPage_num)) {
   curPage_num  ;
   show_func(curPage_num);
  }
};
this.pageup_btn.onRelease = function() {
  if (curPage_num>0) {
   curPage_num--;
   show_func(curPage_num);
  }
};
}

同时附带另一个源文件,图片依次加载效果(也就是加载完一个接着加载下一个)。以上两个实例都是在经典论坛回贴时做的,用了人家现成的图片,虽不算什么特别的东东,但AS是我原创。

源文件下载:XML加载图片分页.rar

      图片依次加载.rar
    
[此文来源于互联网,牛C网只负责收集整理]

在Flash MX的时候开始,就经常有人问为什么Flash载入的中文会是乱码?

后来大家都用了 System.useCodePage=true; 去解决这个问题。

可能大家都已经习惯了在Flash 5或以前,Flash完全没有理会编码时候吧。

大家都可能觉得,我在Flash5的时候可以很容易的载入外部文本,可以很容易的跟PHP, ASP等等的后台程序作信息交互。但是到了Flash MX的时候,同样的方法却出现了乱码。一定要在前面加上System.useCodePage=true;才可以解决问题。大家可能都会觉得这是Flash的问题,觉得Flash MX的中文支持能力差了。但是,事实却刚刚相反。Flash MX, Flash 2004这些版本对编码的支持觉得是比Flash5好的。(废话,Flash5都没有任何编码的问题)大家可能对我的话有所怀疑,这不要紧,下面就让我说明一下吧。

大家都知道我们国家就已经有两种不同的编码了,分别是香港,台湾的BIG5和我们内地的GB2312。在Flash 5或以前,Flash完全没有理会编码问题,所有在Dynamic/Input Textfield显示的中文字,Flash是根据浏览者系统预设编码去显示。香港一般用Big5去编码文字,而大部分人都是用繁体中文Windows,所以一拍即合,可以显示到中文。对于英文或简体中文Windows浏览者,他们就无法显示到Dynamic/Input Textfield上的Big5编码繁体中文。以前的英文Windows用户,经常要靠外挂中文程式,例如:南极星或Richwin看中文网页,可惜这类软件对Flash里的中文字无法起作用,依旧是乱码。

但是从Flash MX开始,Flash就开始支持Unicode编码。

Unicode

Unicode能够支持多国不同文字在同一套编码架构中,所以能够在同一篇文章中,同时显示繁简体中文字和其他文字。Flash 6(Flash MX)开始支持Unicode,并将Flash Player 6或以上预设编码为Unicode(如果播放Flash 5的SWF就仍然是根据浏览者系统预设编码去显示),新手不知道这转变,动态载入外部档案,例如:

loadVariablesNum("text.txt", 0);

text.txt这档案里的中文用Big5编码,Flash Player 6则用Unicode,结果当然是显示乱码。

解决方法有两个:一、强迫Flash使用“Flash 5原来编码方法”,在Frame 1加入指令:

System.useCodepage = true;

如果整个SWF都是使用“Flash 5原来编码方法”,就只需在Frame 1开始加一次便可。

服务端编程:

1.PHP/ColdFusion的开发者

请把你的PHP/ColdFusion存为UTF-8编码。

文本:文件->另存为->编码->UTF-8

DW2K4:File->New->Preference...->Default encoding->UTF-8

2.ASP的开发者

请把你的ASP存为UTF-8编码。

文本:文件->另存为->编码->UTF-8

DW2K4:File->New->Preference...->Default encoding->UTF-8

然后在顶上多加

<%@ codepage=65001 %>

就可以了

在Flash里面请 加入

System.userCodePage=true;

加了这指令之后,Flash对Unicode的文件将会显示为乱码。也就是说,你不能用Unicode编码了。如果不用utf-8编码,对于gb2312编码来说,是可以部分兼容繁体中文和一些日文编码的, 那是因为gb2312里面已经包括了这些编码,即所谓的gbk大字符集。这就让很多使用System.userCodePage的人觉得只要默认编码为gb2312,就可以做到解决编码问题。我在原先做的时候也是这样误解的,那是因为我没有测试别的语言,比如韩文。后来试了韩文之后,发现输入到数据库中的文字都变成了%#5234;%#1243;这样子的乱码。原来这些特殊语言的编码在gb2312里找不到,所以就被转成了字节编码。所以,如果你只是想让繁体和简体之间没有编码问题,那只需使用gb2312编码就足够了,ie会帮你转换big5到gb2312。而如果要适应更多语言的浏览器,那么,你就必须使用万国码unicode。不过值得注意的是, 某些数据库不支持unicode。比如早些的mysql,现在的mysql已经支持了。这就需要强行转换编码,可以使用urlencode编码,或者base64也行。读取的时候再反编码回unicode。还有要注意的地方, 就是flash里面的文本框字体不能再用宋体了。而是需要用公用字体,比如Arial。因为别的语言并没有宋体。

    

Flash Actionscript Animation简明教程

Category : Flash技术 | Post on 2007/07/18 21:54 by gdgzboy | Comments:0
[此文来源于互联网,牛C网只负责收集整理]

本教程节选自bit-101.com的未正式出版的新书making things move的新书介绍。主要内容是关于速度,加速度,弹性,缓动,摩擦力,重力等内容,这里没有非常详尽的内容,如果你想知道更详尽的内容,可以预定购买作者的新书making things move…相信一定是一本好书。引用keith peters的话就是你一定不要直接将代码粘过来用,只有理解了它的应用,才能运用自如。在本教程中本人对大部分内容进行了扩展讲解。希望对于初学或中级用户有所帮助,由于多年没有研究过数学物理,难免有误,希望多多指正。

1.速度

物体的运动都是沿着一定的方向,以恒定或是加速度的方式的运动的。在FALSH中要使物体以一个恒定的速度运动,就需要我们在每一帧不断的累加恒定的速度。这里面我们使用一种帧的循环的方式,来使物体不断的累加恒定的速度,以达到目的地。对于帧的循环方式大致上有三种,一种是使用代码onEnterFrame,一种是使用setInterval,另一种就是使用二到三帧来达到循环,如果你对这三种方式不太熟,请查看帮助来学习。

在x轴方向的速度我们定义为vx,方向是向右,如果向左只要设为负值就可以。 代码:

vx=5;  
onEnterFrame=function(){  
my_mc._x =vx;//你也可以写成my_mc._x=my_mc._x vx;  
}
演示:a0001.swf

我们发现MC以恒定为5的速度向右移动,如果想要它向左移,只要将vx设为负值即可。通过上面的代码我们可以变通一下,如果想使小球上下移动,可以设置y轴上移动。代码如下:
vy=5;  
onEnterFrame=function(){  
my_mc._y =vy;//你也可以写成my_mc._y=my_mc._y vy;  
}
这里就不再做演示了。你可以自已试一下,看看你是否理解了。

下面,我们再变通一下,在物理中有一个概念叫合速度,也就是x轴和y轴方向上的合速度。下面我们就来看一下,你可能已经知道了我在说什么。下面来看一下代码:最好你能在看下面代码之前自已写出来。代码:
vx=5;  
vy=5;  
onEnterFrame=function(){  
my_mc._x =vx;  
my_mc._y =vy;  
}
演示:a0002.swf

演示发现它已经沿着x,y合速度的方向移动了。是不是决得很容易。J这里我用的vx,vy都是5,也就是说合速度的方向是45度,当然你可以让vx,vy为不同的值,会有不同的速度也会沿不同的方向移动,如果反向,自然设置vx,vy为负值即可。

上面的学习如果你认为很容易,那下面这段相信对你也不会有问题,刚才我们说到当设置vx,vy都相同时,它是以45度的合速度方向运动的。虽然设置不同的值可以代表不同的方向。但这种方法很不科学。我们可以动用我们的数学知识,来让物体按我们指定的特定的角度移动。这里需要复习一下我们的数学知识。
(1)    弧度:弧度=角度*PI/180;
(2)    角度:角度=弧度*180/PI;
如果以指定的角度运动。那么这时的速度累加相当于沿着半径的方向。最终目的点是到达沿着半径方向的某一点。由于是合速度,我们需要定义一个统一个合速度以方便我们将x和y 轴上的速度分解出来为vx,vy。我们定义为speed;
那么在x轴方向上的速度应为:vx=Math.cos(radians)*speed;在y轴上的速度应为vy=Math.sin(radians)*speed;

代码:
speed=10;  
angle=15;  
radians=angle*Math.PI/180;  
onEnterFrame=function(){  
vx=Math.cos(radians)*speed;  
vy=Math.sin(radians)*speed;  
my_mc._x =vx;  
my_mc._y =vy;  
}
演示:a0003.swf

通过演示你已经发现小球已经沿着15度的方向移动了。这样angle相当是一个接口参数,你可以任意的对小球的方向进行控制。

2.加速度
经过上面的学习已经对速度应用有了一些了解,下面我们看一下加速度。在物理中的加速度有一个公式如:vt=vo at在FLASH中应用基本上与些公式类似,只是省去了一些细节如时间。细分析时间并没有省去,而是通过时间轴来代替了。这里我们加速度为ax,那么在x轴上速度一般写成vx=vx ax,简写成vx =ax;我们把初速度设为0;

代码:
ax=0.2;  
vx=0;  
onEnterframe=function(){  
vx =ax;  
my_mc._x =vx;  
}
演示:a0004.swf

那么同样道理,我们需要变通一下,另外个人的一点小观点,要善于提出问题,并努力想办法自已去解决,有助于你快速的学习进步。我们在y轴也加上加速度。
代码:
ax=0.2;  
ay=0.1;  
vx=0;  
vy=0;  
onEnterFrame=function(){  
vx =ax;  
vy =ay;  
my_mc._x =vx;  
my_mc._y =vy;  
}
演示:a0005.swf

通过演示我们发现小球已沿着合速度方向加速运行,现在问题又来了,如何使我们能按指定的角度加速运行呢。这个就当一个小作业吧。看你是否理解了它的应用。你可以结合前面的例子试一下。

3.重力

重力实际上就是加速度,但它有一个特殊性是只做用在y轴上,这里我们把重力定义成grav,与上面的加速度类似。
代码:
grav=0.5  
vy=0;  
onEnterFrame=function(){  
vy =garv;  
my_mc._y =vy;  
}
演示:a0006.swf

4.弹性

弹性,一般是指物体接触到到某个边界,所进行的回弹,在FLASH中,我们需要做的是设置好边界,以及物体回弹的方向。那么如何确定它回弹的方向呢,我们设定一个边界,当小球超出边界时小球回弹,也就是方向改变了。以x轴为例应为:vx*=-1;实际上你可能发现它实际上就是vx=-vx;

代码:
//设定边界  
top=0;  
left=0;  
right=400;  
bottom=300;  
vx=10;  
vy=10;  
onEnterFram=function(){  
my_mc._x =vx;  
my_mc._y =vy;  
//下面代码检测小球是否到达边界,如果已到边界,重设小球的正确做坐,并使其回弹,  
if(my_mc._x my_mc._width/2>right){  
  my_mc._x=right-my_mc._width/2;  
  vx*=-1;  
}  
if(my_mc._x-my_mc._width/2<left){  
my_mc._x=left mc_mc._width/2;  
vx*=-1;  
}  
if(my_mc._y-my_mc._height/2<top){  
my_mc._y=top my_mc._height/2;  
vy*=-1;  
}  
if(my_mc._y my_mc._height/2>bottom){  
my_mc._y=bottom-my_mc._height/2;  
vy*=-1;  
}  
}
演示:a0007.swf

通过演示我们发现小球在碰到边界会不断的回弹。
*注意:上面代码中的my_mc._x,my_mc._y的坐标都是指my_mc的中心点,也就是说my_mc的注册点在中心,如果你在制作过程中发现与本演示不同,那一定是你的my_mc注册点没有在中心上。

弹性中的能量损失

在上面的例子,小球在回弹时我们设定当碰到边界时直接回弹,也就是vx*=-1;并没有能量的损失,但在现实生活中,小球在回弹时要有一定的能量损失,其中还要有重力加速度的影响,通过上面的例子我们可以得出结论,当回弹速度设为1时无能量损失,其中的负号只是代表方向,当小于1时会产生能量损失,也就是我们通常说的摩擦,如:vx*=-0.8;同时不要忘了在现实生活小球还会受重力加速度的影响。

代码:
top=0;  
left=0;  
right=400;  
bottom=300;  
//设定重力加速度变量garv  
garv=.5;  
vx = 10;  
vy = 10;  
onEnterFrame = function () {  
//y轴方向的加速度  
    vy =garv;  
    my_mc._x  = vx;  
    my_mc._y  = vy;  
    if(my_mc._x my_mc._width/2>right){  
        my_mc._x=right-my_mc._width/2;  
        vx*=-0.8;  
    }  
    if(my_mc._x-my_mc._width/2<left){  
        my_mc._x=left my_mc._width/2;  
        vx*=-0.8;  
    }  
    if(my_mc._y-my_mc._height/2<top){  
        my_mc._y=top my_mc._height/2;  
        vy*=-0.8;  
    }  
    if(my_mc._y my_mc._height/2>bottom){  
        my_mc._y=bottom-my_mc._height/2;  
        vy*=-0.8;  
    }  
};

演示:a0008.swf

5.摩擦力

摩擦力的应用相对比较简单,我们需要定义一个摩擦系数,通常它的值为小于1,然后将它与速度相乘,也就是前面在弹性时所提到的能量损失。代码:

fraction=0.95;  
vx=10;  
vy=10;  
onEnterFrame=function(){  
vx*=fraction;  
vy*=fraction;  
my_mc._x =vx;  
my_mc._y =vy;  
}

演示:a0009.swf

6.拖动与抛

   拖动与抛实际是与上面的例子的结合应用,这里只是说明如何与上面相结合使用。在本例中我们想要在拖动小球的小球停止运动,松开或抛出时小球继续运动,在制作之前,我们先看一下基础知识:
   要点:拖动我们使用方法startDrag(),同时要禁止小球运动,当拖动时要注意小球的运动速度变化,松开时,使用方法stopDrag(),同时重置速度,然后小球继续运动。

代码:

top=0;  
left=0;  
right=400;  
bottom=300;  
garv=.5;  
vx = 10;  
vy = 10;  
onEnterFrame = function () {  
//设定如果没有拖动则小球正常进行带有能量损失的弹性运动  
    if(!dragging){  
    vy =garv;  
    my_mc._x  = vx;  
    my_mc._y  = vy;  
    if(my_mc._x my_mc._width/2>right){  
        my_mc._x=right-my_mc._width/2;  
        vx*=-0.8;  
    }  
    if(my_mc._x-my_mc._width/2<left){  
        my_mc._x=left my_mc._width/2;  
        vx*=-0.8;  
    }  
    if(my_mc._y-my_mc._height/2<top){  
        my_mc._y=top my_mc._height/2;  
        vy*=-0.8;  
    }  
    if(my_mc._y my_mc._height/2>bottom){  
        my_mc._y=bottom-my_mc._height/2;  
        vy*=-0.8;  
    }  
//如果有拖动,则此时速度发生了变化,需要记录下最后my_mc的位置和当前my_mc的位置,两者的差为当前的速度。  
    }else{  
        vx=my_mc._x-oldx;  
        vy=my_mc._y-oldy;  
        oldx=my_mc._x;  
        oldy=my_mc._y;  
    }  
              
};  
my_mc.onPress=function(){  
    this.startDrag();  
    dragging=true;  
}  
my_mc.onRelease=function(){  
    this.stopDrag();  
    dragging=false;  
}

演示:a0010.swf

7.easing缓动
                          
简单的easing方式,需要我们选择目的地,然后以摩擦的形式达到目的点。这就是easing.如果想要更复杂的easing方式,可以参看www.robertpenner.com,当然你也可以使用现在网站各种各样的类。或是使用mm自带的transition类或是tween类。

代码:

targetx = 200;  
targety = 150;  
onEnterFrame = function () {  
    dx=targetx-my_mc._x;  
    dy=targety-my_mc._y;  
    my_mc._x =dx*.3;  
    my_mc._y =dy*.3;  
      
};

演示:a0011.swf

8.Spring弹簧

spring非常类似于easing,但它的效果比easing更cool。一般的方法为定义一个目标点,计算出到它的距离,加速度为距离与摩擦系数的积,同时还需要使用摩擦。

代码:

var targetx = 200;  
var targety = 150;  
fraction = .9;  
vx = 0;  
vy = 0;  
onEnterFrame = function () {  
    if (!dragging) {  
        //起始点与目标地点的距离  
        dx = targetx-my_mc._x;  
        dy = targety-my_mc._y;  
       //加速度  
        vx  = dx*.3;  
        vy  = dy*.3;  
       //加入摩擦  
        vx *= fraction;  
        vy *= fraction;  
        my_mc._x  = vx;  
        my_mc._y  = vy;  
    }  
};  
my_mc.onPress = function() {  
    this.startDrag();  
    dragging = true;  
};  
my_mc.onRelease=function() {  
    this.stopDrag();  
    dragging = false;  
};

演示:a0012.swf

spring 与鼠标相连

下面我们要对spring 进行一下简单的扩展,我们可以将目标地点设为光标的坐标值,同时可以使用drawing api用画线的方式将其相连起来。
代码:

var targetx = 200;  
var targety = 150;  
fraction = .9;  
vx = 0;  
vy = 0;  
onEnterFrame = function () {  
    dx = _xmouse-my_mc._x;  
    dy = _ymouse-my_mc._y;  
    vx  = dx*.3;  
    vy  = dy*.3;  
    vx *= fraction;  
    vy *= fraction;  
    my_mc._x  = vx;  
    my_mc._y  = vy;  
    //画线与mouse相连  
    clear();  
    lineStyle(1,0,100);  
    moveTo(_xmouse,_ymouse);  
    lineTo(my_mc._x,my_mc._y);  
};  

演示:a0013.swf

现在我们在变通一下,小球在自然界中是有重力的。加上重力看看什么效果。一个小作业,你试一下。

Spring 链

最后我们来一个稍微难一点的,是上面例子的一个扩展,如果你对上一个例子有了一定的理解,这个对你来说是不成问题的。上面的例子是跟随着光标,如果是链的话。那么第二个小球就应跟随第一个小球,依次类推。如果这个你难做出来。相信这种类型的菜单对你来说就不成问题了。J
代码:

fraction = .7;  
grav=20;  
my_mc.vx = 0;  
my_mc.vy = 0;  
my_mc1.vx = 0;  
my_mc1.vy = 0;  
my_mc2.vx = 0;  
my_mc2.vy = 0;  
onEnterFrame = function () {  
    clear();  
    lineStyle(1, 0, 100);  
    moveTo(_xmouse, _ymouse);  
    spring(my_mc, _xmouse, _ymouse);  
    spring(my_mc1, my_mc._x, my_mc._y);  
    spring(my_mc2, my_mc1._x, my_mc1._y);  
};  
function spring(mc, x, y) {  
    dx = x-mc._x;  
    dy = y-mc._y;  
    mc.vx  = dx*.3;  
    mc.vy  = dy*.3;  
    mc.vy  = grav;  
    mc.vx *= fraction;  
    mc.vy *= fraction;  
    mc._x  = mc.vx;  
    mc._y  = mc.vy;  
    lineTo(mc._x, mc._y);  
}

演示:a0014.swf

总结:上面的教程看起来都是一些简单的东西,但它确确实实是一些好的框架,你可无限的发挥你的想象和创意,只要在这个框架之中添加一些元素或是代码。写这篇教程的目的主要是针对初级和中级的用户。目的是使大家意识到其实许多表面看起来复杂的东西,实际上都隐藏着相对复杂的简单,前提条件是你的思路一定要清晰。最后。仍要引用keith peters话。不要直接下载源文件或是直接粘贴代码。最好的方式是理解。

    
[此文来源于互联网,牛C网只负责收集整理]

Flash实现输入对方QQ号回车即可直接聊天

直接复制以下代码,场景大小设置成80*22,只访问网络,就可以输入对方QQ号,回车之后,即可直接聊天了。

//===========屏闭菜单============
fscommand("showmenu", false);
//===========创建文本格式======
var txt_fmt:TextFormat = new TextFormat();
txt_fmt.size = 16;
txt_fmt.bold = true;
txt_fmt.color = Math.random()*0xffffff;
//===========创建输入QQ号的文本======
var QQ_txt:TextField = this.createTextField("QQ_txt", 2, 0, 0, 80, 22);
QQ_txt.border = true;
QQ_txt.type = "input";
QQ_txt.restrict = "0-9";
QQ_txt.maxChars = 9;
//===========创建输入QQ号的文本======
QQ_txt.setNewTextFormat(txt_fmt);
//===========回车动作设置======
this.onKeyDown = function() {
//======如果回车时QQ号大于5位就打开面板======
if (Key.getCode() == 13 && QQ_txt.text.length>=5) {
  getURL("tencent://message/?uin=" QQ_txt.text);
}
};
//======QQ输入文本框得到焦点时,注册键盘帧听======
QQ_txt.onSetFocus = function() {
Key.addListener(this._parent);
};
//======QQ输入文本框失去焦点时,卸载键盘帧听======
QQ_txt.onKillFocus = function() {
Key.removeListener(this._parent);
};

    
    

I spent some time improving the Salesbuilder Flex / AIR demo application I posted a couple of weeks ago. This version is a lot more complete and polished than the initial incarnation of the application.

Salesbuilder is a Sales Force Automation application that demonstrates local persistence using the embedded SQLite database, data synchronization, native drag-and-drop, and other features such as direct chart manipulation.

First, I got help from our Experience Design team (special thanks to Ethan Eismann): this is still work in progress, but the design has already been improved significantly.

salesbuilder1.png
salesbuilder2.png
salesbuilder3.png
salesbuilder4.png

I also added a number of new features. For example, you can now create and edit sales opportunities, use the menu bar buttons to access summary screens, etc. One interesting new feature is the direct manipulation options available in the Sales Pipeline bubble chart, and in particular the way data visualization turns into data manipulation/data entry: drag bubbles up, down, left or right to adjust the probability and the expected closing date. The new values are automatically saved to the database.

Click here to install the application.

Follow this guided tour to make sure you don’t miss any new feature.


Tags: ,

Flash AS2 事件处理机制 不指定

Category : Flash技术 | Post on 2007/07/13 11:21 by gdgzboy | Comments:0
[此文来源于互联网,牛C网只负责收集整理]
本教程中你将学习下面的内容:

       1.事件处理机制.
       2.创建类库.
       3.使用 回调函数.
              3.1.示例: CFEventClass 类(简单的示例).
              3.2.示例: CFTimer 类(定时器).
       4.使用 addListener 方法(AsBroadcaster / BroadcasterMX 类).
              4.1.示例: AsBEventClass 类(简单的示例).
              4.2.示例: AsBTimer 类(定时器).
       5.使用 addEventListener 方法(EventDispatcher 类).
              5.1.示例: EDEventClass 类(简单的示例).
              5.2.示例: EDTimer 类(定时器).
       6.建立强大的事件处理机制.
              6.1.创建 CFDelegate 类(修改 Delegate 类).
              6.2.创建 CFEventDispatcher 类(修改 EventDispatcher 类).
              6.3.创建 Event 类(事件基类,继承 Object 类).
              6.4.创建 IOErrorEvent 类(错误事件类,继承 Event 类).
              6.5.创建 HTTPStatusEvent 类(http状态事件类,继承 Event 类).
              6.6.示例: EventClass 类(简单的示例).
              6.7.示例: Timer 类(定时器,功能跟 AS3 中的 Timer 类一样).
       7.小结.

源文件(LRC 和 CFSound 类也在这):Flash Class Library.rar

[1.事件处理机制]

AS2 的事件处理机制并不完美.形态多样.不易于管理.在这里可以解决此问题的一半.本文会先了解和使用
AS2 中基本的事件处理机制.然后建立强大的事件处理机制.来方便管理自己的程序.下面讲解.

形态多样的事件处理机制(后面会详细的讲解):
1.回调函数.(如 onLoad, onHTTPStatus 等)
2.使用 addListener 方法. (如 onLoadStart, onLoadInit 等)
3.使用 addEventListener 方法. (如 click, change 等)

它们的作用域和形态(代码):
作用域是指标识符(如常量、数据类型、变量或例程)在程序内可被引用的范围.
1.this 指向触发此事件的对象

object.onLoad = function()
{
    trace(this); //输出: object
}

2.this 指向侦听器对象

var listenerObject:Object = {};
listenerObject.onLoadStart = function()
{
    trace(this); //输出: listenerObject
}
broadcasterObject.addListener(listenerObject);

3.使用侦听器对象:this 指向侦听器对象

var listenerObject:Object = {};
listenerObject.click = function(evt:Object)
{
    trace(this); //输出: listenerObject
}
broadcasterObject.addEventListener("click", listenerObject);

使用函数:this 指向触发此事件的对象

function clickHandler(evt:Object):Void
{
    trace(this); //输出: broadcasterObject
}
broadcasterObject.addEventListener("click", clickHandler);

有时我们需要更改它们的作用域怎么办?
想要改变它们的作用域,需使用 Delegate 类的 create 方法.
此类的全路径: mx.utils.Delegate;
用法: Delegate.create(要运行函数的范围, 函数);
例:
1.this 指向 _level0

import mx.utile.Delegate;
object.onLoad = Delegate.create(this, _onLoad);
function _onLoad():Void
{
    trace(this); //输出: _level0
}

2.this 指向 _level0

import mx.utile.Delegate;
var listenerObject:Object = {};
listenerObject.onLoadStart = Delegate.create(this, loadStart);
function loadStart():Void
{
    trace(this); //输出: _level0
}
broadcasterObject.addListener(listenerObject);

3.
使用侦听器对象:this 指向 _level0

import mx.utile.Delegate;
var listenerObject:Object = {};
listenerObject.click = Delegate.create(this, clickHandler);
function clickHandler(evt:Object)
{
    trace(this); //输出: _level0
}
broadcasterObject.addEventListener("click", listenerObject);

使用函数:this 指向 _level0

function clickHandler(evt:Object):Void
{
    trace(this); //输出: _level0
}
broadcasterObject.addEventListener("click", Delegate.create(this, clickHandler));

事件对象:
它包含两个基本属性:
type:String              事件名.
target:Object       事件源.此属性可以不指定,默认为事件源(调用dispatchEvent方法的对象).
此对象传递给 EventDispatcher 类的 dispatchEvent 方法并作为参数传递到侦听器.
例:

//发送事件.
dispatchEvent({type:"click", target:this});
//事件处理函数.
function clickHandler(evt:Object):Void
{
    trace([evt.type, evt.target]);  
}
//添加事件侦听器.
addEventListener("click", clickHandler);

下一节讲:[2.创建类库]

在开始下面的教程之前.先要创建类库.在硬盘中创建如图结构的文件目录:

Flash AS2 事件处理机制


Classes 目录是用来存放类文档.
Example 目录是用来存放示例文档.
创建好后还需要在 Flash 中添加类路径:
Flash 8: 编辑-->首选参数-->ActionScript-->ActionScript 2.0 设置-->添加( )-->浏览到 Flash Class Library/Classes 目录.
Flash AS2 事件处理机制

Flash CS3: Edit-->Preferences-->ActionScript-->ActionScript 2.0 Settings-->Add New Path( )-->Browse To Flash Class Library/Classes 目录.
ActionScript 3.0 也要添加(在后续文章中会用到).
Flash AS2 事件处理机制

下一节讲: [3.使用 回调函数]

[3.使用 回调函数]

回调函数也可以说是匿名函数,先看下面的代码:

var myXML:XML = new XML();
myXML.load("xml.xml");
myXML.onLoad = function(success:Boolean)
{
    trace(success);
}

XML.onLoad 是一个回调函数.将匿名函数与特定的事件关联,以创建回调函数.函数将在特定事件发生后调用回调函数.
在自定义类中怎么做呢?看下面的示例.

[3.1.示例: CFEventClass 类(简单的示例)]
此示例文档详细:
Example/AS2/events/CFEvent/CFEventClass.as                            
Example/AS2/events/CFEvent/CFEventExample.as                    
Example/AS2/events/CFEvent/CFEventExample.xml                    
Example/AS2/events/CFEvent/CFEventExample.fla                    

主类:
打开 CFEventClass.as  文档,输入下面的代码:

import mx.utils.Delegate;
//----------------------------------------
class CFEventClass
{
    //----------------------------------------
    public var tXML:XML;
    //定义事件函数.
    public var complete:Function;
    //----------------------------------------
    public function CFEventClass(url:String)
    {
        this.tXML = new XML();
        this.tXML.onLoad = Delegate.create(this, this.XMLonLoad);
        this.tXML.load(url);
    }
    private function XMLonLoad(success:Boolean):Void
    {
        if (success) {
            //执行事件函数.
            this.complete();
        }
    }
    //----------------------------------------
}

保存文档,这样我们就创建了一个名为 CFEventClass 的类,拥有一个事件,一个属性,此事件在 XML 文档成功加载后发生.

示例类:
打开 CFEventExample.as 文档,输入下面的代码:

import CFEventClass;
//----------------------------------------
class CFEventExample
{
    public function CFEventExample()
    {
        var ee:CFEventClass = new CFEventClass("CFEventExample.xml");
        ee.complete = this.complete;
    }
    private function complete():Void
    {
        trace("complete");
    }
}

保存文档.
在示例类中我们创建主类的一个实例.来加载 CFEventExample.xml 文档.然后使用自定义函数与 complete 事件关联.
如果要移除事件,请使用下面的方法:

ee.complete = undefined
//或
ee.complete = null;
//或
delete ee.complete;

要加载的 XML 文档:
打开 CFEventExample.xml 文档,随便输入一些内容便可.测试用.

示例 fla 文档:
打开 CFEventExample.fla 文档.将"图层 1"重命名为  Actions.并在第一帧中输入下面的代码:

new CFEventExample();

保存文档.
测试 Flash 文档.在 XML 文档成功加载后会在输出面板中显示以下内容

complete

如需给事件传递参数,在执行事件函数时如下添加参数:

this.complete(参数1, 参数2, 参数N);

在调用事件时:

private function complete(参数1, 参数2, 参数N)
{
    trace([参数1, 参数2, 参数N]);
}

下面再看一个示例:

[3.2.示例: CFTimer 类(定时器)]
此示例文档详细:
Classes/AS2/utils/CFTimer.as
Example/AS2/utils/CFTimer/CFTimerExample.as
Example/AS2/utils/CFTimer/CFTimerExample.fla

主类:
打开 CFTimer.as 文档,输入下面的代码:

import mx.utils.Delegate;
//----------------------------------------
class AS2.utils.CFTimer
{
    //----------------------------------------
    private var _timerID:Number;
    private var _delay:Number;
    private var _repeatCount:Number;
    private var _currentCount:Number = 0;
    private var _running:Boolean;
    //----------------------------------------
    public var timer:Function;
    public var timerComplete:Function;
    //----------------------------------------
    /*
    @parameter    delay:            延迟,单位毫秒.
    @parameter    repeatCount:    重复的次数.默认为Infinity(正无穷大);
    */
    public function CFTimer(delay:Number, repeatCount:Number)
    {
        if (isNaN(delay)) {
            return;
        }
        if (isNaN(repeatCount)) {
            repeatCount = Infinity;
        }
        this._delay = delay;
        this._repeatCount = repeatCount;
    }
    //----------------------------------------
    public function reset():Void
    {
        this._currentCount = 0;
        this.stop();
    }
    public function start():Void
    {
        this._timerID = setInterval(CFDelegate.create(this, this.startTimer), this._delay);
        this._running = true;
    }
    public function stop():Void
    {
        clearInterval(this._timerID);
        this._running = false;
    }
    public function toString():String
    {
        return "[CFTimer]";
    }
    //----------------------------------------
    private function startTimer():Void
    {
        this._currentCount  ;
        this.timer(this._currentCount);
        if (this._currentCount == this._repeatCount) {
            this.reset();
            this.timerComplete();
        }
    }
    //----------------------------------------
    public function get delay():Number
    {
        return this._delay;
    }
    public function set delay(d:Number):Void
    {
        this._delay = d;
    }
    public function get repeatCount():Number
    {
        return this._repeatCount;
    }
    public function set repeatCount(r:Number):Void
    {
        this._repeatCount = r;
    }
    public function get currentCount():Number
    {
        return this._currentCount;
    }
    public function get running():Boolean
    {
        return this._running;
    }
    //----------------------------------------
}

保存文档.
此类的详细信息:
构造函数:
public CFTimer(delay:Number, repeatCount:Number)
参数:
delay:Number              ---延迟,单位毫秒.
repeatCount:Number       ---重复次数.默认为 Infinity(正无穷大);

方法:
public reset():Void                     ---停止定时.并复位 currentCount .
public start():Void                     ---开始计时.
public stop():Void                     ---停止定时.
public toString():String       ---返回类名称"[CFTimer]".

属性:
public delay:Number                                   ---延迟,单位毫秒.
public repeatCount:Number                      ---重复的次数.默认值为 Infinity(正无穷大);
public currentCount:Number [只读]       ---当前的次数.当开始计时,此值会递增,直到等于 repeatCount.
public running:Boolean           [只读]       ---定时器目前的状态,true 表示正在运行, false 表示已停止.

事件:
timer = function(currentCount:Number){}              ---每当时间间隔到达 delay 时调用.
timerComplete = function(){}                            ---当 currentCount 等于 repeatCount 时调用.

示例类:
打开 CFTimerExample.as 文档.输入下面的代码:

import AS2.utils.CFTimer;
//----------------------------------------
class CFTimerExample
{
    //----------------------------------------
    public function CFTimerExample()
    {
        var te:CFTimer = new CFTimer(1000, 5);
        te.timer = this.timer;
        te.timerComplete = this.timerComplete;
        te.start();
    }
    private function timer(currentCount:Number):Void
    {
        trace("timer: "   currentCount);
    }
    private function timerComplete():Void
    {
        trace("timerComplete: ");
    }
    //----------------------------------------
}

保存文档.
这里我们创建 CFTimer 类的一个实例, 时间间隔为 1000 毫秒,重复执行 5 次.然后实现 timer 和 timerComplete 事件.

示例 fla 文档:
打开 CFTimerExample.fla 文档,将"图层 1" 重命名为 Actions.并在第一帧中输入下面的代码:

new CFTimerExample();

测试 Flash 文档.输出面板会陆续显示以下的内容:

timer: 1
timer: 2
timer: 3
timer: 4
timer: 5
timerComplete:

下一节讲: [4.使用 addListener 方法(AsBroadcaster / BroadcasterMX 类)]

[4.使用 addListener 方法(AsBroadcaster / BroadcasterMX 类)]

在 MovieClipLoader 和 Tween 等类中都用到了 addListener 方法来注册侦听.
我们该怎么用呢? Macromedia 为我们提供了如下二个类:
AsBroadcaster 属于系统类.
BroadcasterMX 属于自定义类.类路径: mx.transitions.BroadcasterMX
这两个类的很相似.它们都是提供事件通知和侦听器管理功能.
但 AsBroadcaster 类是系统内置的.执行效率会比 BroadcasterMX 类快很多.所以这里我们就用 AsBroadcaster
类来讲解.
此类详细:
public addListener(listenerObj:Object):Boolean         ---注册侦听器.
public broadcastMessage(eventName:String):Void         ---广播消息/发送事件.
public static initialize(obj:Object):Void                ---将事件通知和侦听器管理功能添加到给指定的对象
public removeListener(listenerObj:Object):Boolean ---移除侦听器.
public _listeners:Array [只读]                                     ---对已注册侦听器对象的引用.

该怎么用呢? 看下面的示例:
[4.1.示例: AsBEventClass 类(简单的示例)]
此示例文档详细:
Example/AS2/events/AsBEvent/AsBEventClass.as
Example/AS2/events/AsBEvent/AsBEventExample.as
Example/AS2/events/AsBEvent/AsBEventExample.xml
Example/AS2/events/AsBEvent/AsBEventExample.fla

主类:
打开 CFEventClass.as  文档,输入下面的代码:

import mx.utils.Delegate;
//----------------------------------------
class AsBEventClass extends AsBroadcaster
{
    //----------------------------------------
    public var tXML:XML;
    //----------------------------------------
    public function AsBEventClass(url:String)
    {
        AsBroadcaster.initialize(AsBEventClass.prototype);
        this.tXML = new XML();
        this.tXML.onLoad = Delegate.create(this, this.XMLonLoad);
        this.tXML.load(url);
    }
    private function XMLonLoad(success:Boolean):Void
    {
        if (success) {
            this.broadcastMessage("complete");
        }
    }
    //----------------------------------------
}

保存文档.
这里首先继承 AsBroadcaster 类.然后在构造函数中使用

AsBroadcaster.initialize(AsBEventClass.prototype);

来获取事件通知和侦听器管理功能.最后使用

this.broadcastMessage("complete");

来广播消息或发送事件.
当然你也可以选择不继承它,但需要在类中添加下面的方法:

public var addListener:Function;
public var removeListener:Function;
private var broadcastMessage:Function;

示例类:
打开 CFTimerExample.as 文档.输入下面的代码:

import AsBEventClass;
//----------------------------------------
class AsBEventExample
{
    public function AsBEventExample()
    {
        var ee:AsBEventClass = new AsBEventClass("AsBEventExample.xml");
        ee.addListener(this);
    }
    private function complete():Void
    {
        trace("complete");
    }
}

保存文档.
在示例类中我们创建主类的一个实例.来加载 AsBEventExample.xml 文档.然后添加侦听器.
如果要移除侦听器,请使用下面的方法:

ee.removeListener(this);

要加载的 XML 文档:
打开 AsBEventExample.xml 文档,随便输入一些内容便可.测试用.

示例 fla 文档:
打开 AsBEventExample.fla 文档.将"图层 1"重命名为  Actions.并在第一帧中输入下面的代码:

new AsBEventExample();

保存文档.
测试 Flash 文档.在 XML 文档成功加载后会在输出面板中显示以下内容

complete

如需给事件传递参数,在发送事件时如下添加参数:

this.broadcastMessage("complete", 参数1, 参数2, 参数N);

在调用事件时:

private function complete(参数1, 参数2, 参数N)
{
    trace([参数1, 参数2, 参数N]);
}

下面再看一个示例:
[4.2.示例: AsBTimer 类(定时器)]
此示例文档详细:
Classes/AS2/utils/AsBTimer.as
Example/AS2/utils/AsBTimer/AsBTimerExample.as
Example/AS2/utils/AsBTimer/AsBTimerExample.fla

主类:
打开 AsBTimer.as 文档,输入下面的代码:

import AS2.utils.CFDelegate;
//----------------------------------------
class AS2.utils.AsBTimer extends AsBroadcaster
{
    //----------------------------------------
    private var _timerID:Number;
    private var _delay:Number;
    private var _repeatCount:Number;
    private var _currentCount:Number = 0;
    private var _running:Boolean;
    //----------------------------------------
    /*
    @parameter    delay:            延迟,单位毫秒.
    @parameter    repeatCount:    重复次数.默认为Infinity(正无穷大);
    */
    public function AsBTimer(delay:Number, repeatCount:Number)
    {
        AsBroadcaster.initialize(AsBTimer.prototype);
        if (isNaN(delay)) {
            return;
        }
        if (isNaN(repeatCount)) {
            repeatCount = Infinity;
        }
        this._delay = delay;
        this._repeatCount = repeatCount;
    }
    //----------------------------------------
    public function reset():Void
    {
        this._currentCount = 0;
        this.stop();
    }
    public function start():Void
    {
        this._timerID = setInterval(CFDelegate.create(this, this.startTimer), this._delay);
        this._running = true;
    }
    public function stop():Void
    {
        clearInterval(this._timerID);
        this._running = false;
    }
    public function toString():String
    {
        return "[AsBTimer]";
    }
    //----------------------------------------
    private function startTimer():Void
    {
        this._currentCount  ;
        this.broadcastMessage("timer", this._currentCount);
        if (this._currentCount == this._repeatCount) {
            this.reset();
            this.broadcastMessage("timerComplete");
        }
    }
    //----------------------------------------
    public function get delay():Number
    {
        return this._delay;
    }
    public function set delay(d:Number):Void
    {
        this._delay = d;
    }
    public function get repeatCount():Number
    {
        return this._repeatCount;
    }
    public function set repeatCount(r:Number):Void
    {
        this._repeatCount = r;
    }
    public function get currentCount():Number
    {
        return this._currentCount;
    }
    public function get running():Boolean
    {
        return this._running;
    }
    //----------------------------------------
}

因此类详细前面已讲,功能一样,只是事件处理机制不同而已.这里就不再啰嗦.

示例类:
打开 AsBTimerExample.as 文档.输入下面的代码:

import AS2.utils.AsBTimer;
//----------------------------------------
class AsBTimerExample
{
    //----------------------------------------
    public function AsBTimerExample()
    {
        var te:AsBTimer = new AsBTimer(1000, 5);
        te.addListener(this);
        te.start();
    }
    private function timer(currentCount:Number):Void
    {
        trace("timer: "   currentCount);
    }
    private function timerComplete():Void
    {
        trace("timerComplete: ");
    }
    //----------------------------------------
}

保存文档.

示例 fla 文档:
打开 AsBTimerExample.fla 文档,将"图层 1" 重命名为 Actions.并在第一帧中输入下面的代码:

new AsBTimerExample();

测试 Flash 文档.输出面板会陆续显示以下的内容:

timer: 1
timer: 2
timer: 3
timer: 4
timer: 5
timerComplete:

下一节讲:[5.使用 addEventListener 方法(EventDispatcher 类)]

[5.使用 addEventListener 方法(EventDispatcher 类)]


打瞌睡了吧? 貌似有口水流下来了.呵.本人文字表达能力不是很好(好像是没吃多少书).让大家见笑了.其实学编程
是比较闷的.不只是闷,还有很多很多,但既然选择了,这些就只是学习途中的坎,需要我们跨过去.就像是你选择走哪
条路一样,既然选择了,就必需是要走的.但这路不只是你一个人走,人多了就会有竞争,我们不能总走在别人后面.所
以需要加快脚步走在前面,让后面的人去追.但有时也会在不知不觉中走弯路,我一样也会,所以在本文中如果你看到
有不正确的,希望你能指正,谢谢.此文的目的是想让大家在这条路上能走快点.你很啰嗦呀....呵.题外话就说到这.
下面继续.

这一节讲 EventDispatcher 类.此类也是提供事件通知和侦听器管理功能的,但比前面讲的功能会强一些.在 AS2
中,此类用于组件的事件处理机制中.因 Macromedia 没有过多的讲解此类.很少人将它用于自定义类中.本人在研究
mx包下的类时才知道此类的用法.

首先看看在组件中如何使用:
1.

function clickHandler(evt:Object):Void
{
    trace("click");
]
button.addEventListener("click", clickHandler);

2.

function click(evt:Object):Void
{
    trace("click");
]
button.addEventListener("click", this);

3.

function handleEvent(evt:Object):Void
{
    trace("click");
]
button.addEventListener("click", this);

4.

button.clickHandler = function(evt:Object)
{
    trace("click");
}

这几种写法其效果都是一样的.都是侦听 button 实例的 click 事件.

下面来了解此类详细:
public addEventListener(eventName:String, 侦听器对象或函数):Void              ---添加事件侦听器
public removeEventListener(eventName:String, 侦听器对象或函数):Void              ---移除事件侦听器
public dispatchEvent(eventObj:Object):Void          object:Object):Void

帮助文档中没有讲解 initialize 方法.此方法的功能同 AsBroadcaster 类的 initialize 方法一样.

该怎么用呢? 看下面的示例:
[5.1.示例: EDEventClass 类(简单的示例)]
此示例文档详细:
Example/AS2/events/EDEvent/EDEventClass.as
Example/AS2/events/EDEvent/EDEventExample.as
Example/AS2/events/EDEvent/EDEventExample.xml
Example/AS2/events/EDEvent/EDEventExample.fla

主类:
打开 EDEventClass.as 文档,输入下面的代码:

import mx.utils.Delegate;
import mx.events.EventDispatcher;
//----------------------------------------
class EDEventClass extends EventDispatcher
{
    //----------------------------------------
    public var tXML:XML;
    //----------------------------------------
    public function EDEventClass(url:String)
    {
        this.tXML = new XML();
        this.tXML.onLoad = Delegate.create(this, this.XMLonLoad);
        this.tXML.load(url);
    }
    private function XMLonLoad(success:Boolean):Void
    {
        if (success) {
            this.dispatchEvent({type:"complete"});
        }
    }
    //----------------------------------------
}

如果不继承 EventDispatcher 类.请将代码改成如下:

import mx.utils.Delegate;
import mx.events.EventDispatcher;
//----------------------------------------
class EDEventClass
{
    //----------------------------------------
    //不继承需添加这三个方法.
    public var addEventListener:Function;
    public var removeEventListener:Function;
    private var dispatchEvent:Function;
    //----------------------------------------
    public var tXML:XML;
    //----------------------------------------
    public function EDEventClass(url:String)
    {
        //还有使用 initialize 静态方法.
        EventDispatcher.initialize(this);
        this.tXML = new XML();
        this.tXML.onLoad = Delegate.create(this, this.XMLonLoad);
        this.tXML.load(url);
    }
    private function XMLonLoad(success:Boolean):Void
    {
        if (success) {
            this.dispatchEvent({type:"complete"});
        }
    }
    //----------------------------------------
}

保存文档.
这里首导入 EventDispatcher 类,你可以选择继承或不继承此类.上面的代码一个是继承,一个是不继承.区别
也很容易看出来.这里就不讲了.

示例类:
打开 EDEventExample.as 文档,输入下面的代码:

import EDEventClass;
//----------------------------------------
class EDEventExample
{
    public function EDEventExample()
    {
        var ee:EDEventClass = new EDEventClass("EDEventExample.xml");
        ee.addEventListener("complete", this);
    }
    private function complete(evt:Object):Void
    {
        trace("complete");
    }
}

保存文档.
在示例类中我们创建主类的一个实例.来加载 EDEventExample.xml 文档.然后添加侦听器.
如果要移除事件侦听器,请使用下面的方法:

ee.removeEventListener("complete", this);

要加载的 XML 文档:
打开 EDEventExample.xml 文档,随便输入一些内容便可.测试用.

示例 fla 文档:
打开 EDEventExample.fla 文档.将"图层 1"重命名为  Actions.并在第一帧中输入下面的代码:

new EDEventExample();

保存文档.
测试 Flash 文档.在 XML 文档成功加载后会在输出面板中显示以下内容

complete

如需给事件传递参数,在发送事件时将参数添加事件对象(请看:1.事件处理机制)中,如下添加:

this.dispatchEvent({type:"complete", 参数1:"参数1", 参数2:"参数2", 参数N:"参数N");

在调用事件时:

private function complete(evt:Object)
{
    trace([evt.type, evt.target, evt.参数1, evt.参数2, evt.参数N]);
}

下面再看一个示例:
[5.2.示例: EDTimer 类(定时器)]
此示例文档详细:
Classes/AS2/utils/EDTimer.as
Example/AS2/utils/EDTimer/EDTimerExample.as
Example/AS2/utils/EDTimer/EDTimerExample.fla

主类:
打开 EDTimer.as 类,输入下面的代码(当不急时,应多打代码(有利于巩固知识).不应 copy/paste):

import mx.utils.Delegate;
import mx.events.EventDispatcher;
//------------------------------
class AS2.utils.EDTimer extends EventDispatcher
{
    //------------------------------
    private var _timerID:Number;
    private var _delay:Number;
    private var _repeatCount:Number;
    private var _currentCount:Number = 0;
    private var _running:Boolean;
    //------------------------------
    /*
    @parameter    delay:            延迟,单位毫秒.
    @parameter    repeatCount:    重复次数.默认为Infinity(正无穷大);
    */
    public function EDTimer(delay:Number, repeatCount:Number)
    {
        if (isNaN(delay)) {
            return;
        }
        if (isNaN(repeatCount)) {
            repeatCount = Infinity;
        }
        this._delay = delay;
        this._repeatCount = repeatCount;
    }
    //------------------------------
    public function reset():Void
    {
        this._currentCount = 0;
        this.stop();
    }
    public function start():Void
    {
        this._timerID = setInterval(Delegate.create(this, this.startTimer), this._delay);
        this._running = true;
    }
    public function stop():Void
    {
        clearInterval(this._timerID);
        this._running = false;
    }
    public function toString():String
    {
        return "[EDTimer]";
    }
    //----------------------------------------
    private function startTimer():Void
    {
        this._currentCount  ;
        this.dispatchEvent({type:"timer", currentCount:this._currentCount});
        if (this._currentCount == this._repeatCount) {
            this.reset();
            this.dispatchEvent({type:"timerComplete"});
        }
    }
    //------------------------------
    public function get delay():Number
    {
        return this._delay;
    }
    public function set delay(d:Number):Void
    {
        this._delay = d;
    }
    public function get repeatCount():Number
    {
        return this._repeatCount;
    }
    public function set repeatCount(r:Number):Void
    {
        this._repeatCount = r;
    }
    public function get currentCount():Number
    {
        return this._currentCount;
    }
    public function get running():Boolean
    {
        return this._running;
    }
    //------------------------------
}

因此类详细前面已讲,功能一样,只是事件处理机制不同而已.这里就不再啰嗦.

示例类:
打开 EDTimerExample.as 文档,输入下面的代码:

import AS2.utils.EDTimer;
//----------------------------------------
class EDTimerExample
{
    //----------------------------------------
    public function EDTimerExample()
    {
        var te:EDTimer = new EDTimer(1000, 5);
        te.addEventListener("timer", this);
        te.addEventListener("timerComplete", this);
        te.start();
    }
    private function timer(evt:Object):Void
    {
        trace("timer: "   evt.currentCount);
    }
    private function timerComplete(evt:Object):Void
    {
        trace(evt.type);
    }
    //----------------------------------------
}

示例 fla 文档:
打开 EDTimerExample.fla 文档,将"图层 1" 重命名为 Actions.并在第一帧中输入下面的代码:

new EDTimerExample();

测试 Flash 文档.输出面板会陆续显示以下的内容:

timer: 1
timer: 2
timer: 3
timer: 4
timer: 5
timerComplete

下一节:[6.建立强大的事件处理机制]

[6.建立强大的事件处理机制]

这一节讲建立强大的事件处理机制.学完这节,如果有接触过 AS3 的,马上会想到一句:这不就是 AS3 的事件处理机制吗?
的确.可以说跟 AS3 的事件处理机制一模一样.但还是有个作用域的问题.这节对想学习 AS3 的事件处理机制会有很大
帮助.如果你掌握这节中的内容,在 AS3 中就只有语法问题.也就会很快进入状态.毕竟是"水往低处流,人往高处走".对现
在用 AS2 的,学 AS3 是迟早的问题.不过 AS2 在新版本出来之前还是会很有用的(个人的看法).

作用域因为一样,前面也讲过,这里就不在啰嗦.
事件对象.这里已经创建一个 Event 类(或其子类)来代替.但功能一样.

这节讲的事件处理机制的形态(代码).
发送事件:

//继承.
import AS2.events.Event;
import AS2.events.CFEventDispatcher;
class className extends CFEventDispatcher
{
    ...
    this.dispatchEvent(new Event(Event.COMPLETE));
    ...
}

//不继承.
import AS2.events.Event;
import AS2.events.CFEventDispatcher;
class className
{
    public var addEventListener:Function;
    public var removeEventListener:Function;
    private var dispatchEvent:Function;
    
    public function className()
    {
        //此方法要在使用 dispatchEvent 方法前被执行.一般放于构造函数中.
        CFEventDispatcher.initialize(this);
    }
    
    ...
    this.dispatchEvent(new Event(Event.COMPLETE));
    ...
}

侦听事件:

//使用自定义函数.
import AS2.events.Event;
import className;
...
var cn:className = new className();
//自定义函数.
function completeHandler(evt:Event):Void
{
    trace(this); //输出: _level0.cn
}
cn.addEventListener(Event.COMPLETE, completeHandler);
...

//使用事件侦听器对象.
import AS2.events.Event;
import className;
...
var cn:className = new className();
//事件同名函数.
function complete(evt:Event):Void
{
    trace(this); //输出: this(指向侦听器对象)
}
cn.addEventListener(Event.COMPLETE, this);
...

移除侦听:

//使用自定义函数.
...
cn.removeEventListener(Event.COMPLETE, completeHandler);
...

//使用事件侦听器对象.
...
cn.removeEventListener(Event.COMPLETE, this);
...

AS2.utils.CFDelegate;
AS2.events.Event;
AS2.events.CFEventDispatcher;
这些是什么?下面讲解:

[6.1.创建 CFDelegate 类(修改 Delegate 类)]
CFDelegate 类是 Delegate 类的修改版本.简化了代码(一般不用的功能).提高了执行效率.

此类文档详细:
Classes/AS2/utils/CFDelegate.as

主类:
打开 CFDelegate.as 文档.输入下面的代码:

class AS2.utils.CFDelegate
{
    public static function create(scope:Object, method:Function):Function
    {
        var f:Function = function ()
        {
            method.apply(scope, arguments);
        };
        return f;
    }
}

保存文档.

[6.2.创建 CFEventDispatcher 类(修改 EventDispatcher 类)]
CFEventDispatcher 类是 EventDispatcher 类的修改版本.简化了代码(一般不用的功能).提高了执行效率.

此类文档详细:
Classes/AS2/events/CFEventDispatcher.as

主类:
打开 CFEventDispatcher.as 文档.输入下面的代码:

*/
//----------------------------------------
class AS2.events.CFEventDispatcher
{
    //----------------------------------------
    //构造函数
    public function CFEventDispatcher(){}
    //----------------------------------------
    //当不继承此类时,此属性才有效.
    private static var _ed:CFEventDispatcher;
    //----------------------------------------
    private static function _removeEventListener(queue:Object, handler):Void
    {
        /*
        这里主要用于删除事件数组中的事件处理器.
        */
        if (queue != undefined) {
            var l:Number = queue.length;
            while(l--){
                if(queue[l] == handler){
                    queue.splice(l, 1);
                    return;
                }
            }
        }
    }
    //当不继承此类时.此方法有效.
    public static function initialize(o:Object):Void
    {
        /*
        如果没有继承此类,而是使用 initialize 此方法时, _ed 等于 undefined.然后创建此类的实例.
        最后将事件通知和侦听器管理功能添加到 initialize 方法中的对象 o.
        前面所讲的不继承此类时需添加的三个方法,其实是四个.还有 dispatchQueue 方法.但此方法在
        调用 dispatchEvent 方法时就会自动调用.可能有人会问,为什么没有定义就能调用?因为在函数
        中可以操作对象.从而对对象动态添加方法和属性.这里就是用了在函数中操作对象.
        */
        if (_ed == undefined) {
            _ed = new CFEventDispatcher();
        }
        o.addEventListener = _ed.addEventListener;
        o.removeEventListener = _ed.removeEventListener;
        o.dispatchEvent = _ed.dispatchEvent;
        o.dispatchQueue = _ed.dispatchQueue;
    }
    //----------------------------------------
    private function dispatchQueue(queueObj:Object, eventObj:Object):Void
    {
        /*
         这里主要用于判断事件处理器是对象还是函数.
        */
        if (queueObj[eventObj.type] != undefined) {
            for (var i:String in queueObj[eventObj.type]) {
                var o = queueObj[eventObj.type][i];
                if (typeof (o) == "object" || typeof (o) == "movieclip") {
                    //调用对象中的handleEvent函数.
                    //if (o.handleEvent != undefined) {
                        //o.handleEvent(eventObj);
                    //}
                    //调用对象中的事件同名函数.  
                    //if (o[eventObj.type] != undefined) {
                        o[eventObj.type](eventObj);
                    //}
                } else {
                    //调用自定义函数.
                    o.apply(queueObj, [eventObj]);
                }
            }
        }
    }
    public function dispatchEvent(eventObj:Object):Void
    {
        //将事件源始终指向this(应用此类的对象).
        eventObj.target = this;
        //此句对动态类,或在类中定义"事件名Handler" 这样的函数时才有效.在这里我注释了这句.你如果你想用,可以启用它.
        /*
        用法: 对象.事件名Handler = function(evt:Object){};
        */
        //this[eventObj.type   "Handler"](eventObj);
        this.dispatchQueue(this, eventObj);
    }
    public function addEventListener(event:String, handler):Void
    {
        //这里可以这样理解:
        /*
        使用
        addEventListener("click", 事件处理器);
        添加事件.
        这时, this["click"] 就等于 undefined.
        (this["click"] == undefined) = true
            然后将创建一个新数组来存储事件处理器.
            this["click"] = [];
        然后执行
        CFEventDispatcher._removeEventListener(this["click"], 事件处理器);
        来检测此事件是否有相同的事件处理器.如果是就删除它.
        举个例:当你在一个网站注册用户名时.网站的注册程序会从数据库中检测是否有与你相同的用户名.
        如果有将会提示你重新输入用户名(在这里就是直接删除了).如果没有就会注册成功(这里就在后面
        执行 push).但是网站的注册程序不会从数据库中检测是否有与你相同的密码.
        
        就是说一个事件,可添加多个不同的事件处理器,但不能添加相同的事件处理器.
        当添加新的事件时,也是一样的
        
        最后使用
        this["click"].push(事件处理器);
        将事件处理器添加到事件数组.
        */
        if (this[event] == undefined) {
            this[event] = new Array();
        }
        //ASSetPropFlags 是隐藏的方法.用它和不用它貌似没有区别.大家可以研究下.
        //_global.ASSetPropFlags(this, event, 1);
        CFEventDispatcher._removeEventListener(this[event], handler);
        this[event].push(handler);
    }
    public function removeEventListener(event:String, handler):Void
    {
        //这里我就不啰嗦了.
        CFEventDispatcher._removeEventListener(this[event], handler);
    }
    //----------------------------------------
}

保存文档.

[6.3.创建 Event 类(事件基类,继承 Object 类)]
你可以把它看作事件对象.因应它的工作就是生成事件对象.

此类文档详细:
Classes/AS2/events/Event.as

主类:
打开 Event.as 文档.输入下面的代码:

class AS2.events.Event extends Object
{
    //----------------------------------------
    //事件的常数名.
    public static var COMPLETE:String = "complete";
    public static var CANCEL:String = "cancel";
    public static var CHANGE:String = "change";
    public static var CLOSE:String = "close";
    public static var CONNECT:String = "connect";
    public static var FULLSCREEN:String = "fullScreen";
    public static var OPEN:String = "open";
    public static var REMOVED:String = "removed";
    public static var RESIZE:String = "resize";
    public static var SCROLL:String = "scroll";
    public static var SELECT:String = "select";
    //----------------------------------------
    public var type:String;
    public var target:Object;
    //----------------------------------------
    private var className:String = "Event";
    //----------------------------------------
    //构造函数.
    public function Event(type:String)
    {
        this.type = type;
    }
    //----------------------------------------
    public function toString():String
    {
        var str:String = "";
        for (var i:String in this) {
            if (this[i] != undefined) {
                str  = i   "="   this[i]   " ";
            }
        }
        return "["   this.className   " "   str.slice(0,str.length - 1)   "]";
    }
    //----------------------------------------
}

保存文档.

此类包含下面内容:
1.事件的常数名.如:

    public static var COMPLETE:String = "complete";
    ...

2.基本的属性.如: