2012-09-07 5 views
1

Я работаю над маленькой флеш-игрой. Игра содержит 20 уровней и главное меню. Переход между уровнями осуществляется путем удаления каждого объекта в кадре, а также всех прослушивателей событий. Затем код добавляет объекты следующего уровня ...Как автоматически удалить прослушиватель событий из объекта в AS3

Ловля и удаление слушателей событий осуществляется с помощью этого кода:

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 из массива.

Этот код отлично подходит для EventListeners, назначенных этапу. Однако, когда EventListener назначается непосредственно объекту, он не добавляется в массив, поэтому он не может быть удален автоматически позже.

Я знаю, что при удалении объекта также удаляются назначенные ему прослушиватели событий. Но когда я снова добавляю этот объект, Listeners запускаются дважды. Вы можете свободно перемещаться по уровням, чтобы вы могли идти туда и обратно. И когда ты возвращаешься, я получаю проблемы. Система чрезмерно используется и работает медленнее, потому что количество выполняемых прослушивателей событий удваивается.

Итак, можете ли вы изменить этот код или дать мне совет, как я могу поймать EventListeners, которые назначены Object и в конечном итоге удалить их.

Код:

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 уровней.

Спасибо за консультацию.

+0

Непонимание вашего вопроса. В частности: «Этот код отлично подходит для EventListeners, которые не привязаны к объекту.Когда определенному EventListener назначается объект, он не добавляется к массиву, поэтому я не могу его удалить позже ». – BadFeelingAboutThis

+0

Первая функция из кода, который я загрузил, только улавливает addEventListeners, которые добавляются по этому пути: - stage .addEventListener (Event.ENTER_FRAME, начал) или - addEventListener (Event.ENTER_FRAME, начало); Но когда я addEventListener, который присваивается объекту для Ex: - Start_btn.addEventListener (Mouse.CLICK, щелкнул) Код не улавливает и не помещает его в массив, а это значит, что я не могу удалить позже, используя вторую функцию – Stefan4024

+0

, не уверен, как вы переопределяете функцию addEventListener на этапе? Ваш Start_btn (или wha tever) должен был бы наследовать класс, код которого вы показали. – BadFeelingAboutThis

ответ

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

Не уверен, если это будет исправить вашу проблему, хотя. Если у вас есть слушатели событий, созданные при добавлении новых объектов, вы должны удалить этих слушателей, когда объект будет уничтожен/удален.

+0

i установлен в 1, потому что сначала добавляю один EventListener, который будет проверять, прошел ли уровень. Поэтому я не удаляю его, потому что я должен добавить его снова. – Stefan4024

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 
} 

Это сделает ваши слушатели перестать слушать, когда элемент удаляется из списка отображения, и добавьте их при добавлении. Вам придется изменить свой массив, чтобы включить в него другую информацию слушателя, такую ​​как фаза захвата и слабая реакция. Если вы не хотите, чтобы они были добавлены снова, просто позвоните в clearEvents() в обработчик removeFromStage и вытащите добавочный/добавочный приемник addToStage.

Предполагается, что введенный вами код (и мои добавления) является базовым классом всего объекта, к которому вы его применили.

+0

Не могли бы вы дать мне немного объяснения кода. Я не знаю, как это работает. Поэтому краткое объяснение может помочь мне. Я добавил первую строку к контрструктору, мне не нужно второе, потому что clearEvents() отлично работает. Кроме того, я добавил функцию addToStafe в код, но снова получаю ту же проблему. Поэтому, пожалуйста, объясните мне, что треска – Stefan4024

+0

вы используете только прослушиватель/обработчик добавленногоToStage, если вы сохраняете свои ресурсы в памяти после выполнения removeChild() на них - и планируете позже использовать addChild(), чтобы показать их снова. – BadFeelingAboutThis

+0

Я не понимаю, как ваше переопределение функции addEventListener на сцене, возможно, если вы обновите свой вопрос, чтобы показать контекст кода, который вы предоставили. Это ваш класс документов? или базовый класс, который распространяется на все ваши игровые активы? – BadFeelingAboutThis

Смежные вопросы