《AS3从入门到精通》笔记

1.AS3的虚拟机叫AVM2,而早期的AS使用的是AVM1,所以效率上AS3比早期版本快了10倍;
2.舞台的名字叫state,主时间轴的名字叫root
3.当trace()函数输出变量时,会自动调用toString()方法
4.写在帧里面的变量都是在MainTimeLine的类里,并且MainTimeLine是动态类,而root是该类创建的对象,所以这些变量都变成了root的属性,可以用 root.xxx 来访问
5.Stage不是动态类,所以不能给他创建属性,例如stage.xxx就不行了
6.时间轴的方波顺序是在同一时间轴而不同图层中,同一帧上的代码由上到下执行;在同一图层上,按照包含这些代码的帧在时间轴上出现的先后顺序排列
7.声明常量 const ABC:unit=5;
8.flash中的数字计算,整数计算没有误差,但是浮点数计算总会出现误差,例如:trace(0.1+0.2)
9.有时候,处理数字的时候,可以先把它转换成文本类型,或许可以处理的更加方便
10.在基于时间轴的编程中,如果在第一帧定义了一个变量,又在后面的帧中定义了一个同名变量,AS3会当作“重复定义变量”来处理---新的变量代替旧的变量
11.Number类型的默认值是NaN(not a number);String类型的默认值是null;Boolean->false;int(uint)->0;
"*"类型的默认值是undefined,Object的默认值是null;
12.使用var 定义变量比直接定义变量和this动态添加变量效率更高;另外,声明变量的准确数据类型会提高效率;(相比不定义数据类型或数据类型定义的不准确)
13.AS3中任何类都是Object的子类 var aaa:Object=new Object();或者var a:Object;
14.a=[0];表示数组;a={x:0};表示对象,x是其属性;
15.用反射动态创建实例的话,就可以制作swf素材库,根据库中的链接名可动态导出素材,实现程序与美工的分离;
//保存链接名  
var linkname:String = "BigPhoto";  
//得到类信息  
var cla:Class = getDefinitionByName(linkname);  
//创建类的实例  
var bitmapdata:NewClass = new cla();  



16.复杂数据类型的变量通过引用来操作实例的

  1. var obj1:Object=new Object();
  2. var obj2:Object=new Object();
  3. trace(obj1==obj2); //false;
  4. var obj3:Object=obj1;
  5. trace(obj1==obj3)//true

17.delete 不能删除var 定义的变量,只能删除动态的属性。
delete mc.speed;
delete arr[0];-------只是删除数组的元素的值,不能删除索引; 可以用splice删除元素;//oneArray.splice(2,2);
18.检测变量的准确数据类型,用is-----用来判断实例是否属于某类型;或者它的父级;

  1. var x_mc:MovieClip=new MovieClip();
  2. trace(x_mc is MovieClip); //true
  3. trace(x_mc is Sprite);       //true
  4. trace(x_mc is Stage);       //falsed

19.getQualifiedClassName();获取包括包在内的完整信息;
20.as作为复杂类型转换: 对象 as 类型;mc2=mc1 as MovieClip;
21.this是对当前对象的引用,在主时间轴中,this引用的是主时间轴,所以trace(root==this);//true
22.点语法可以用“[ ]”来代替

  1. var x_mc:MovieClip=new MovieClip();
  2. trace(x_mc.x);
  3. trace(x_mc['x']);

好处1.访问的动态性:可以用变量名,属性名,方法名保存在字符串变量中,通过变量和数组运算符就可以访问属性和方法;2.在严谨模式下,点语法可能会出错;
23. 在if 中 “||”中,把最可能的条件放在前面,可减少条件的判断次数;在if的“&&”的条件中,同理把最不可能的条件放在前面;
24. “!”运算符是对布尔值取反;
var t:Boolean=true;
trace(!t);
25.for (变量 in 对象或数组)与 for each(变量 in 对象或数组)的区别是 前者的变量代表属性名或者数组索引,后者获得的是属性值或者数组元素的值;
26.定义对象可以用

  1. var object1:Object=new Object();
  2. obje1.x=100;obje1.y=100;
  3. 或者 object1={x:100,y:100};

