显示容器 DisplayObjectContainer

显示容器 DisplayObjectContainer(DisplayObjectContainer 继承自 DisplayObject)

本节详细介绍显示容器以及显示列表的使用方法

批注:
Shape, Bitmap, textFeild, TextInput不可以addChild。原因是他们直接继承自DisplayObject
Sprite, Stage, MovieClip, BitmapText可以addChild,原因是他们继承自DisplayObjectContainer,又封装了一些显示列表中常用的功能




-----------1, 显示容器的概念与实现
所有的容器全部继承自 DisplayObjectContainer 类,这个名称为 DisplayObjectContainer 的类又继承自 DisplayObject 。也就是说,在Egret中,所有的容器其实也继承自 DisplayObject。

在Egret中, DisplayObjectContainer 封装了一些显示列表中常用的功能。在后面的内容中,我们将详细介绍显示列表的操作。这些常用操作主要分为四类:

添加、删除子对象
访问子对象
检测子对象
设置叠放次序


属性:

方法:






批注:GameApp类就是继承了DisplayObjectContainer,所以GameApp就像一个舞台,有自己的:
a, stage对象,可获取舞台宽高,
var stageW:number = this.stage.stageWidth;
        var stageH:number = this.stage.stageHeight;
this.stage.addChild(this.loadingView);
this.stage.removeChild(this.loadingView);
b, 监听事件,可以this.addEventListener(egret.Event.ADDED_TO_STAGE,this.onAddToStage,this);
c, 添加孩子,
//添加背景
var sky:egret.Bitmap = this.createBitmapByName("bgImage");
        this.addChild(sky);
//添加遮罩
        var topMask:egret.Shape = new egret.Shape();
        topMask.graphics.beginFill(0x000000, 0.5);
        topMask.graphics.drawRect(0, 0, stageW, stageH);
        topMask.graphics.endFill();
        topMask.width = stageW;
        topMask.height = stageH;
        this.addChild(topMask);
//添加logo
        var icon:egret.Bitmap = this.createBitmapByName("egretIcon");
        icon.anchorX = icon.anchorY = 0.5;
        this.addChild(icon);
        icon.x = stageW / 2;
        icon.y = stageH / 2 - 60;
        icon.scaleX = 0.55;
        icon.scaleY = 0.55;
//添加Hello Egret
        var colorLabel:egret.TextField = new egret.TextField();
        colorLabel.x = stageW / 2;
        colorLabel.y = stageH / 2 + 50;
        colorLabel.anchorX = colorLabel.anchorY = 0.5;
        colorLabel.textColor = 0xffffff;
        colorLabel.textAlign = "center";
        colorLabel.text = "Hello Egret";
        colorLabel.size = 20;
        this.addChild(colorLabel);

(1)最轻量级的容器

在Egret中,我们拥有一个非常轻量级的容器:Sprite。

如果你查看Sprite类的内容,你会发现,Sprite仅仅是继承 DisplayObjectContainer。同时添加了一个Graphics功能。

(2)自定义容器

想要自定义一个容器非常容易,我们编写一个类,并且继承 DisplayObjectContainer 即可。当然,如果你想实现相关的Graphics绘图功能,你也可以继承 Sprite。

下面是一个自定义容器类的示例,这里我们定义了一个GridSprite。这个类默认会绘制一个红蓝相间的格子。
与上同,仅写出继承
class GridSprite extends egret.Sprite

批注:也可以写继承 DisplayObjectContainer。由于Sprite也继承自DisplayObjectContainer,同时又加入了自己的功能,为方便起见,也可以直接继承Sprite

批注:Sprite,不是上节对象中的四种对象Bitmap、Shape、TextField、TextInput
Sprite是容器,里面可以放置很多东西
Bitmap、Shape、TextField、TextInput是对象,不能放置东西




-----------2,添加与删除显示对象

(1)添加显示对象到显示列表
this.addChild( spr );

