2014-09-29 53 views
1

我的代碼如下:刪除事件監聽器將不起作用。

有一個函數可以創建筆記。創建的筆記無論好還是壞。

有一個移動事件偵聽器使筆記移動。 有一個鼠標事件偵聽器,用於檢查筆記點擊時的好壞。

兩個偵聽器中的remove event listener都不起作用。 檢查下面的破碎評論。 (筆記仍然移動,仍然可以點擊)

已經嘗試了很多東西,但沒有運氣。 :(

有以前沒有問題,但是當我修改代碼,這樣我就可以向聽衆傳遞參數,它打破。所以我猜有什麼毛病我做的方式。

如果有人知道一個更好的辦法來區分移動音符/點擊音符,如果它是好還是壞,都幫助!這就是爲什麼我傳遞參數到聽衆的方式的原因。:)

function SpawnNote(rpos:int):void 
{ 
    rsn = int(Math.random() * 3) + 1; 

    spawn = int(Math.random() * notes.length); 
    var note:MovieClip = new notes[spawn](); 
    addChild(note); 

    rpos = int(Math.random() * 3) + 1; 

    if (rpos==1) 
    { 
     note.x = pos1; 
    } 
    else if (rpos==2) 
    { 
     note.x = pos2; 
    } 
    else if (rpos==3) 
    { 
     note.x = pos3; 
    } 

    note.y = 150; 
    note.addEventListener(Event.ENTER_FRAME, MoveNote(spawn)); 
    note.addEventListener(MouseEvent.CLICK, CheckNote(spawn)); 

if(rsn%2==0) 
{ 

    rtemp = rpos; 

    if (rtemp==1) 
    { 
     rpos = int(Math.random() * 2) + 2; 
    } 

    if (rtemp==2) 
    { 
     rpos = int(Math.random() * 2); 
     if (rpos==0) 
     { 
      rpos = 3; 
     } 
    } 

    if (rtemp==3) 
    { 
     rpos = int(Math.random() * 2) + 1; 
    } 

    spawn = int(Math.random() * notes.length); 
    var note:MovieClip = new notes[spawn](); 
    addChild(note); 

    if (rpos==1) 
    { 
     note.x = pos1; 
    } 
    else if (rpos==2) 
    { 
     note.x = pos2; 
    } 
    else if (rpos==3) 
    { 
     note.x = pos3; 
    } 

    note.y = 150; 

    note.addEventListener(Event.ENTER_FRAME, MoveNote(spawn)); 
    note.addEventListener(MouseEvent.CLICK, CheckNote(spawn)); 
} 


function MoveNote(spawncheck:int):Function 
{ 
    return function(event:Event):void { 
    var note:DisplayObject = event.target as DisplayObject; 

    note.y += 7;   

    if (note.y >= stage.stageHeight + 50) 
    { 
     if(spawncheck<15) 
     { 
      trace(spawn+" GOOD ITEM PASSED!");    
      score+=100; 
     } 

     else 
     { 
      trace(spawn+" BAD ITEM PASSED!"); 
      score-=100;    
     } 
     //if (note.parent) 
     //{ 
      //REMOVE EVENT LISTENER BROKEN 
      //e.currentTarget.removeEventListener(Event.type, MoveNote(spawn)); 
      //e.currentTarget.removeEventListener(Event.type, CheckNote(spawn)); 
     note.removeEventListener(Event.ENTER_FRAME, MoveNote); 
     note.removeEventListener(MouseEvent.CLICK, CheckNote); 
     note.parent.removeChild(note); 
     //removeChild(note); 
     //}      
     scorecon.text = score.toString();  
    } 
    } 
} 


function CheckNote(spawncheck:int):Function 
{ 
    return function(e:MouseEvent):void { 
    var note:DisplayObject = e.target as DisplayObject; 

    if(spawncheck<15) 
    { 
     trace("GOOD ITEM!"); 
     score-=100; 
    } 

    else 
    { 
     trace("BAD ITEM!"); 
     score+=100; 
    } 
    scorecon.text = score.toString();   

    //BROKEN 
    note.removeEventListener(Event.ENTER_FRAME, MoveNote); 
    note.removeEventListener(MouseEvent.CLICK, CheckNote); 
    note.x = stage.stageHeight/2; 
    note.y = stage.stageWidth/2; 
    /* 

    if (clicked.parent) 
    {  
     clicked.parent.removeChild(clicked); 
    } 
    */ 
    //removeChild(note); 
    } 
} 
} 
+1

這些偵聽器沒有範圍,因此您不能引用它們,也無法刪除它們。您只能使用weakListener標誌。但是,無論如何,整個代碼風格都很薄弱和不專業。爲了避免編寫一個簡單的自定義事件類,需要大量代碼廢話,解決方法和黑客攻擊。 – BotMaster 2014-09-29 14:04:25

回答

0

如前所述,您的變量範圍是錯誤的。在函數外部聲明var note,然後您將刪除偵聽器到合適的變量:

var note:MovieClip; 

    function SpawnNote(rpos:int):void 
    { 
    rsn = int(Math.random() * 3) + 1; 

    spawn = int(Math.random() * notes.length); 
    note = new notes[spawn](); 
    note.spawn = spawn; //so you don't need to pass the parameter and get the value later but I would use an array or dictionary to track them 
    .... 
+0

謝謝你。我使用了數組,問題已解決! – 2014-10-02 15:42:37

+0

沒問題。如果您發現它有用,請將我的答案標記爲解決方案。 – Delcasda 2014-10-02 20:15:49

0

你不能寫

note.addEventListener(Event.ENTER_FRAME, MoveNote(spawn)); 
note.addEventListener(MouseEvent.CLICK, CheckNote(spawn)); 

正確的語法是

note.addEventListener(Event.ENTER_FRAME, MoveNote); 
note.addEventListener(MouseEvent.CLICK, CheckNote); 

雖然偵聽器函數應該是這樣的

function MoveNote(e:Event):void{ 
... 
} 

function CheckNote(e:MouseEvent):void{ 
... 
} 

你不能傳遞與參數爲另一個函數調用的參數函數調用。 .addEventListener只接受對函數的引用。 你也不應該在Listener Functions中返回Function,只需使用void並忘記返回任何東西。

你需要找出一種不同的方法來檢查你的「spawncheck:int」對象。 這是一個建議:重寫代碼,使「Notes」不是Movieclip,而是來自Class Note的對象。給這個類一個公共變量spawnCheck並在EventListener函數中檢查它。

一般來說,您應該重新學習AS3編碼的基礎知識。

+1

實際上,提供的代碼OP是有效的,至少是添加了監聽器的部分。這是因爲MoveNote(spawn)返回一個有效的事件監聽器函數,它也是一個閉包。 – Varnius 2014-09-29 12:41:10

+0

@Varnius它可能是「有效的」。但是,編寫AS3是一種可怕的方式。更何況,如果我沒有記錯的話,刪除匿名功能(如果這是任何OP在他的科學怪人實驗室中創建的)是不可能的。這並不意味着它不會得到GC'ed,但仍然。 – 2014-09-29 14:45:21

+0

@FlexFiend我完全同意提供的代碼可以改進。我只是想闡明可以用這種方式添加監聽器。另外,通過引用arguments.callee應該可以刪除匿名函數。 – Varnius 2014-09-30 06:56:40