如何追踪显示对象的“深度”或堆叠顺序?

时间:2011-03-24 15:42:39

标签: actionscript-3

如何使用AS3跟踪显示对象的“深度”或堆叠顺序?

我正在试图弄清楚我的精灵是否落后于另一个精灵......

6 个答案:

答案 0 :(得分:7)

container.getChildIndex(displayObject);

但这只会告诉你它有多深,不一定是它前面有任何东西。

答案 1 :(得分:2)

比较两个DisplayObject实例以确定哪一个在显示列表上的“深度”更高的函数:

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;
}

注意:如果其中一个对象不在显示列表中,则该函数返回null。您可以更改它以返回其他对象。

你几乎可以肯定地优化它,但这是第一次削减。

答案 2 :(得分:2)

只是使用向量的Manish回答的重构版本,如果你打电话给更高的(a,a.parent),它将不会返回奇怪的结果。

parents()也可用于其他目的:

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;
}

答案 3 :(得分:0)

container.getChildIndex(child)应该这样做,它会返回孩子的索引

答案 4 :(得分:0)

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;
}

答案 5 :(得分:0)

这是jaubouxManish所做的修订版本 即,在深度匹配时,从null添加highestOf()返回值。

/**
 * @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;
}