27.函数的参数可以是任何数据类型的变量;当使用简单数据类型作为变量时,传递的是值;使用复杂数据类型作为变量时,传递的是引用(函数调用开始时,实参向形参进行了值的传递,函数调用结束时形参向实参进行了值传递)
28.在使用函数的默认参数功能时,默认参数必须是写在所有必须参数的后面;
29.   Interactive类的contextMenu属性用于右键菜单的创建;
30. this.numChildren;返回此对象的子实例数目
31.Graphics类不允许用户自己创建实例,只有通过Shape或Sprite(MovieClip)来创建;首选Shape,如果需要图形的交互时,再考虑Sprite或者MovieClip;
32.判断显示实例是否出现在舞台上,可使用显示实例的stage属性;
trace(mc.stage);如果是null,则不在,否则的话,是[object Stage]
33.绘图
绘制直线:

  1. this.graphics.lineStyle(1);
  2. this.graphics.moveTo(0,0);
  3. this.graphics.lineTo(100,200);
  4. 绘制曲线:
  5. this.graphics.lineStyle(1);
  6. this.graphics.moveTo(0,0);
  7. this.graphics.curveTo(100,0,100,100);//控制点的x和控制点的y,终点的x和终点的y;
  8. 绘制矩形:
  9.    this.graphics.beginFill(0xFF9900,1);
  10.    this.graphics.drawRect(0,0,50,100);
  11.    this.graphics.endFill();

34.当创建一个flash文档时,已经有了stage和root(this)2个实例;root(this)又是stage的实例;
35.用name属性给实例赋实例名
var mc:Sprite=new Sprite();
mc.name="xxx";

36.使用parent属性 可以访问显示列表中的上一级实例;
下一级引用:
getChildAt(index:int);
getChildByName(name:String);   
通过点语法也可以访问子级实例,要求是显示列表中的实例都是动态类,可以有自定义的属性(例如MovieClip)
37.深度可以理解成显示实例的显示层次,深度越大,显示实例显示的层次就越高;
38.getChildIndex(实例名);获取实例的深度
39.交换深度的2种方法:
swapChildren(实例名1,实例名2);//通过引用来交换
swapChildrenAt(0,1);                      //通过深度来交换
40.移除所有子对象

  1. for (var i:int=mc.numChildren-1;i>=0;i--) {
  2. mc.removeChildAt(0);
  3. }

41.mc.currentLabel 当前帧标签 mc.currentFrame 当前帧
42.addFrameScript(index:int,fn);//帧数,函数
    移除addFrameScript(index:int,null); //移除在第index帧上的函数
43.使用LoaderInfo类的2种方式:通过DisplayObject类的loadinfo属性来引用LoaderInfo类,或者通过Loader类的contentLoaderInfo属性来引用;
this.loadInfo.addEventListener(...);
var loaderoader=new Loader();
loader.contentLoaderInfo.addEventListener(...);


函数体中的this一般指向定义函数的路径

Animator类,选中动画的全部帧-》右键-》【将动画负值为AS3脚本】-》输入实例名-》粘贴脚本;

事件流:1.捕获阶段:从顶部到目标;2.目标阶段:目标;3.冒泡阶段:从目标到顶部;
addEventListener的第三个参数,默认是false,表示没有捕获阶段,只有目标阶段和冒泡阶段;(先侦听目标事件,再侦听冒泡阶段的事件);
true:表示先有捕获阶段,再有目标阶段(先侦听捕获阶段的事件,再侦听目标事件);
如果想同时使用捕获阶段和冒泡阶段,则应该把事件注册2次,第一次把useCapture设置true,第二次把useCature设置成false;
Event类的cancelable属性表示默认行为能否被阻止;
a_txt.addEventListener(TextEvent.TEXT_INPUT,func);
function func(e:TextEvent) {
e.preventDefault(); //阻止文本输入的事件
}


