[Egret][文档]显示对象和显示容器(视图)

一、基本概念

视图包括看得见的显示对象和看不见的显示对象容器

1.显示对象

——图形、文字、视频、图片等。DisplayObject类是所有显示对象的父类。

核心显示类

DisplayObject 显示对象基类,所有显示对象均继承自此类
Bitmap 位图,用来显示图片
Shape 用来显示矢量图,可以使用其中的方法绘制矢量图形
TextField 文本类
BitmapText 位图文本类
DisplayObjectContainer 显示对象容器接口,所有显示对象容器均实现此接口
Sprite 带有矢量绘制功能的显示容器
Stage 舞台类

【注】:显示对象容器类似于div,可以放东西,而Bitmap、Shape这些类似于<img>,只能放对应的显示对象。

【注】:Stage是唯一的、根部容器。Sprite是可以绘制矢量图的容器。

可视属性

——可视属性用来设置可见的对象的一些属性(大小、旋转、透明等等)

  • alpha:透明度
  • width:宽度
  • height:高度
  • rotation:旋转角度
  • scaleX:横向缩放
  • scaleY:纵向缩放
  • skewX:横向斜切
  • skewY:纵向斜切
  • visible:是否可见
  • x:X轴坐标值
  • y:Y轴坐标值
  • anchorOffsetX:对象绝对锚点X
  • anchorOffsetY:对象绝对锚点Y

2.显示对象容器

DisplayObjectContainer 封装了一些显示列表中常用的功能:

  • 添加、删除子对象

  • 访问子对象

  • 检测子对象

  • 设置叠放次序

3.显示列表

可以把显示列表看成树状结构。

在这个树状结构中,处于最上层的是“舞台”。对应到程序中,是 stage 对象。舞台是Egret显示架构中最根本的显示容器。每个Egret应有且只有一个stage对象。舞台是这个显示树结构的根节点。

在舞台中,我们还拥有一个主容器。这个容器就是文档类所创建的容器。每一个Egret都会拥有一个文档类,这个文档类必须是一个显示对象容器。

在这个场景中,包含了一个场景背景,背景是由背景图和一颗大树组成的。另外两个元素分别是人物和草地。

 二、交换操作

1.本地坐标和舞台坐标

x 和 y 属性始终是指显示对象相对于其父显示对象坐标轴的 (0,0) 坐标的位置,但该位置不一定是舞台的左上角。

若要确定对象相对于全局舞台坐标的位置,可以使用任何显示对象的 globalToLocal() 方法将坐标从全局(相对于舞台)坐标转换为本地(相对于显示对象容器)坐标

//把舞台左上角的坐标(0,0)转换为 container 内部的坐标
var targetPoint: egret.Point = container.globalToLocal(0,0);
// 也可以使用localToGlobal() 方法将本地坐标转换为舞台坐标

三、添加、删除显示对象

——在Egret中建立显示对象和渲染显示对象是两个过程。

建立显示对象后,对象会处于内存中,但不会参与渲染过程,只有把显示对象放到显示列表后,显示对象才会参与渲染过程。

如果想将某个显示对象从渲染过程中删除,只需要将其移除显示列表即可。

//创建了一个类型为Sprite的显示对象
var spr:egret.Sprite = new egret.Sprite();
spr.graphics.beginFill( 0x00ff00 );
spr.graphics.drawRect(0, 0, 100, 100);
spr.graphics.endFill();
//该对象存在,被添加到显示列表中,在画面中显示
this.addChild( spr );
//该对象存在,但已被移除显示列表,画面上不显示
this.removeChild( spr );
//该对象存在,驻于内存中

1.添加显示对象

this.addChild( spr );

【注】:同一个显示对象无论被代码加入显示列表多少次,在屏幕上只绘制一次

如果一个显示对象A被添加到了B这个容器中,然后A又被添加到了C容器中。那么在第二次执行 C.addChild(A) 的时候,A自动的从B容器中删除,然后添加到C容器中

2.删除显示对象

this.removeChild( spr );

【注】:执行删除操作时,“显示对象”必须拥有父级。

可以每次removeChild之前,对即将要被删除的显示对象做一次判断,判断它是否拥有父级:

if( spr.parent ) {
    spr.parent.removeChild( spr );
}

四、深度管理(层级)

——每一个显示对象在其父级的容器中都拥有一个属于自己的深度值,而且这个值相对于同级显示对象是唯一的。(可以类比为数组下标,中间加一个,则后边都加一,减一个则都减一)

可以通过容器的 numChildren 属性来获取当前容器的子对象数量。

容器.numChildren

1.深度顺序

容器的深度都是从0开始,逐渐累加的。深度大的对象覆盖深度小的对象。

2.添加/删除对象到指定深度

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

若要将某一个显示对象添加到一个指定深度的时候,需要使用 addChildAt() 方法。

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

可以使用 容器.removeChild( 显示对象 ) 将一个显示对象移除显示列表,同样,还可以使用

容器.removeChildAt( 深度值 ) 来删除一个指定深度的显示对象。

【注】:移除所有子对象

容器.removeChildren();

3.交换不同深度对象

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

4.重设子对象深度

容器.setChildIndex( 显示对象, 新的深度值 );

五、访问子对象

Egret 提供两种访问容器子对象的方法: getChildAt() 和 getChildByName() 方法。

容器.getChildAt( 深度值 );
容器.getChildByName( 显示对象 )

【注】:通过深度值和 name 属性获取子对象的作用是相同的,但Egret在内部的实现原理却大大不同。

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

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

 

posted @ 2018-12-17 11:14  麦田里的小王子  阅读(891)  评论(0编辑  收藏  举报