【问题标题】:Flash AS3: ArgumentError: Error #2025: The supplied DisplayObject must be a child of the callerFlash AS3:ArgumentError:错误 #2025:提供的 DisplayObject 必须是调用者的子对象
【发布时间】:2012-01-27 06:29:10
【问题描述】:

我正在尝试创建幻灯片样式的演示文稿,其中每张幻灯片/页面都是一个影片剪辑,它们通过滑动动画进行过渡。 我遇到的问题是我不希望舞台上的所有影片剪辑都同时出现以防止滞后问题,这是我想要实现的一个示例:

  • 当前页面为页面 A,点击下一步按钮
  • 页面 B 使用 addChild 放置在舞台上(但放置在视野之外)
  • 页面 A 滑出可见舞台
  • 页面 B 滑入可见阶段
  • 页面 A 使用 removeChild 从阶段中删除 - 这是我遇到问题的地方。
//greensock stuff
import com.greensock.*;
import com.greensock.easing.*;

//buttons that navigate to next and previous slides
prevBtn.addEventListener(MouseEvent.CLICK,prevClicked,false,0,true);
nextBtn.addEventListener(MouseEvent.CLICK,nextClicked,false,0,true);

//setting up array of all the pages
var pageArray:Array = [page1, page2, page3, page4, page5];
var currentArray:Number = 0;

//defining the first page and placing it on the stage
var currentPage:MovieClip = new pageArray[currentArray];
addChild(currentPage);



function nextClicked(event:MouseEvent):void{
    //check to ensure it is not the last page
    if (currentArray < pageArray.length - 1){
            //define the current slide as oldPage
            var oldPage:MovieClip = new pageArray[currentArray];
            currentArray++;
            //define the next slide as currentPage and place on stage
            var currentPage:MovieClip = new pageArray[currentArray];
            addChild(currentPage);
            currentPage.x = 1024;
            TweenMax.to(currentPage, 1, {x:0});
            TweenMax.to(oldPage, 1, {x:-1024,onComplete:removeChild,onCompleteParams:[oldPage]});
    }
}



function prevClicked(event:MouseEvent):void{
    //check to ensure it is not the first page
    if (currentArray > 0){
            //define the current slide as oldPage
            var oldPage:MovieClip = new pageArray[currentArray];
            currentArray--;
            //define the next slide as currentPage and place on stage
            var currentPage:MovieClip = new pageArray[currentArray];
            addChild(currentPage);
            currentPage.x = -1024;
            TweenMax.to(currentPage, 1, {x:0});
            TweenMax.to(oldPage, 1, {x:1024,onComplete:removeChild,onCompleteParams:[oldPage]});    }
}

【问题讨论】:

    标签: flash actionscript-3 contains removechild gsap


    【解决方案1】:

    您的“oldPage”可能尚未添加到舞台/电影剪辑中,就像刚开始时一样。

    所以而不是:

    TweenMax.to(oldPage, 1, {x:-1024,onComplete:removeChild,onCompleteParams:[oldPage]});
    

    考虑在删除之前先检查孩子是否仍然存在。这需要调用一个新函数,例如:

    (未经测试的代码)

    TweenMax.to(oldPage, 1, {x:-1024,onComplete:tryRemoveChild,onCompleteParams:[oldPage]});
    
    function tryRemoveChild(page:MovieClip):void {
       if(contains(page)){ //Check if child is still there
           removeChild(page); //It is, so remove
       } //Otherwise there is no child to currently remove
    }
    

    【讨论】:

    • 我认为这是我出错的地方 - 我从来没有在任何时候真正将“oldPage”添加到舞台上,我试图将“currentPage”重命名/重新定义为“oldPage”所以在对它使用 removeChild 之前,我可以将其补间到左侧,但这是行不通的。
    【解决方案2】:

    当您实例化 oldPage 时,您正在创建该类的一个新实例(或者至少在我看来是这样)。该页面与舞台上的页面不同。

    在您的构造函数中,将变量 currentPage 设置为舞台上页面的实例变量(您在对象属性中调用的任何内容)。然后,在您的 nextClicked 中,将 currentPage 存储在 oldPage 中,然后再将其重置为添加的新页面。

    FWIW,约定是类名总是大写的。如果您这样做了,就更容易确定 page1、page2 等是您正在实例化的类。

    另外请注意,如果在启动时没有实例在舞台上,您可能不会节省太多,因为它们是在第 1 帧之前编译到电影中的。即使您取消选中“嵌入第 1 帧”按钮,通过引用它们在第 1 帧编译的 Class 文件中,强制它们在第 1 帧编译。

    ======================================= 编辑以回答有关将变量设置为实例的问题

    如果您在 fla 文件中单击舞台上的对象,则在属性面板中查看实例名称。那是您在舞台上的实例的名称。如果它没有名字,给它一个。如果您启用了“自动声明阶段实例”,则一切就绪。如果没有,您需要在文件顶部添加变量声明,以使该实例名称可用作变量。

    现在,在您的 fla 文件的 Document Class 中(我假设这是您在上面粘贴的代码):

    public function YourDocumentClassName() {
        super();
        currentPage = theNameofThatInstance;
    }
    

    nextClicked 会变成这样:

    function nextClicked(event:MouseEvent):void{
         //check to ensure it is not the last page
         if (currentArray < pageArray.length - 1){
                 //define the current slide as oldPage
                 var oldPage:MovieClip = currentPage;
                 currentArray++;//may also want to consider checking for past the end of the array and starting at the beginning
                 //define the next slide as currentPage and place on stage
                 var currentPage:MovieClip = new pageArray[currentArray];
                 addChild(currentPage);
                 currentPage.x = 1024;
                 TweenMax.to(currentPage, 1, {x:0});
                 TweenMax.to(oldPage, 1, {x:-1024,onComplete:removeChild,onCompleteParams:[oldPage]});
         }
     }
    

    我猜如果你的图形很大或者它们会移动,你可能会在舞台上遇到不止一个的性能问题,但我认为你试图解决加载问题。

    【讨论】:

    • 如何将curentPage 设置为舞台上的实例变量?我以为我是这样做的: var currentPage:MovieClip = new pageArray[currentArray];但相反,我认为我可以使用返回 page1、page2 等的数组来设置它。而且当我在任何给定时间在舞台上有多个 mc 而不是只有一个时,我似乎得到了显着的 FPS 差异。我在每个 mc 中都有不断的补间。
    猜你喜欢
    • 1970-01-01
    • 2013-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-08
    • 2023-03-13
    • 2012-02-29
    • 1970-01-01
    相关资源
    最近更新 更多