Event类的bubbles属性表示是否可以使用冒泡机制;并非所有类都可以使用该机制;例如MouseEven类可以,Event类的complete事件不可以;
Event类的eventPhase属性表示事件流的阶段;1=捕获阶段;2=目标阶段;3=冒泡阶段;
target属性在事件流的目标阶段;currentTarget在事件流的冒泡,目标,捕获阶段;只有当事件流在目标阶段,2者才是相同的;

mc1.mouseChildren=false;//mc1的子对象将不能处理鼠标事件;

stopPropagation()停止事件流中当前节点以后的事件;stopImmediatePropagation()停止当前事件以后的所有事件;
function fn_1(e:MouseEvent) {
e.stopPropagation();
}

addEventListener(事件,函数,冒泡机制,次序,是否弱引用);如果在addEventListener内的函数不存在任何引用,那么在弱引用的情况下,这个侦听器会被垃圾回收器删除
第二部分:

Event类的事件:
Event.ACTIVATE 当播放器获得系统的焦点时发生
Event.DEACTIVATE 当播放器失去系统的焦点时发生
Event.Added    当显示实例添加子显示实例或显示实例被添加到父级显示实例时发生;
var sp1=new Sprite();
sp1.addChild(sp2);
this.addChild(sp1);
Event.REMOVED 移除显示实例的事件(查一下是否和Added类似);


过程参考:
this.addChild(sp1);
stage.addChild(sp1);
相当于先把sp1从root下删除,触发REMOVED事件,再把sp1添加到stage,触发Added事件;

判断显示实例 是否在舞台中,可以通过显示实例的stage属性来判断,如果显示实例没有通过addChild()添加到显示列表,说明显示实例不在舞台中,它的stage属性是null;

Keyboard类的发起者一般是stage

在FLASH IDE下控制元件的坐标,参照点是元件信息面板上选择的参照点,默认是元件中心点;控制元件缩放,参照点是元件中心点,也就是圆圈所在位置;使用AS控制元件的坐标和缩放,参照点都是元件的注册点,也就是元件上的十字标记

改变root的坐标,root下的显示实例的坐标也会随着改变。(stage的x,y不能被改变),所以,一般实例都是添加在root下面的;

stageX,stageY,鼠标相对于stage的x,y坐标;localX,localY,鼠标相当于显示实例的注册点的x,y坐标

mc.addEventListener(MouseEvent.CLICK,fn);

function fn(e:MouseEvent) {

trace(e.localX);//MouseEvent类的属性
trace(e.stageX);//MouseEvent类的属性
trace(stage.mouseX);//显示实例的属性--本地坐标(DisplayObject实例的属性)
}



在package中,如果要直接访问属性,需要在var 属性名...之前加上public;
在var 和 function 前没有加修饰符时,属性或方法相当于被internal修饰,在同一包内可以调用;
另外,当局部变量和成员变量同时出现在类的方式中时,成员变量将会被隐藏;一般用this.成员变量来代表;
package {
public class Person{ //相当于public class Person extends Object 这是隐式继承
public var names:String="sss"
static public var length:int=3 //静态属性,在类的内部,不能通过this.length调用,因为静态属性也就是类属性,不通过实例来调用,在类内部可以通过length或者Person.length调用,在类外部通                               //过Person.length调用
public function p(names:String) {
   trace(this.names)
   this.names=names;
}

static function s() { //在函数体前加上static,表示是静态方法;静态方法只能访问静态属性;实例方法可以对静态属性和实例属性都可以访问;
//静态方法可以调用静态方法,实例方法不能调用静态方法
trace("aaa");
}
}
}
当类加载(import)的时候,会给类成员(类属性和类方法---静态属性和静态方法)分配一定的内存;当创建第一个实例,会给实例成员(实例属性和实例方法)分配内存,当创建第二个实例,会给第二个实例的实例成员(实例属性和实例方法)分配内存,但此时类成员不能再分配内存;因此可以理解类成员和实例成员相互访问间的机制;

