as3 - 如何对不断切换深度的显示对象进行排序?

as3 - How to sort display objects that constantly switch depths?

我有一款 2.5D 游戏(像 3D 游戏一样运行的 2D 游戏),您可以不断切换深度,当玩家走在物体前面和走在物体后面时,玩家会显示在物体顶部,该对象显示在播放器的顶部。就像当玩家的 y 小于物体的 y 时,玩家会走到物体后面,反之亦然。

我尝试使用这样的代码:

if (player.y < block.y)
{
    setChildIndex(block, numChildren - 5);
}
else if (player.y > block.y)
{
    setChildIndex(block, numChildren - 10);
}

但是,我发现如果我多次这样做,我将需要大量代码,并且显示列表会混淆并以错误的顺序对错误的深度进行排序。谁能用最少的代码展示一个有组织的深度转换器?

使用 z-index stack sorting, (also refered as z-buffer in the 3D graphics literature) the same used to create the 3D depth effect using just 2D techniques.

换句话说,为每个对象分配一个 zIndex 并定期(例如 onEnterFrame 事件)运行 一个 zsort 例程,该例程对(的顺序)进行排序根据 zIndex 值显示对象。或者,您可以 运行 zsort 手动例程,每次在对象上发生 zIndex 的更改时。

然后在您的代码中,您只需将 zIndex 值分配给显示对象以模拟一个对象通过 in-front 或在另一个对象后面,然后 zsort 负责其余部分。

这里的一个技巧是在zIndex赋给对象的值中有适当的空隙(即不一定是下一个zIndex+1),这样就可以在这些空隙之间放置对象来模拟传入在其他物体的前面或后面,无需每次调整一个以上的zIndex值,即你只调整一个zIndex 通过 in-front 或在另一个对象后面的对象的值,而不是另一个对象的 zIndex

连续 zIndexes 之间的间隙量可以根据 在任何给定时间可能位于这些对象之间的(其他)对象的最大数量 (所以例如,如果最多 3 个对象可能在某个时间在 in-front 之间移动或在任何给定对象后面移动,则连续 zIndexes 的间隙值为 3这样所有的物体都可以容纳)

这是一个非常简单的 zsorter 例程,它 运行 定期 onEnterFrame 事件并为您进行必要的深度排序(来自下面的参考资料 1)

package {

 import flash.display.*;
 import flash.events.*;

 public class DepthSortSpace extends MovieClip {

  public function DepthSortSpace() {
   super();
   this.addEventListener( Event.ADDED_TO_STAGE, this.addedToStage, false, 0, true );
  }

  private function addedToStage( e:Event ) {
   this.stage.addEventListener( Event.ENTER_FRAME, this.enterFrame, false, 0, true );
  }

  private function sortDisplayList():void {
   var len:uint = numChildren;
   var i,j;
   for( i=0; i < len-1; i++ )
    for (j=i+1; j < len; j++)
     if ( getChildAt(i).y > getChildAt(j).y ) this.swapChildrenAt( i, j );
  }

  private function enterFrame(e:Event) {
   this.sortDisplayList();
  }

 }
}

上面的 zsorter 是 in-fact 一个 movieClip,它充当 scene 容器,因为您将显示对象添加到 zsorter 影片剪辑这需要注意相应地对它们进行排序,但是可以只采用 zsort 例程并将其应用于任何 DisplayObjectContainerScene 对象实例。

注意,上面的zsorter使用了bubbleSort sorting algorithm, which has a O(n^2) complexity, but one can use another sorting algorithm (e.g mergeSort,复杂度O(n lgn)

示例和参考资料

  1. http://nephilim.blogspot.gr/2010/06/easy-depth-sorting-in-actionscript-3.html
  2. http://www.actionscript.org/forums/actionscript-3-0-a/169035-sorting-technique.html
  3. http://www.simppa.fi/blog/the-fastest-way-to-z-sort-and-handle-objects-in-as3/