【问题标题】:Switching of depths causes duplication of MC切换深度会导致 MC 重复
【发布时间】:2011-02-24 03:15:23
【问题描述】:

这是对上一个问题的重新发布,这次提供了更多信息。

文件:2shared.com/file/hRKhEiqh/Script_Test.html2shared.com/video/UZNmqzXt/a_anconeus.html

在我的机器上使用 Flash Professional CS5 中 Actionscript 3.0 中的新 .fla 项目时,可以重现此问题。这是对我的原始问题的编辑,包含更多信息。

我正在做一个项目来加载外部 SWF 并通过实例名称搜索匹配的关键字,即“拖动”和“拖放”来识别电影剪辑匹配,然后将事件侦听器附加到这些包含 D&D 事件侦听器和代码。

具体问题是嵌套在动态加载的外部 SWF 文件中的影片剪辑的深度切换。

我遇到问题的地方是具体的命令:

swapChildrenAt、setChildIndex、swapChildren、removeChild/addChild。我已经尝试了所有四个相同的重复问题。让我解释一下。

单击可拖动的 MC 时,它会移动到动态加载的 SWF 的顶部索引,因此它在该 SWF 中的所有其他内容之上可见。问题是尝试这些命令中的任何一个都会重复 MC。会发生什么:

在 MC 上触发 MOUSE_DOWN 事件: 目标MC的索引记录为'2',我们将切换到的索引是'20'(SWF的最大索引) 在目标 MC 父级上调用 setChildIndex: mc.parent.setChildIndex(mc, (mc.parent.numChildren-1)) MC 移动到索引 20,然后在它之前所在的层(索引 2)创建另一个 MC 实例,这发生在 MOUSE_DOWN 事件完成后,我不确定确切的时间。

已使用附加到舞台的 EVENT.ADDED_TO_STAGE 侦听器确认此副本,以捕获添加到舞台的每个 MovieClip 类型的对象。我检查了 SWF 以确认没有重复的 MovieClips,痕迹也证实了这一点。

类似的帖子提到了相同的重复问题,但没有人有我发现的解决方案适用于我的情况。

http://www.kirupa.com/forum/showthread.php?t=359452 http://board.flashkit.com/board/showthread.php?t=775200 http://forums.adobe.com/thread/199983

最后一点,如果我注释掉索引交换语句,代码与 MC 完美配合,只需保持在其较低的 z-index 上而不是在顶部。不幸的是,由于我没有构建外部 SWF,因此这不会作为解决方案起作用。

要复制此行为,您需要一个外部 AS3 SWF,其中包含两个至少两个 MC,实例名称为“drag01”和“drop01”或与关键字“drag”和“drop”匹配的名称。将字符串变量“SWF”指向该文件,您应该会看到重复问题。

感谢和问候 卡梅伦

编辑:新的修剪代码,复制到一个空白的 AS 3.0 文件中,错误相同。

    import flash.net.URLRequest;
import flash.display.Loader;
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.display.MovieClip;
import flash.display.DisplayObject;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.net.URLLoader;




var swf:String = "a_anconeus.swf";
loadSWF(swf);

stage.addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStageReport, true);
stage.addEventListener ( Event.ADDED_TO_STAGE , onAddedToStageReport , true ) ;

function onRemovedFromStageReport (evt:Event)
{
    {
        trace("REMOVED: " + evt.target.name + " at depth: " + evt.target.parent.getChildIndex(evt.target));
    }
}


function onAddedToStageReport (evt:Event)
{
    {
        trace("ADDED: " + evt.target.name + " at depth: " + evt.target.parent.getChildIndex(evt.target));
    }
}

function onDragMouseDown(event:MouseEvent):void
{
    var drag:MovieClip = MovieClip(event.target);
    var topPosition:uint = drag.parent.numChildren - 1;
    trace("click: "+drag.name +", ontarget = "+drag.ontarget + ", current z: " + drag.parent.getChildIndex(drag) + " new z: " + topPosition);
    //drag.parent.setChildIndex(drag, topPosition);
    var indexToDelete:int = drag.parent.getChildIndex(drag);

//this.parent.removeChild(this);
        trace("index to delete: " + indexToDelete +", what's there: " + drag.parent.getChildAt(indexToDelete).name);
        drag.startDrag();
        //drag.parent.setChildIndex(drag, drag.parent.numChildren-1); //set child depth to top
        trace("after change, what's there: " + drag.parent.getChildAt(indexToDelete).name);
        //drag.parent.swapChildren(drag, drag.parent.getChildAt(drag.parent.numChildren -1));


}

function onDragMouseUp(event:MouseEvent):void
{
    trace("mouse up: "+event.target.name + ", index: " +event.target.parent.getChildIndex(event.target));
    var drag:MovieClip = MovieClip(event.target);

    drag.stopDrag(); //Movieclips have simple drag methods

}

/*function dragEnterFrameHandler(event:Event):void {

    var drag:MovieClip = MovieClip(event.target);

    if (drag.mousedown == false)
    {

        if (drag.onTarget == true)
        {
            //send it to the drop X/Y
            drag.x -= (drag.x - drag.dropon.x)/5;
            drag.y -= (drag.y - drag.dropon.y)/5;
        }

        else if (drag.onTarget == false)
        {
            drag.x -= (drag.x - drag.homeX)/5;
            drag.y -= (drag.y - drag.homeY)/5;
        }
    }
}*/