文档类即是MainTimeline的实例;一般继承Sprite(如果主时间轴只有一帧)或者MovieClip类(多帧);
当在主时间轴的帧中编写代码时,使用位于flash.*包内的类或函数,不需要进行导入,当使用了文档类,则需要导入包

弧度=Math.atan2(y,x);//Y轴坐标和X轴坐标;角度/弧度=180/Math.PI;
2点间的距离:Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
Math.sin(弧度);Math.cos(弧度);利用sin,cos可计算X,Y轴的速度;
根据正余弦曲线可以做曲线运动;

Math.floor(x:Number)获取数字的下限值;Math.round(x:Number)获取数字的四舍五入值;

var p1oint=new Point(100,200);
var p2oint=new Point(100,200);
p1.length;获取p1距离(0,0)的长度
Point.distance(p2,p1);获取p2到p1的长度;
var lineine=new Line(p1,p2);
line.K;直线的斜率((p1.y-p2.y)/(p1.x-p2.x));如果输出的是Infinity,表示是90度
line.angle倾斜角
trace(line.A+":"+line.B+":"+line.C);相当于Ax+By+C=0;

两直线的交点:

  1. var line1ine=new Line(new Point(0,0)),new Point(0,100));
  2. var line2ine=new Line(new Point(100,0)),new Point(0,50));
  3. var point=line1.pointOfIntersection(line2);
  4. trace(p);

获取影片剪辑的矩形实例
trace(mc.getBounds(this))   //包括笔触
trace(mc.getRect(this)) //不包括笔触
trace(mc.transform.pixelBounds) //带笔触的背景矩形
这3者获得的x,y是以矩形的左上角为坐标,而mc的x,y是以注册点为坐标的;

标签:

AS3中的getChildByName及动态操作控件问题

在AS3中,我们可以用getChildByName来获取一个元件,但是要注意返回的类型是DisplayObject,这样一旦我们的元件中有一些自定义的方法就不能使用了。

比如我有一个类Ball,Ball有一个方法move,那么我可以这样写:

var b:Ball=new Ball();

addChild(b);

b.move();//这样没问题

getChildByName(”b”).move();//这样编译时会报错

其原因应该就是getChildByName返回的类型是DisplayObject,而并不是Ball,所以无法调用Ball的方法。

如果这样写:

var c:Ball= getChildByName(”b”) as Ball;

c.move();

这样就没问题了,编译通过,可以调用Ball的方法。

 

下面是我自己的总结:

getChildByName方法是用于元件动态命名时的。例如:在场景中有一个元件,在属性面板中对其命名为cc,在对其操作时就可以写cc.y=XXX;而动态命名时,就如上面的例子,场景中本没有这个元件,用addChild将其放到场景中时再对其命名,这时要对这个元件进行操作就要用到getChildByName了,再举例如下:

var b:Ball=new Ball()

addChild(b)

b.name="mc1"

getChildByName("mc1").y=200

 

补充:

例如场景中有一元件mc1,现在用一个字符串来表示它,并且利用这段字符串来调用它的属性或方法:

var cc="mc1"

getChildByName(cc).XXX

这时如果是自定义的属性或方法的话,会报错,因为AS3认不出来被操作的对象是何类型的,这就需要我们来告诉它,有两种方法解决这个问题:

一、将getChildByName(cc)改成MovieClip(getChildByName(cc)),意思是先用getChildByName将cc这个字符串变成DisplayObject,然后再将它变为MovieClip,这时AS3认出它是一个MovieClip了,就可以访问它的属性和调用它的方法了。

二、将语句写成:

var cc:MovieClip=mc1

this["cc"].XXX

 

另外还有一种字符串的写法:

var cc=mc1.name

this["cc"].XXX

这里mc1.name必须是在属性面板里命名的,而不是mc1.name="XXX"命名的

[]在这里就是动态的意思,被操作的对象的类型是动态的,这样就可以绕过AS3的编译器了