从数组中精简 add/remove 个子 MovieClip

Streamline add/remove child MovieClips from an array

我目前正在尝试根据过去几个月我一直在研究的几个教程制作一个交互式故事书,但在我继续扩展项目之前,我想更改一些内容和精简。下面是原教程的简化版,之后是我目前正在修改的地方。

    package
    {
        import flash.display.MovieClip;
        import flash.events.MouseEvent;

        public class Main_Test extends MovieClip
        {
            var startPage:StartPage;
            var hillPage:HillPage;
            var pondPage:PondPage;

            public function Main_Test()
            {
                startPage = new StartPage;
                hillPage = new HillPage;
                pondPage = new PondPage;
                addChild(startPage); 

                // add event listeners
                startPage.hillButton.addEventListener(MouseEvent.CLICK, onHillButtonClick);
                startPage.pondButton.addEventListener(MouseEvent.CLICK, onPondButtonClick);
                hillPage.backToStartButton.addEventListener(MouseEvent.CLICK, onBackButtonClick_Hill);
                pondPage.backToStartButton.addEventListener(MouseEvent.CLICK, onBackButtonClick_Pond);
            }

            // event handlers
            function onHillButtonClick(event:MouseEvent):void
            {
                addChild(hillPage);
                removeChild(startPage);
            }
            function onPondButtonClick(event:MouseEvent):void
            {
                addChild(pondPage);
                removeChild(startPage);
            }
            function onBackButtonClick_Hill(event:MouseEvent):void
            {
                addChild(startPage);
                removeChild(hillPage);
            }
            function onBackButtonClick_Pond(event:MouseEvent):void
            {
                addChild(startPage);
                removeChild(pondPage);
            }
        }
}

package
{
    import flash.display.MovieClip;
    import flash.events.MouseEvent;

    public class Main_Test_2 extends MovieClip
    {
        var pages:Array = ["startPage", "hillPage", "pondPage"];

        public function Main_Test_2()
        {
            pages[0] = new StartPage;
            pages[1] = new HillPage;
            pages[2] = new PondPage;
            addChild(pages[0]); 
            /*trace (pages[0]);*/

            // add event listeners
            pages[0].hillButton.addEventListener(MouseEvent.CLICK, hillButtonClick);
            pages[0].pondButton.addEventListener(MouseEvent.CLICK, pondButtonClick);
            pages[1].homeButton.addEventListener(MouseEvent.CLICK, homeButtonClick);
            pages[2].homeButton.addEventListener(MouseEvent.CLICK, homeButtonClick);
        }


        function hillButtonClick(event:MouseEvent):void
        {
            trace ("You did a thing.");
            addChild(pages[1]); 
            removeChild(pages[0]); 
        }
        function pondButtonClick(event:MouseEvent):void
        {
            trace ("Slimy frogs are slimy.");
            addChild(pages[2]); 
            removeChild(pages[0]); 
        }
        function homeButtonClick(event:MouseEvent):void
        {
            /*addChild(pages[0]); */
            if (pages[1])
            {
                trace ("All your base are belong to me.");
                /*removeChild(pages[1]);*/
            }
            if (pages[2])
            {
                trace ("You are who you choose to be.");
                /*removeChild(pages[2]);*/
            }
        }
    }
}

我做的第一件事是从每个页面的单个变量切换到一个数组。当我制作交互式故事书的 9 页 3x3 版本时,代码失控并且非常重复,所以我认为数组会缩短内容,但这让我想到了我正在尝试做但做不到的第二件事甚至在切换到阵列之前也不知道。在本教程中,MovieClip 中的每个按钮都使用 addChild 添加下一页,并使用 removeChild 删除当前页面,但是这些按钮的设置使其可以根据单击时所在的页面执行不同的操作,这会导致多个 onBackButtonClick结果,例如。随着页面数量的增加,这会成为一个问题。我宁愿让每个按钮添加与按钮对应的页面,同时删除所有其他页面,所以我不需要像 onBackButtonClick_hill 和 onBackButtonClick_pond 这样的多个冗余按钮。我尝试使用第二批代码自行设置它,但无法正常工作。

我也在考虑制作一些变量,包括 var currentPage、var allPages 和 var allOtherPages (currentPage - allPages),这样我就可以告诉按钮执行添加当前页面和删除所有其他页面等操作,但我不知道如何将舞台上的当前动画片段称为当前页面等。我对编程还是太陌生了。

任何有关这些问题和建议的帮助将不胜感激。

你走对了。如果你多花点时间,你就能想出如何优化它。

首先,使用页面对象数组(不是名称):

var pages:Array = [new startPage(), new hillPage(), new pondPage()];

接下来,您可以使用循环高效地排列 3x3(或任何其他)页面输出。

const GRID_SIZE:int = 3;
for (var i:int = 0; i < pages.lengthl i++) {
    var page:MovieClip = pages[i] as MovieClip;
    page.x = (i % GRID_SIZE) * (page.width + 10);
    page.y = Math.floor(i / GRID_SIZE) * (page.height + 10);
    addChild(page);
    page.homeButton.addEventListener(MouseEvent.CLICK, homeButtonClick, false, 0, true);
}

因此,您可以根据需要放置任意数量的页面,并且可以高效地为每个页面添加侦听器。在侦听器内部,使用:

function homeButtonClick(event:MouseEvent):void {
    var t:MovieClip = event.target.parent as MovieClip;
    if (t is hillPage) {
        // ... do something for the hillPage
    } else if (t is pondPage) {
        // ... do something for the pondPage
    } else {
        // ... and so on
    }
    navigateBack();
}

现在您还可以看到有一个新函数 navigateBack 自然地用于向后导航。

您所要做的就是记住您必须到达的最后一页 return。请注意,如果您愿意,它可能不是起始页。此外,您可以记住的不是一页,而是一页的历史记录 - 如果您愿意,也可以再次记住。让我们创建一个访问过的页面数组:

var pageStack:Array = [];

每次进入某个页面,都可以放到pageStack:

pageStack.push(page);

每次需要返回时,使用navigateBack函数:

function navigateBack():void {
    var page:MovieClip = pageStack.pop();
    // it is your current page, so destroy it
    removeChild(page);
    // also remove listeners, if you want...
    // now retrieve the previous page
    var pl:int = pageStack.length;
    if (pl) {
        page = pageStack[pl - 1];
    } else {
        page = pages[0];
    }
    addChild(page);
}

您还可以修改 navigateBack 函数,不仅销毁当前页面,还销毁所有之前的页面等。