function loadSWF(filepath:String)
{

    trace("calling loader");
    var loader:Loader = new Loader();
    var url:String = filepath;
    loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteHandler);

    loader.load(new URLRequest(url));

}





function onAddedToStage ( evt:Event )
{
    trace("calling onAddedToStage");
    /*if (evt.target is MovieClip) //filter only movieclips
    {
        var mc:MovieClip = MovieClip(evt.target);
       // trace ( "onAddedToStage, evt: " + mc.name + ", " +(mc.parent.numChildren-1) ) ;

        if (String(mc.name).indexOf("drag") != -1) 
        {
            var dropString:String = String(mc.name).split("drag").join("drop");

            if (mc.parent.getChildByName(dropString))
            {
                trace("our droptarget: " + mc.dropon);
                mc.addEventListener(MouseEvent.MOUSE_DOWN, onDragMouseDown);
                mc.addEventListener(MouseEvent.MOUSE_UP, onDragMouseUp);
                mc.buttonMode = true;

            }
        }
    }*/
}

function onCompleteHandler(loadEvent:Event)
{
    trace("load complete");
    var swf:MovieClip = MovieClip(loadEvent.currentTarget.content);
    //swf.addEventListener ( Event.ADDED_TO_STAGE , onAddedToStage, true ) ;
    //trace("event attached, adding child");

trace("child add started");
    addChild(swf);

    trace("child add finished");
    var children:Number = (swf.numChildren-1);
    trace("children: " + children);
    for (var i:Number = 0; i <= children; i++)
    {
        trace("LOOP STARTS HERE");
        if (swf.getChildAt(i) is MovieClip)
        {
            //trace("MC: yes");
            var mc:MovieClip = MovieClip(swf.getChildAt(i));
            trace("name: " + mc.name);

            if (String(mc.name).indexOf("drag") != -1) 
            {
                var dropString:String = String(mc.name).split("drag").join("drop");

                if (swf.getChildByName(dropString))
                {
                    trace("removing: " + mc.name);
                    children--;
                    swf.removeChild(mc);
                    trace("removed");
                    //swf.addChild(mc);


                    /*mc.addEventListener(MouseEvent.MOUSE_DOWN, onDragMouseDown);
                    mc.addEventListener(MouseEvent.MOUSE_UP, onDragMouseUp);
                    mc.buttonMode = true;*/

                }
            }
        }
    }
trace("finish function");
}

【问题讨论】:

  • 你能添加一个链接,我们可以测试这个吗?我经常做类似的事情,我从未见过这种行为。如果它与您加载的 SWF 的设置方式有关,那么尝试用虚拟文件重新创建您的问题将毫无意义...
  • PS:不过我可以说一件事:您的代码包含拼写错误。有时您使用drag.onTarget,有时使用drag.ontarget。由于您总是使用 MovieClip 引用,而且 MovieClip 是动态的,因此编译器不会对此抱怨。但你绝对应该修复它。
  • 我已经尝试了代码,它运行良好,唯一改变的是 swf 文件位置
  • 很高兴知道代码可以正常工作,任何想法是什么让我最终破坏了它?我刚刚打开了一个新的 AS3.0 项目,将代码粘贴进去,它仍然会中断并复制拖动对象 =(

标签: actionscript-3


【解决方案1】:

谜团解开了 :)

查看您的 swf,我可以看到它有两个帧,因此一旦您开始拖动,下一帧就会呈现并且对象会返回。

为了测试这一点,我将 swf.stop(); 添加到你的 onCompleteHandler

【讨论】:

  • 你这个聪明人,你已经解决了。添加 swf.stop();已解决问题,它是一个 2 帧 SWF。我会进行检查以警告用户使用多帧 SWF,感谢您的帮助。
【解决方案2】:

我无法打开您的示例文件,因为我只有 CS3,但我可以告诉您我认为最可能的原因。当您重新设置这些剪辑的父级,然后发现它们重复时,是否有任何时间线播放同时发生?喜欢这个示例 fla?
Unintentional cloning

问题在于,当您从发布它的显示列表中删除一个影片剪辑时,但该显示列表位于正在播放的影片剪辑中,当该剪辑重新播放旧帧时,或以任何其他方式“期望”剪辑在您发布 fla 时的位置,它只是“克隆”它并将其放回......或者更确切地说,它“克隆”它所知道的如果你没有移动它会是.这就是我在上面的 fla 中说明的内容。我重新设置 foo 剪辑的父级,将其随机放置在舞台上的某个位置,然后当影片剪辑循环回到第 1 帧时,它发现“这里应该有一个 foo,但没有。最好制作一个。”

【讨论】:

  • 我确定主 FLA 的第 1 帧上只有一个脚本,外部 SWF 上也没有脚本。跟踪语句希望是一个有用的线索,特别是如果您只删除剪辑而不重新添加它,它会自行出现,并且它会在任何函数之外执行它。不过感谢您的建议,请继续关注。
  • onCompleteHandler 内的movieclip 'swf' 的时间线上有多少帧?超过 1 个吗?
  • 很确定它只有 1 帧,没有动作脚本。
猜你喜欢
  • 2020-06-18
  • 1970-01-01
  • 2011-12-01
  • 2021-03-09
  • 2016-08-24
  • 2023-01-14
  • 2013-06-19
  • 1970-01-01
  • 2020-07-24
相关资源
最近更新 更多