如何自动从AS3的对象中删除事件监听器监听器、象中、事件

2023-09-08 14:30:38 作者:奈何。

我工作的小Flash游戏。游戏包含20个级别和主菜单。电平之间的转换是通过删除每个对象的帧和所有事件监听器上进行。然后,code,从一个新的水平增加了对象......

I am working on small flash game. The game contains 20 levels and main menu. The transition between levels is made by deleting every object on the frame and also all event listeners. Then the code adds objects from the next level...

捕捉和删除事件侦听器是由该code完成的:

Catching and the removing event listeners is done by this code:

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 = []
    }

这code覆盖内部addEventListeners,使每一个听众在一个数组以复加。第二个函数检查EventListeners的仍然存在(没有prevoiusly删除)和刚刚从数组中删除所有的监听器。

This code overrides internal addEventListeners and makes every Listener to be added in an array. Second function checks if the EventListeners is still there(not prevoiusly removed) and the just remove every Listener from the array.

这code工作正常,已分配到舞台EventListeners的。然而,当一个事件监听器被直接分配到一个对象,然后它没有添加到阵列中,所以它不会自动删除后。

This code works fine for EventListeners that are assigned to the stage. However, when an EventListener is assigned directly to an Object then it's not added to the array, so it doesn't get removed automatically later.

我知道,当你删除的对象,你也删除分配给它的事件侦听器。但是,当我再补充一点对象再次听众运行两次。您可以自由移动通过各级,这样你就可以来回走。而当你回到我收到的问题。系统被过度使用,并回环速度较慢,因为运行事件侦听器的数量增加一倍。

I know that when you remove the object, also you remove the Event Listeners assigned to it. But when I add that object again the Listeners run twice. You can freely move through levels, so you can go back and forth. And when you go back I recieve problems. System is overused and is woring slower, because the amount of Event Listeners that are running is doubled.

所以,你能修改此code或给我意见,我怎么能赶上分配给对象,并最终EventListeners的删除它们。

So, can you modify this code or give me an advice how can I catch EventListeners that are assigned to Object and eventually remove them.

code:

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个级别。

And so on for the next 20 levels.

谢谢意见。

推荐答案

删除一个对象( removeChild之(对象))的不自动删除这是事件侦听器。您需要做的是你自己。像这样可以工作:

Removing an object (removeChild(object)) does NOT automatically remove it's event listeners. You would need to do that yourself. Something like this could work:

在类的构造函数:

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);

的处理程序:

The handlers:

//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
}

这会使你的听众停止时,该项目从显示列表中删除倾听,并添加时再添加。你必须修改你的阵列包括像捕获阶段的WeakReference的其他的侦听信息。如果你不想让他们再次添加,只是叫你clearEvents()在removedFromStage处理程序,并完全取出addedToStage监听器/处理器。

This would make your listeners stop listening when the item is removed from the display list, and re-add them when added. You'd have to modify your array to include the other listener information like capture phase and weakReference. If you don't want them added again, just call your clearEvents() in the removedFromStage handler and take out the addedToStage listener/handler altogether.

这是假设您发布的code(和我的加法)是基类中的所有你希望它应用到的对象。

This is assuming that the code you posted (and my additions) is the base-class of all the object you want it applied to.