How can you trace the "depth" or stacking order of a display object with AS3?
I'm trying to figure out开发者_如何学Go if my sprite is behind another sprite...
container.getChildIndex(displayObject);
but that will only tell you how deep it is, not necessarily if anything is in front of it.
Function comparing two DisplayObject instances to determine which one is at a higher "depth" on the display list:
private function higher(a:DisplayObject, b:DisplayObject):DisplayObject
{
// Parent chains
var ac:Array = [a];
var bc:Array = [b];
// Pointers to individual nodes
var an:DisplayObject = a.parent;
var bn:DisplayObject = b.parent;
while (an != null) {
ac.push(an);
an = an.parent;
}
while (bn != null) {
bc.push(bn);
bn = bn.parent;
}
var acl:int = ac.length;
var bcl:int = bc.length;
var n:int = Math.min(acl, bcl);
var i:int = 0;
for (; i < n; i++) {
an = ac[acl - i - 1];
bn = bc[bcl - i - 1];
// First uncommon ancestor
if (an != bn)
break;
}
var ca:DisplayObjectContainer = an.parent;
if (!ca)
return null;
if (ca.getChildIndex(an) > ca.getChildIndex(bn))
return a;
else
return b;
}
Note: If one of the objects is not on the display list, the function returns null
. You can change it to return the other object instead.
You can almost certainly optimize this, but this is a first cut.
Just a refactored version of Manish answer using vectors and which won't return weird result if you ever call higher(a,a.parent).
parents() may be used for other purpose too :
public function higher(a:DisplayObject, b:DisplayObject):DisplayObject
{
var aParents:Vector.<DisplayObject> = parents(a);
var bParents:Vector.<DisplayObject> = parents(b);
var commonDepth:int = Math.min(aParents.length, bParents.length);
for (var depth:int = 0; depth < commonDepth; depth++)
if (aParents[depth] != bParents[depth])
break;
if (depth == 0 || depth == commonDepth)
return null;
var commonAncestor:DisplayObjectContainer = aParents[depth].parent;
if (commonAncestor.getChildIndex(aParents[depth]) > commonAncestor.getChildIndex(bParents[depth]))
return a;
else
return b;
}
private function parents(d:DisplayObject):Vector.<DisplayObject>
{
var result:Vector.<DisplayObject> = new Vector.<DisplayObject>;
while (d != null)
{
result.unshift(d);
d = d.parent;
}
return result;
}
private function getDepth(clip:DisplayObject):uint
{
var depth:uint = 0;
var currentClip:DisplayObject = clip;
while (currentClip.parent && currentClip.parent != this)
{
depth++;
currentClip = currentClip.parent;
}
return depth;
}
container.getChildIndex(child)
should do it, it returns the index of the child
This is a revised version of what jauboux did from a version Manish did.
Namely, adding a null
return value from highestOf()
when depths match.
/**
* @param ifDepthsMatchReturnObjectA
* @return Whichever DisplayObject is higher on the display list.
* Optionally returns `null` if they're at the same depth.
*/
public function highestOf(a:DisplayObject, b:DisplayObject, ifDepthsMatchReturnObjectA:Boolean = false):DisplayObject
{
var aParents:Vector.<DisplayObject> = ancestorsOf(a);
var bParents:Vector.<DisplayObject> = ancestorsOf(b);
var commonDepth:int = Math.min(aParents.length, bParents.length);
for (var depth:int = 0; depth < commonDepth; depth++)
if (aParents[depth] != bParents[depth])
break;
if (depth == 0 || depth == commonDepth)
return null;
var commonAncestor:DisplayObjectContainer = aParents[depth].parent;
var aDepthOnCommonAncestor:int = commonAncestor.getChildIndex(aParents[depth]);
var bDepthOnCommonAncestor:int = commonAncestor.getChildIndex(bParents[depth]);
if (aDepthOnCommonAncestor > bDepthOnCommonAncestor)
return a;
else if (aDepthOnCommonAncestor < bDepthOnCommonAncestor)
return b;
else
return ifDepthsMatchReturnObjectA ? a : null;
}
/**
* @return Whether a is higher than b.
*/
public function isHigher(a:DisplayObject, b:DisplayObject):Boolean
{
return highestOf(a, b) === a;
}
/**
* @return All ancestors of given display.
*/
private function ancestorsOf(display:DisplayObject):Vector.<DisplayObject>
{
var result:Vector.<DisplayObject> = new Vector.<DisplayObject>;
while (display != null)
{
result.unshift(display);
display = display.parent;
}
return result;
}
精彩评论