0

我正在从永远不会卸载的主菜单中加载多个 swf 文件。我已经用下面的代码完成了这个......唯一的问题是,我没有卸载到主菜单,而是看到一个白屏,好像没有加载任何内容。

function BackToMenu(i:MouseEvent):void
{
    var BaseMovie:MovieClip = parent.parent as MovieClip;
    BaseMovie.parent.removeChild(BaseMovie);
}

编辑:我会从一开始就解释我有一个 MainMenu.swf。单击与游戏相关的按钮时,将从 MainMenu.swf 加载游戏。当在 MainMenu.swf 上单击游戏按钮时,游戏会加载。当玩家完成游戏时,他们会看到退出按钮,该按钮会卸载当前游戏并显示 MainMenu.swf,而无需重新加载它。

4

1 回答 1

1

首先,您应该删除一个parent以确保您实际上只删除了游戏:

function BackToMenu(i:MouseEvent):void
{
    var BaseMovie:MovieClip = parent as MovieClip;
    BaseMovie.parent.removeChild(BaseMovie);
}

这应该可以解决您最紧迫的问题,并允许您返回菜单。但是,您并没有真正卸载游戏,而只是将其从显示列表中删除。这通常意味着仍然有声音在运行、活动键和/或鼠标监听器等 - 这些都必须注意!

而且,就像我说的,这只会解决你眼前的问题。然而,这不是一个永久的解决方案,也不是一个好的解决方案:由于主 SWF 负责加载游戏,它也应该负责处理它们。您应该将清理代码放入您的游戏中,但它应该只关注停止任何正在运行的脚本、声音等 - 简单的规则:在游戏中启动的任何内容都应该在游戏中停止。但它不应尝试访问显示层次结构中更上层的对象,或尝试卸载自身。

更好的方法是替换上面的所有代码,让主 SWF 负责删除游戏,以及从内存中卸载它。为此,您必须做三件事:

  1. 不要编写实际的removeChild调用等,而是让您的按钮调度一个自定义事件来通知主 SWF 现在应该将其删除:

    function onBackButtonClicked( event:MouseEvent ):void {
        destroyGame(); // this would be the function that stops all the scripts
        dispatchEvent( new Event( "FINISH_GAME", true ) ); 
    }
    

    请注意,“FINISH_GAME”现在是“冒泡”事件,即它在显示层次结构中向下传播。我们现在可以在包含游戏的任何祖先显示对象中侦听此事件。

  2. 在您的主 SWF 中,Loader在游戏成功加载时添加一个事件侦听器。这是在加载过程完成时调用的事件侦听器中完成的:

    function onLoadComplete( event:Event ):void {
        var loader:Loader = event.target.loader;
        loader.addEventListener( "FINISH_GAME", onFinishGame, true );
    }
    
  3. 使用相应的事件处理程序删除游戏剪辑:

    function onFinishGame( event:Event ):void {
        var loader:loader = event.currentTarget;
        loader.parent.removeChild( loader );
        loader.unloadAndStop();
    }
    

还有一些需要考虑的事情:

  • ActionScript 中的命名约定建议我们对方法和变量使用小写名称,而仅对类型使用大写。

  • 相同的命名约定建议我们使用“on”或“handle”作为事件侦听器的前缀,以及事件的名称。因此,它应该是onBackToMenu,或者更确切地说onBackButtonClicked,,等等。

  • 由于我对您用于加载的代码一无所知,我只是假设您有一个完整的侦听器,并且您不保留对加载程序的引用。如果你使用一个成员变量,你可以使用它来代替event.target, resp。event.currentTarget.

于 2012-04-30T17:35:40.183 回答