2014-09-29 5 views
1

내 코드는 다음과 같습니다.이벤트 리스너 제거가 작동하지 않습니다.

메모를 만드는 기능이 있습니다. 생성 된 노트는 좋거나 나쁘다.

메모를 이동시키는 이동 이벤트 리스너가 있습니다. 클릭하면 좋고 나쁜 경우 메모를 확인하는 마우스 이벤트 수신기가 있습니다.

리스너 모두의 remove 이벤트 수신기가 작동하지 않습니다. 아래의 // 깨진 설명을 확인하십시오. (메모가 여전히 이동하고 클릭 할 수 있음)

이미 많은 노력을했지만 운이 없었습니다. :(

전에 아무 문제가 없다하지만 난 내 코드를 수정할 때 그래서, 그것은. 그래서 내가했던 방식에 문제가있는 것 같은데요.

분류 리스너에 매개 변수를 전달할 수 있습니다 사람이 움직이는 메모를 차별화 할 수있는 더 좋은 방법을 알고 있다면 도움 않는, 좋은 또는 나쁜 경우 /! 그게 내가하는 방식으로 리스너에 매개 변수를 전달하고 있습니다 이유입니다. :)

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

답변

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

감사합니다. 배열을 사용했는데 문제가 해결되었습니다! –

+0

문제 없습니다. 유용하다고 생각되면 해결책으로 해결책을 표시하십시오. – Delcasda

0

당신은 할 수 없습니다를 클릭 쓰기

note.addEventListener(Event.ENTER_FRAME, MoveNote(spawn)); 
note.addEventListener(MouseEvent.CLICK, CheckNote(spawn)); 
리스너 함수를 사용하면 함수가 다른 함수 호출에 대한 매개 변수로 매개 변수를 호출을 전달할 수 없습니다이

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

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

과 같아야 동안 10

올바른 구문은

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

이 될 것입니다. .addEventListener는에 대한 참조 만 허용합니다 (). 또한 Listener 함수에서 Function을 반환하지 말고 단순히 void를 사용하고 아무것도 반환하지 않도록합니다.

"spawncheck : int"개체를 확인하는 다른 방법을 찾아야합니다. 제안 사항 : "메모"가 무비 클립이 아니라 클래스 메모의 객체가되도록 코드를 다시 작성하십시오. 클래스에 public 변수 spawnCheck를 지정하고 EventListener 함수에서이를 확인하십시오.

일반적으로 AS3 코딩의 기초를 다시 배워야합니다.

+1

사실, 제공된 코드 OP는 유효합니다. 적어도 청취자가 추가 된 부분은 유효합니다. 그것은 MoveNote (스폰)가 또한 클로저 인 유효한 이벤트 리스너 함수를 반환하기 때문입니다. – Varnius

+0

@Varnius "유효"일 수 있습니다. 그러나 AS3을 작성하는 것은 끔찍한 방법입니다. 말할 것도없이, 익명의 함수를 제거하는 것은 (만약 프랑켄슈타인 실험실에서 OP가 만든 것이라면) 정확하게 기억한다면 실제로 가능하지 않습니다. 그렇다고 GC 화되지는 않을 것입니다. –

+0

@FlexFiend 제공된 코드를 개선 할 수 있다는 것에 전적으로 동의합니다. 그런 식으로 청취자를 추가하는 것이 가능하다는 것을 분명히하고자했습니다. 또한 arguments.callee를 참조하여 익명의 함수를 제거 할 수 있어야합니다. – Varnius

관련 문제