In this tutorial I will show you how depth sorting works in OpenFL and how to sort Sprites based on their Y value.
OpenFL employs a DispayList pattern which people coming from AS3 will be familiar with.
All Sprites added using the addChild() method to a container (which is also visible) are sorted by their indices, which are set automatically when you add new Sprites.
Each newly added Sprite is placed on top of everything else, with its index being the biggest. Indices in OpenFL can be swapped and set explicitly using various methods.
Take a look at the following example:
red = new Sprite();
red.graphics.beginFill(0xff0000);
red.graphics.drawRect(0, 0, 100, 100);
red.graphics.endFill();
blue = new Sprite();
blue.graphics.beginFill(0x0000ff);
blue.graphics.drawRect(0, 0, 100, 100);
blue.graphics.endFill();
blue.y = 50;
blue.x = 50;
addChild(red);
addChild(blue);
Since the blue sprite was created the last, it is placed on top of the first one.
You can explicitly set a child's index using setChildIndex() method of the parent. In this case we take the red sprite and put it on top:
this.setChildIndex(red, this.numChildren - 1);
The same can be achieved by swapping the indices of the two children:
this.swapChildren(red, blue);
2D games with some sort of perspective often sort the depth of the children by their Y coordinate. To achieve this, first create a new array of Sprites:
var sortableChildren:Array<Sprite>;
Add all the children that you want to sort to this array. I also add an animation using Actuate to demonstrate the depth sorting in real time.
Actuate.tween(red, 1, { y: 100 }, true).repeat( -1).reflect(true).ease(Quad.easeInOut);
sortableChildren = new Array<Sprite>();
sortableChildren.push(red);
sortableChildren.push(blue);
I want to update the depth sorting every frame so I add a new listener:
addEventListener(Event.ENTER_FRAME, update);
And simply sort all the items inside sortableChildren by their Y coordinate. I needed to write a custom sorting function for this.
private function update(e:Event):Void {
sortableChildren.sort(sortByY);
var i:Int;
for (i in 0...sortableChildren.length) {
setChildIndex(sortableChildren[i], i);
}
}
private function sortByY(a:Sprite, b:Sprite):Int {
if (a.y == b.y) return 0;
if (a.y > b.y) return 1;
return -1;
}
Easy!