2

显然,在 Adob​​e 的智慧中,被蒙版的对象和蒙版对象都包含“蒙版”属性。这会导致循环参考,从而阻止确定哪个是实际掩码,哪个是被掩码。

例如...

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"

我已经遍历了clip和的属性,boundary似乎没有什么独特之处可以将它们区分开来。我的第一个想法是强制删除 中多余的“掩码”引用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 参考之后,很明显,在缓存时,掩码需要是掩码的子项,但是......具有与掩码相同深度的掩码也是有效的(当面具不需要与被掩盖的内容一起旅行时,我会不时这样做)。

例如...

MainTimeline ¬
    0: clip ¬
        0: boundary

...也可以布置为...

MainTimeline ¬
    0: clip ¬
    1: boundary

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

4

2 回答 2

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']让这个接受Shapes,但显然不是超级有效。我不确定最好的方法是什么,除了添加一个接口。

于 2013-04-17T21:28:19.147 回答
1

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

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

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

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

显然还是不理想。

于 2013-04-16T19:53:43.350 回答