Удаление прослушивателей событий в функции, которые были запущены в другой функции

Поэтому я работал над обновлением простой игры в догадки, которую я сделал в ранние годы обучения в школе. В основном я понял это, но есть кое-что, чего я, кажется, всегда упускаю, и которое удаляет списки событий и таймеры в конце игры, поэтому пользователь может начать новый сеанс, если он захочет это сделать.

Исследуя вопрос, я не смог найти ничего такого, что могло бы пролить свет на эту же информацию. За исключением этой ссылки, но она все еще не совсем помогает.

Могу ли я создать EventListener в AS3 из одного объекта и удалить его из другого объекта?

Все, что я пробовал, я все еще получаю ошибку, и я думаю, что это имеет дело между функциями.

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



    }

}

1 ответ

Решение

Я собираюсь рискнуть предположить, что stGame а также inStruc являются MovieClip экземпляры, которые вы разместили на основной временной шкале и которые недоступны в 10-м кадре, который является кадром, из которого selfClearingEvents метод называется. Это объясняет, почему вы получаете пустые ссылки на объекты при попытке вызвать removeEventListener на них.

Если эти экземпляры больше не нужны при запуске игры, вы можете попробовать удалить слушателей в этот момент:

    private function gameStarting(){

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

        // Rest of game start code
    }
Другие вопросы по тегам