【问题标题】:visible property of DisplayObjectDisplayObject 的可见属性
【发布时间】:2009-11-06 00:08:26
【问题描述】:

例如,我有一个影片剪辑层次结构。 mc1 是 mc 的孩子,mc2 是 mc1 的孩子。 原来,当我设置时

    mc1.visible = false;

mc2.visible 保持为真。

这应该发生吗? 是否有测试 mc2 可见性的捷径?


要玩的代码:

var mc = new Sprite();

mc.graphics.beginFill(0xFF0000);
mc.graphics.moveTo(50,50);
mc.graphics.lineTo(100,50);
mc.graphics.lineTo(100,100);
mc.graphics.lineTo(50,100);
mc.graphics.endFill();

var mc1 = new Sprite();
mc1.graphics.beginFill(0x00ff00);
mc1.graphics.moveTo(150,150);
mc1.graphics.lineTo(200,150);
mc1.graphics.lineTo(200,200);
mc1.graphics.lineTo(150,200);
mc1.graphics.endFill();
mc.addChild(mc1);

var mc2= new Sprite();
mc2.graphics.beginFill(0x0000ff);
mc2.graphics.moveTo(250,150);
mc2.graphics.lineTo(200,150);
mc2.graphics.lineTo(200,200);
mc2.graphics.lineTo(250,200);
mc2.graphics.endFill();
mc1.addChild(mc2);

stage.addChild(mc);

mc1.visible = false;

function myOnEnterFrame(e){
    trace(mc2.hitTestPoint(mouseX, mouseY));
}

stage.addEventListener(Event.ENTER_FRAME, myOnEnterFrame);

结果: mc2.visible 仍然是真的。 hitTest 仍会为 mc2 触发。

除了迭代父母,还有其他方法可以测试舞台上 mc2 的存在吗?

【问题讨论】:

  • 只是一个不相关的小说明:查看 graphics.drawRect(x,y,w,h) 方法;)
  • 是的,专注于一件事让我忽略了显而易见的 =)

标签: flash actionscript-3


【解决方案1】:

如果父级的visible 属性设置为false,则它的所有子级都不会在舞台上可见。但这并不意味着孩子的 visible 属性会自动设置为 false - 它们将继续保持其原始值。

简而言之,具有 visible 属性 trueDisplayObject 不必在舞台上可见 - 它也取决于其父级的 visible 值。但是如果一个对象的visible设置为false,无论如何它都不会是可见的。

编译下面的代码,点击文本框可以更好的理解。文本字段将变得不可见(因为它的父级的 visible 设置为 false),但它自己的 visible 属性仍然是 true

private var sprite:Sprite;
private var tf:TextField;
public function init():void
{
    sprite = new Sprite();
    addChild(sprite);
    tf = new TextField();
    tf.text = "sometext";
    sprite.addChild(tf);
    sprite.addEventListener(MouseEvent.CLICK, onClick)
}
private function onClick(e:MouseEvent):void
{
    sprite.visible = false;
    trace(tf.visible);//traces true - but tf is not displayed.
}

更新以回答 clorz 关于如何检查对象是否可见的问题:

function isVisible(t:DisplayObject):Boolean
{
    if(t.stage == null)
        return false;
    var p:DisplayObjectContainer = t.parent;
    while(!(p is Stage))
    {
        if(!p.visible)
           return false;
        p = p.parent;
    }
    return true;
}

【讨论】:

  • 这是正确的。我误读了这个问题,认为 MovieClip 仍在显示,而不是属性的实际值。
  • 那么如何测试对象在场景中是否可见?
  • 你将不得不遍历它的父级一直到舞台并检查可见属性 - 如果其中至少一个为假,则它不可见。
  • 好的,你知道 hitTestPoint 是否考虑了父母的可见性吗?那么,如果 parent visible 设置为 false,孩子的 hitTestPoint 是否仍会评估为 true?
  • 我相信hitTestPoint 会考虑到可见性;毕竟,一个物体怎么会撞到一个看不见的物体——或者可以吗?文档说将 visible 设置为 false 使其无效(没有鼠标事件等),但没有说明命中测试。如果可以,请进行测试并发布结果。
【解决方案2】:

是的,设置为 visible=false 的父级的子级也将被隐藏。它遵循简单的层次结构。

您可以随时通过

测试可见状态
if(uiObject.visible) ...

您也可以始终设置 alpha = 0,但在内存管理方面,如果您要处理大量对象,最好将对象移出舞台。

更多信息in this article

【讨论】:

  • 感谢您的文章,但这并不是我真正需要的。我已经改变了问题。
【解决方案3】:

不,这不应该发生。如果您隐藏父 MovieClip,则子项也将始终被隐藏。我的猜测是,要么 mc2 不是 mc1 的孩子,要么你在其他地方引用了另一个剪辑,也称为 mc1。

【讨论】:

  • 这个答案不正确。 mc2 将被隐藏,但它的 visible 属性仍然为 true。
【解决方案4】:

是的,这应该会发生。在这种情况下,层次结构发挥了作用。您将 mc1 的可见设置为 false,这会使 mc1 不可见,并且由于 mc2 是 mc1 的子级,因此它也会消失。 (换句话说,mc2 在 mc1 中可见或不可见)。因此,如果针对 mc1 将 visible 重置为 true,则 mc2 也会根据其 visible 属性显示。

【讨论】:

    【解决方案5】:

    这是我创建的一个递归函数,它接受一个孩子并向上遍历层次结构,直到它用完 DisplayObjects。如果一路上找到一个不可见的父级,则返回 false,但如果所有父级都可见,则返回 true:

    function allParentsVisible(obj:DisplayObject):Boolean{
        //trace("\r--- Test for visibility ---");           
        var counter:Number = 0;
        var safetyLimit:Number = 10;
        var parent:DisplayObject = obj;
        var allVisible:Boolean = true;
    
        doTest();
    
        function doTest(){
            parent = parent.parent;
            if(parent && counter < safetyLimit){
                if(!parent.visible) allVisible = false;     
                doTest();
            }else{
                return;
            }
            counter ++;
        }
        return(allVisible);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-27
      • 2015-12-07
      • 2014-08-20
      • 1970-01-01
      • 2011-01-18
      • 1970-01-01
      • 2018-03-13
      相关资源
      最近更新 更多