显示列表是一个树状结构,这里 spr 的上一级就是 this,也就是我们的文档类。文档类是 stage 舞台的第一个子对象。

批注,他们之间的关系是:容器->舞台->spr
舞台:有自己的宽高,可以添加/删除spr,this(文档类)是舞台的第一个子对象
spr:是一个容器

(2)删除显示对象
this.removeChild( spr );


(3)显示对象操作的注意点
a.显示对象独立于显示列表

b.相对坐标系
显示对象的坐标系是相对坐标系,而非绝对坐标系。
当我们将一个显示对象的x,y坐标值均设置为100的时候,该坐标值表示,当前显示对象居于父级原点100,100的位置。

c.3.多次添加显示对象到显示列表
同一个显示对象不被被代码加入显示列表多少次,在屏幕上只绘制一次。
如果一个显示对象A被添加到了B这个容器中,然后A又被添加到了C容器中。那么在第二次执行 C.addChild(A) 的时候,A自动的从B容器中被删除,然后添加到C容器中。

d.删除操作的注意点

当我们想要删除一个显示对象的时候需要执行的操作是:
容器对象.removeChild( 显示对象 );
但执行这个删除操作,我们的“显示对象”必须拥有父级。换句话说,被删除的显示对象必须存在于显示列表当中。
如果当前删除显示对象不在显示列表之中,那么在JavaScript控制台中你将看见报错信息:Uncaught Error: [Fatal]child未被addChild到该parent:
避免这种问题的处理方法非常简单,就是当你每次removeChild之前,你都对即将要被删除的显示对象做一次判断,判断它是否拥有父级。判断的代码如下:
if( spr.parent )
{
    spr.parent.removeChild( spr );
}



-----------3, 深度管理
深度是由每个容器的子对象列表所管理。
每个容器都清楚自己拥有多少个子对象。我们可以通过容器的 numChildren 属性来获取当前容器的子对象数量。
容器.numChildren

(1)深度顺序
Egret中容器的深度都是从0开始的,当一个显示对象第一个被添加到容器中时,它的深度值为0。这个显示对象也处于容器的最底层。当我们添加第二个显示对象的时候,他的深度值为1,并且在第一个显示对象上方。如果两个显示对象发生了相交,那么我们可以从视觉上看到,第二个显示对象遮挡住第一个显示对象。

(2)添加/删除指定深度的对象
我们默认使用的 addChild 方法会默认按照当前子对象深度进行排序,从0开始,每次深度加1,以此类推。

当我们想讲某一个显示对象添加到一个指定深度的时候,我们需要使用 addChildAt 方法。这个操作很像排队时插队的想象。
使用 addChildAt 方法也非常的容易,具体使用方法如下:

容器.addChildAt( 显示对象, 深度值 )





-----------4, 访问容器子对象
(1)通过深度值获取子对象
通过深度值获取子对象可以使用 getChildAt 方法,具体使用方式如下:

容器.getChildAt( 深度值 );

(2)通过Name属性获取

第二种方式是通过显示对象的 name 属性来获取,这种方式更加直接简单。

(3)两种获取子对象方式的比较

我们通过深度值和name属性获取子对象的作用是相同的,但Egret在内部事项原理却大大不同。

使用深度值获取子对象,Egret会根据当前容器的显示列表查找指定深度的显示对象,并作为返回值返回给用户。这种检索方式是快速的,不需要进行大量运算。

通过name属性来获取子对象,Egret内部首先会对当前容器的所有子对象进行编译,同时匹配相同的name属性值,当发现相同name属性的时候,则将该子对象作为返回值返回给用户。虽然在Egret内部进行了相关算法优化,但还是在一定程度上消耗了一些性能。

官方推荐使用第一种方法,通过深度值来获取子对象。




如果您觉得本文的内容对您的学习有所帮助,您可以微信:
显示容器 DisplayObjectContainer

你可能感兴趣的:(JavaScript,Egret)