显示容器 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。 如何使用 创建一个实现ILayoutGroup的布局组并设置布局属性。 将一些显示对象或其他ILayoutElement添加到组中。 调用组的layout()方法。 布局组 ( ) HFillLineLayout – 水平...
开发Flash网络游戏需要掌握的技术,一个游戏离不开显示,AS3已经...学习这个部分,学习显示列表,学习DisplayObject和DisplayObjectContainer的区别,学习Shape, Sprite, MovieClip, Bitmap这些基本可显示对象的区别。
此扩展添加了带有图层的特殊类型的DisplayObjectContainer。 开发人员可以将多个DisplayObject链接在一起,并整体上控制它们的转换。 这种显示逻辑非常适合具有自顶向下视图的游戏。 考虑以下示例: const TORSO_...
import flash.display.DisplayObjectContainer; import flash.display.MovieClip; import flash.events.MouseEvent; import flash.events.Event; public class LtouchScroll{ public var tween:Number = ...
The APEngine.container property is now of type DisplayObjectContainer, not Sprite. Renamed 'rotation' to 'radian' in RectangleParticle to be consistent with SpringConstraint. Thanks to Robert Brisita ...
Kinetic2Pixi 该项目描述了 KineticJs 应用程序到 PixiJs 的迁移阶段动力学 var stage = new Kinetic.Stage();皮西 var stage = new PIXI.Stage(0x66FF99);...PIXI.DisplayObjectContainer 事件监听器通过 PIXI.
StarlingFeathers #####整合Starling+Feathers 还有一些Starling扩展 #####Starling 1.7.1+ Feathers 2.0.1 ...3.为DisplayObjectContainer添加了3个方法 addQuiackChild()快速添加子对象 removeQuickC
对于DisplayObjectContainer,可以直接设置这些属性,而对于Transitionable,则可以设置许多状态,以定义这些属性的可能值。 然后,您可以在这些状态之间转换,并且将补间这些属性以平滑地进行动画处理。 例如: ...
图形引擎 SEB-OGP第10课第10周GraphicsEngine作业。 这项任务的目的是开发基于UML类图和序列图的应用程序。...DisplayObjectContainer的实现 2个新矩形 5_adjustment_interface分支: 自定义IRreader
AS3有内置的抽象类如 DisplayObjectContainer,大家可以尝试去用来测试实例化,继承的可行性。 说到这里,其实还是没有说明接口存在的必要性。显 然,上面的形状和文本类,即使没有“抽象类”和接口,两个类照样可以...
class Main extends egret.DisplayObjectContainer{ //申明一个广播对象“dispatchSprite” private dispatchSprite: egret.Sprite; public constructor() { super(); //字典使用对象作为key引用存储数据.对象...