删除在另一个函数中启动的函数中的事件侦听器

Removing Event Listeners in a Function that were started in another function

所以我一直在努力改造我早年在学校制作的一个简单的猜谜游戏。基本上我已经弄清楚了,但是我似乎总是遗漏了一些东西,那就是在游戏结束时删除事件监听器和计时器,这样用户就可以开始一个新的会话,如果他们想这样做的话。

在研究这个问题时,我找不到任何关于相同信息的内容。除了这个链接,但它仍然没有多大帮助。

Can I create EventListener in AS3 from one Object and remove it from another Object?

无论我尝试过什么,我仍然会遇到错误,而且我认为它是函数之间的处理。

TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at Classes::GuessingGames/selfClearingEvents()
    at Classes::GuessingGames/loseGame()
    at Classes::GuessingGames/evaluateGuessing()
    at Classes::GuessingGames/enterKeyGuess() 

这是为删除事件侦听器而创建的函数

public function selfClearingEvents(){ 
                // Remove Event Listeners 
                stGame.removeEventListener(MouseEvent.CLICK, startGame); 
                inStruc.removeEventListener(MouseEvent.CLICK, instructions);
                // Remove Timer Listeners
                myTimer.stop(); 
                myTimer.removeEventListener (TimerEvent.TIMER_COMPLETE, timerComplete);
                myTimer.removeEventListener(TimerEvent.TIMER, timerHandler); 
                // Remove Other Keyboard and MouseListeners 
                input_txt.removeEventListener(KeyboardEvent.KEY_DOWN, enterKeyGuess); // event.charCode === 13
                guess_btn.removeEventListener(MouseEvent.CLICK, enterMouseGuess); 
        }

这是我的完整代码

