开发一个简单的Z轴排序器

Q:为什么要开发Z轴排序器?

A:因为地球人都知道,Flash 10中的3D太弱,仅仅通过内置的3D有很多功能还实现得很不完善!

何为Z轴排序器?

就是根据Z轴坐标来确定一个DisplayObject的深度,从而达到视觉上真正达到:“离屏幕远的物体在后面,近的在前面”这个效果。

首先我们才创建一个简单的排序器,并分析下其不足:

public class ZIndexSorter{

public static function sort(container:DisplayObjectContainer):void

{

var children_arr:Array = [];

for(var i:uint=0; i<container.numChildren; i++){

var d:DisplayObject = container.getChildAt(i);

var tM:Matrix3D = displayObject.transform.getRelativeMatrix3D(stage);

//把对应获得的数据Push到数组中准备排序

children_arr.push({

"displayObject": d,

"z": tM.position.z

});

}

children_arr.sortOn("z", Array.NUMERIC | Array.DESCENDING);

var j:uint = 0;

while(j < children_arr.length){

container.setChildIndex(children_arr[j].displayObject, j);

++j;

}

}

}

很简单,先把子显示对象全部获取到,然后算出对应舞台的Z轴坐标,然后排序!并且根据排序来重新设置深度。

不从效率上考虑此代码,存在什么缺陷?!

以CoverFlow效果而言,处在同一个Z轴上的封面对于这种算法是失效的,不能准确地算出其应该处于的位置。

那么这段代码应该如何更改恩?

很简单,加多一个因素:

public class ZIndexSorter{

public static function sort(container:DisplayObjectContainer):void

{

var children_arr:Array = [];

for(var i:uint=0; i<container.numChildren; i++){

var d:DisplayObject = container.getChildAt(i);

var tM:Matrix3D = displayObject.transform.getRelativeMatrix3D(stage);

//把对应获得的数据Push到数组中准备排序

children_arr.push({

"displayObject": d,

"z": tM.position.z,

"x": Math.abs(tM.position.x - stage.stageWidth / 2)

});

}

children_arr.sortOn("z", Array.NUMERIC | Array.DESCENDING);

children_arr.sortOn("x", Array.NUMERIC | Array.DESCENDING);

var j:uint = 0;

while(j < children_arr.length){

container.setChildIndex(children_arr[j].displayObject, j);

++j;

}

}

}

加多了两行代码来权衡Index,首先我们以Stage的中点作为视觉中点,离中点越远,那么则索引越靠后, 当然这里只是抛砖引玉,实际上还应该计算Y轴中点距离判断。

各位看官应该从这里就能知道自己的Z轴排序器的优化方向,根据需要写出比上面高效得多的代码。

下次分享下Flash Player 10中的强大Text渲染引擎!

loading...