如何确定给定对象是否是掩码

时间:2013-04-16 18:40:22

标签: actionscript-3 mask

显然,在Adobe的智慧中,作为掩码的对象和掩蔽对象都包含“掩码”属性。这会导致循环引用,阻止确定哪个是实际掩码,哪个是掩码。

例如......

var clip:MovieClip = new MovieClip();
clip.name = "clip";
addChild(clip);

var boundary:Shape = new Shape();
boundary.name = "boundary";
clip.addChild(boundary);

clip.mask = boundary;

trace(clip.mask.name); // outputs "boundary"
trace(clip.mask.mask.name); // outputs "clip"

我已经遍历了clipboundary的属性,并且似乎没有任何独特的东西将它们区分开来。我的第一个想法是强制删除boundary中多余的“掩码”引用,但是,它还将mask中的clip属性设置为null,从而删除掩码。

我的第二个想法是检查面具的父关系。如果父对象与对象的掩码相同,则所讨论的对象本身就是掩码。

var a:Array = [clip, boundary];

for each (var item in a) {
    if (item.mask == item.parent) {
        trace(item.name + " is a mask");
    }
}

// outputs "boundary is a mask"

似乎工作,并且在检查了掩码上的API reference之后,很明显当缓存时,掩码会需要成为蒙面的孩子,但是......它也是有效的掩码与掩盖的深度相同(当掩模需要使用蒙版内容不行进时,我会不时这样做。)

例如......

MainTimeline ¬
    0: clip ¬
        0: boundary

......也可以列为......

MainTimeline ¬
    0: clip ¬
    1: boundary

所以,有一个难题。关于如何解决这个问题的任何想法?

2 个答案:

答案 0 :(得分:2)

到目前为止,我发现的“最佳”黑客是在对象上运行hitTestPoint(确保它们在目标下有目标)。面具似乎没有返回true进行全像素点击测试。这似乎适用于我测试的大多数基本情况:

public function isMask(displayObject:DisplayObject):Boolean {

    // Make sure the display object is a Class which has Graphics available,
    // and is part of a mask / maskee pair.
    if ((displayObject is Shape || displayObject is Sprite) && displayObject.mask) {

        // Add a circle at the target object's origin.
        displayObject['graphics'].beginFill(0);
        displayObject['graphics'].drawCircle(0, 0, 10);

        var origin:Point = displayObject.localToGlobal(new Point());
        var maskLocal:Point = displayObject.mask.globalToLocal(origin);

        // Add a circle at the same relative position on the "mask".
        displayObject.mask['graphics'].beginFill(0);
        displayObject.mask['graphics'].drawCircle(maskLocal.x, maskLocal.y, 10);

        // No matter which is the actual mask, one circle will reveal the other,
        // so hit testing the origin point should return true.
        // However, it seems to return false if the object is actually a mask.
        var hit:Boolean = displayObject.hitTestPoint(origin.x, origin.y, true);

        displayObject['graphics'].clear();
        displayObject.mask['graphics'].clear();

        // Return true if the hit test failed.
        return !hit;
    } else {
        return false;
    }
}

显然你想要缓存graphics,以防对象已经有一些,,它可以做一些比铸造Sprite更优雅的东西,以便它可以处理Shapes,但这是一个开始。

编辑:访问['graphics']可以接受Shape,但显然效率不高。我不确定最好的方法是什么,没有添加接口。

答案 1 :(得分:1)

很好的问题,之前没有遇到过这个问题。我不知道周期性参考。

如果您的面具是专门的面具,我建议您将其纳入您的命名约定。例如,将其称为clipMask而不是边界。

如评论中所述,在掩码位于同一显示列表的情况下,您可以使用getChildIndex()来比较它们在父级的显示列表中的位置。

通常情况下,我会将遮罩层叠在另一个显示对象上。这显然没有强制执行,我不相信它会对视觉效果产生任何影响。但是对于大型组来说,维护比命名约定更容易。

显然还不理想。