1

我正在开发小型 Flash 游戏。游戏包含 20 个关卡和主菜单。通过删除框架上的每个对象以及所有事件侦听器来实现级别之间的转换。然后代码从下一级添加对象......

捕获和删除事件侦听器由以下代码完成:

override public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
    {
        super.addEventListener(type, listener, useCapture, priority, useWeakReference);
        arrListeners.push({type:type, listener:listener});

    }

    private function clearEvents():void
    {
       for(var i:Number = 1; i<arrListeners.length; i++){
          if(this.hasEventListener(arrListeners[i].type))
        {
             this.removeEventListener(arrListeners[i].type, arrListeners[i].listener);
          }
       }
       arrListeners = []
    }

此代码覆盖内部 addEventListeners 并使每个侦听器都添加到数组中。第二个函数检查 EventListeners 是否仍然存在(之前没有删除),然后从数组中删除每个 Listener。

此代码适用于分配给舞台的 EventListener。但是,当 EventListener 直接分配给 Object 时,它不会添加到数组中,因此以后不会自动删除。

我知道当你删除对象时,你也会删除分配给它的事件监听器。但是当我再次添加该对象时,侦听器会运行两次。您可以在关卡中自由移动,因此您可以来回走动。当你回去时,我会遇到问题。系统被过度使用并且工作速度变慢,因为正在运行的事件侦听器的数量增加了一倍。

那么,您能否修改此代码或给我一个建议,我如何才能捕获分配给 Object 的 EventListener 并最终删除它们。

代码:

package

{
     Public Class Main extends MovieClip
     {
          Public function Main()
          {
               Intro();
          }
          Private function Intro():void
          {
             //Constructor contains a lot of addChild and a EventListeners. So I will upload what I think i important for this problem.
             Play_btn.addEventListener(MouseEvent.CLICK, clicked);
             function clicked (e:MouseEvent):void
             {
                 clearEvents();
                 clearChild(); // function that removes all children on stage
                 FirstLevel();
              }
           }
           Private function FirstLevel():void
           {
              //Also adding children and EventListeners, that affect the gameplay
              Next_level_btn.addEventListener(MouseEvent.CLICK, clicked1);
              function clicked1 (e:MouseEvent):void
             {
                 clearEvents();
                 clearChild();
                 SecondLevel();
              }
              Main_Menu_btn.addEventListener(MouseEvent.CLICK, clicked1);
              function clicked1 (e:MouseEvent):void
              {
                 clearEvents();
                 clearChild(); 
                 Intro();
               }
            }

接下来的 20 个级别以此类推。

谢谢指教。

4

2 回答 2

0

移除一个对象 ( removeChild(object))不会自动移除它的事件监听器。你需要自己做。像这样的东西可以工作:

在您的类构造函数中:

super.addEventListener(Event.ADDED_TO_STAGE,addedToStage,false,0,true);  //only if you want the listeners added back again the next time this object is added to the stage  eg. addChild(this)
super.addEventListener(Event.REMOVED_FROM_STAGE,removedFromStage,false,0,true);

处理程序:

//this runs whenever the object is added to the display list
//if you don't want the listeners re-added, remove this function.
private function addedToStage(e:Event):void {
    for(var i:int=0; i<arrListeners.length; i++){
        super.addEventListener(arrListeners[i].type, arrListeners[i].listener, arrListeners[i].useCapture, arrListeners[i].priority, arrListeners[i].useWeakReference);
    }
}

//this runs whenever the object is removed from the display list
private function removedFromStage(e:Event):void {
    for(var i:int=0; i<arrListeners.length; i++){
        super.removedEventListener(arrListeners[i].type, arrListeners[i].listener, arrListeners[i].useCapture);
    }

    //OR if you want the listeners gone forever, use your clearEvents() method instead of the for loop above
}

这将使您的听众在项目从显示列表中删除时停止收听,并在添加时重新添加它们。您必须修改您的数组以包含其他侦听器信息,例如捕获阶段和弱引用。如果您不想再次添加它们,只需在 removedFromStage 处理程序中调用您的 clearEvents() 并完全取出 addedToStage 侦听器/处理程序。

这是假设您发布的代码(以及我添加的代码)是您希望将其应用于的所有对象的基类。

于 2012-09-07T20:48:37.560 回答
0

数组索引从 0 开始,clearEvents 应该是:

 private function clearEvents():void
 {
     for(var i:int= 0; i<arrListeners.length; i++){
        if(this.hasEventListener(arrListeners[i].type))
        {
             this.removeEventListener(arrListeners[i].type, arrListeners[i].listener);
        }
     }
     arrListeners = []
 }

不确定这是否会解决您的问题。如果您在添加新对象时创建了事件侦听器,则应在对象被销毁/删除时删除这些侦听器。

于 2012-09-07T20:38:40.200 回答