package Classes {

    import flash.display.MovieClip;
    import flash.events.MouseEvent;
    import flash.events.KeyboardEvent; 

    // Import Timer Utilities
    import flash.utils.Timer;
    import flash.text.TextField;
    import flash.events.TimerEvent;
    import flash.display.Stage;

    public class GuessingGames extends MovieClip {

        // Create Vars for Game 
        var randNum = 0;  
        var maxNum = 10; // Max number we will be guessing
        var numOfGuesses = 4; // Give Max Number of Guesses 
        var myGuess; // Setup Variable for Guess
        var myTimer:Timer; 
        var seconds = 00; 
        var minutes = 2; 
        var score = 0; 

        //var input_txt:TextField; // Create the Text field 

        public function GuessingGames() {
            // stop the playhead first thing 
            stop();
            //trace("HelloWorld"); //test to see whats working 

            // Add Functionality to Buttons 
            // ----------------------------------------------------
            stGame.addEventListener(MouseEvent.CLICK, startGame); 
            inStruc.addEventListener(MouseEvent.CLICK, instructions); 
        } // End Guessing Games 

        // Button Functions 
        // Functions for Buttons 
        // ----------------------------------------------------------------------
         public function startGame(event:MouseEvent):void { 
                // frame 10 is the game start
                gotoAndStop(10); 
                gameStarting(); 
            }
         public function instructions(event:MouseEvent):void {
                // frame 5 is the instructions
                gotoAndStop(5); 
                trace("Instuctions"); 
            }
        public function clearInput(event:MouseEvent):void { 
                input_txt.text=""; 
                input_txt.removeEventListener(MouseEvent.CLICK, clearInput); 
            }

        // Game Logic
        //-----------------------------------------------------

        private function gameStarting(){
            // Game Started 
            trace("game started"); 
            randomNumber(); // Make the Number 
            theTimer(); 

            // Keeping score
            score = 0; // reset the score 
            score_txt.text = score; // show it on the board 


            // Track the Number of Guesses and Display them to the User 
            guess_txt.text = numOfGuesses;  

            // Setup Input 
            input_txt.restrict="0-9"; //Restrict to numbers 0 - 9 
            input_txt.text="__"; //Clears the input text field.
            input_txt.addEventListener(MouseEvent.CLICK, clearInput); 

            // Add Event Listener for Enter Guess 
            // Add to types EnterKey, and MouseEvent 
            input_txt.addEventListener(KeyboardEvent.KEY_DOWN, enterKeyGuess); // event.charCode === 13
            guess_btn.addEventListener(MouseEvent.CLICK, enterMouseGuess); 


            // Setup a feedback message spot 
            // ==================
            var beginningText = "Start by choosing a number 1-10... Lead your team to a TouchDown by guessing the Number.";
            message_txt.text = beginningText; 

        }

        // Create the Random Number
        private function randomNumber(){ 
           randNum = Math.ceil(Math.random() * maxNum); 
        }

        // Keyboard Event Checking Guess 
        // --------------------------------------------
        public function enterKeyGuess(event:KeyboardEvent){
            // if the key is ENTER
            if(event.charCode === 13){
                // Do Something
                //trace("entered Keyboard Guess"); 
                evaluateGuessing(); 
            }
        }

        // Mouse Event Checking Guess 
        // --------------------------------------------
        public function enterMouseGuess(event:MouseEvent):void { 
            // Do Something
            //trace("entered Mouse Guess");
            evaluateGuessing();
        }

        // Store and Check Guesses   
        // ---------------------------------------------
        public function evaluateGuessing(){ 
            myGuess = input_txt.text; // Store Guess

            // Evaluating The Guesses 
            // ---------------------------------
            // Check to make sure guess is in the parameters 
            if(myGuess > 10 || myGuess <= 0) {
                message_txt.text = "Flag On The Play -- Please pick a number between 1 and 10";
            } else { 
                if (myGuess > randNum && myGuess ) { // Check Guess Lose
                    message_txt.text = "Incomplete Pass! You overthrew your reciever. ";
                    numOfGuesses--; // Remove a Guess 
                } else if (myGuess < randNum) { // Check Guess Lose                     
                    message_txt.text = "Tackled short of your goal."; 
                    numOfGuesses--; // Remove a Guess 
                } else{         
                    // Check Guess Win
                    message_txt.text = "TOUCHDOWN!!  Number " + randNum + "."; 
                    score++;  
                    score_txt.text = score; 
                    // reset the random number 
                    randomNumber(); 
                    // reset the Number of Guesses 
                    numOfGuesses = 4; 
                } // end eval 
            }// end else 

            // Adjust the Text on Scoreboard always
            guess_txt.text = numOfGuesses;  

            if(numOfGuesses === 0) { 
                loseGame(); 
            }

        }

        // Create a Timer 
        // --------------------------------------------
        public function theTimer(){
            myTimer = new Timer(1000, 120);
            myTimer.start(); 
            timeText.text = "2:00";  // Displaying The Clock
            myTimer.addEventListener (TimerEvent.TIMER_COMPLETE, timerComplete);
            myTimer.addEventListener(TimerEvent.TIMER, timerHandler); 
        }

        public function timerHandler(e:TimerEvent): void {

            if(seconds > 00) { 
                seconds-=1;
            } else { 
                if (minutes > 0){ minutes-=1; seconds = 59; }
            }

            timeText.text = minutes+":"+(seconds >= 10? seconds : "0"+seconds);

            trace("Current Count: " + myTimer.currentCount);
        }

        private function timerComplete(e:TimerEvent) {
            //trace("Timer is Done"); 
            if(score === 0) { 
                loseGame(); 
            } else { 
                winGame(); 
            }
        }


        // Winning or Losing Game   
        // ---------------------------------------------
        public function winGame(){
                trace("Yea You won!"); 
                myTimer.stop(); 
                gotoAndStop(15); // Frame 15 Shows the Win Screen 
        }

        public function loseGame(){
                trace("You Lost Idiot"); 
                selfClearingEvents(); 
                gotoAndStop(20); // Frame 20 Shows the Lose Screen
        }


        public function selfClearingEvents(){ 
                // Remove Event Listeners 
                stGame.removeEventListener(MouseEvent.CLICK, startGame); 
                inStruc.removeEventListener(MouseEvent.CLICK, instructions);
                // Remove Timer Listeners
                myTimer.stop(); 
                myTimer.removeEventListener (TimerEvent.TIMER_COMPLETE, timerComplete);
                myTimer.removeEventListener(TimerEvent.TIMER, timerHandler); 
                // Remove Other Keyboard and MouseListeners 
                input_txt.removeEventListener(KeyboardEvent.KEY_DOWN, enterKeyGuess); // event.charCode === 13
                guess_btn.removeEventListener(MouseEvent.CLICK, enterMouseGuess); 
        }



    }

}

我大胆猜测 stGameinStrucMovieClip 实例,您已将它们放在主时间轴上,但在第 10 帧中不可用是调用 selfClearingEvents 方法的框架。这解释了为什么当您尝试调用 removeEventListener 时会出现空对象引用错误。

如果游戏开始后不再需要这些实例,您可以尝试在此时移除监听器:

    private function gameStarting(){

        // Remove Event Listeners 
        stGame.removeEventListener(MouseEvent.CLICK, startGame); 
        inStruc.removeEventListener(MouseEvent.CLICK, instructions);

        // Rest of game start code
    }