咖啡伴侣

呆在上海
posts - 163, comments - 156, trackbacks - 0, articles - 2

as3显示对象DisplayObject

Posted on 2008-04-08 12:11 oathleo 阅读(2324) 评论(0)  编辑  收藏

AS3里所有能在舞台(Stage)上看到的东西都继承自 DisplayObject 。如果让它最终显示出来还需要使用某个 DisplayObjectContainer 的addChild() 或者 addChildAt() 方法把它加到显示列表(display list)里。看看图示:
1.jpg
  显示列表的最根部是 Stage 。Stage 是一个 DisplayObjectContainer ,所有的可见对象是它的 child 或者 child 的 child 。在一个文档的第一帧输入代码:

trace(stage.getChildAt(0));

输出类似于“[object Timeline0_94f120f8fa23a64ca3a80eab162a99a]”。下划线后面的字符串是随机的,每次都不同。删掉时间轴上的代码,绑定文档到一个自定义类,如 TestStage :

package{
import flash.display.Sprite;   
public dynamic class TestStage extends Sprite{
public function TestStage(){
trace(stage.getChildAt(0));
}
}
}

输出:“[object TestStage]”。可见,Flash IDE 的默认编辑环境,也就是 AS2 里的 _root ,现在是 Stage 的第一个 child 。注意上面的代码,我把 TestStage 类定义为 dynamic :

public dynamic class TestStage extends Sprite{

AS3 里 DisplayObject 不是动态类,所以如果想像以前那样使用点语法(mc1.mc2.txt1.text)或者 getChildByName() 方法访问 Flash IDE 创建的 MC ,必须把类定义为动态,不然会报错:
“ReferenceError: Error #1056: Cannot create property test_mc on TestStage.”
  现在在 Flash IDE 舞台上随便创建一个影片剪辑,命名为 test_mc ,修改上面的 trace 代码为

trace(stage.getChildAt(0).test_mc.name);

输出:“test_mc”。
在 AS2 里访问同样的 MC 代码为:

trace(_root.test_mc.name);

stage.getChildAt(0) 就是舞台场景或者我们绑定的文档类。所以在文档类里我们直接

trace(this.test_mc.name);

在时间轴上也可以使用同样的代码,就像过去一样。
  当然,前面提到,Stage 是一个 DisplayObjectContainer ,所以它有 addChild() 和 addChildAt() 方法。如果使用

//var stage_mc:Sprite = new Sprite();...
stage.addChild(stage_mc) ;

将可以看到在舞台或者文档类中创建的所有东西都在这个新加的 stage_mc 之下。如果是

stage.addChildAt(stage_mc,0);

所有的东西将在这个 stage_mc 之上,_root 在这里将相当于 stage.getChildAt(1) 了。这在下面会讨论到。
  下面用一张图来加深对 DisplayObjectContainer 的理解,这是一个装载了不同 DisplayObject 的 DisplayObjectContainer 。
2.jpg
那么究竟有哪些类是 DisplayObjectContainer ?直接继承 DisplayObjectContainer 的有 Loader, Sprite, Stage 。那么它们和它们所有的子类(Sprite 的子类 MovieClip,DownloadProgressBar 等以及它们的子类)都将是 DisplayObjectContainer ,可以使用 addChild() 和 addChildAt() 方法加载 DisplayObject (DisplayObjectContainer 也继承 DisplayObject) :

  最后来看看 AS3 中的层管理。它是完全自动的。当使用 addChild() 方法把 DisplayObject 加到一个 DisplayObjectContainer 的 display list ,它将自动获得从0开始的连续的 index 。于是你可以用 getChildAt(0) , getChildAt(1) … 分别获得第一个、第二个…加入显示列表(display list)的 DisplayObject ,这比 getChildByName() 方法更有效率。如果使用 addChildAt() 方法把一个 DisplayObject 加到一个已经存在的层,如上面提到的

stage.addChildAt(stage_mc,0);

那么该层原有的以及所有该层之上的内容都自动上移一层(index + 1)。同样的,当使用 removeChild() 或 removeChildAt() 方法删除某一层的显示内容,所有该层之上的内容都会自动下移一层(index - 1)。注意 index 始终是连续的,如果现在的 numChildren 是4,也就是现有最大的 index 是3(0,1,2,3),你将不能 addChildAt(mc,5) 或者任何比5更高的层,编译器将报错:
“RangeError: Error #2006: The supplied index is out of bounds.”
  最后提一下,所有的 DisplayObject 都有一个 stage 属性指向 Stage ,使用它的前提是该 DisplayObject 已经加入某个 DisplayObjectContainer 的 display list ,不然返回的将是 null 。


只有注册用户登录后才能发表评论。


网站导航: