【问题标题】:Removing Event Listeners in a Function that were started in another function删除在另一个函数中启动的函数中的事件侦听器
【发布时间】:2015-03-03 07:42:41
【问题描述】:

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

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

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



    }

}

【问题讨论】:

    标签: actionscript-3 function flash public-method


    【解决方案1】:

    我会冒险猜测stGameinStruc 是您放置在主时间线上的MovieClip 实例,并且在第10 帧上不可用,这是@987654324 所在的帧@方法被调用。这就解释了为什么当您尝试对它们调用 removeEventListener 时会收到空对象引用错误。

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

        private function gameStarting(){
    
            // Remove Event Listeners 
            stGame.removeEventListener(MouseEvent.CLICK, startGame); 
            inStruc.removeEventListener(MouseEvent.CLICK, instructions);
    
            // Rest of game start code
        }
    

    【讨论】:

    • 它们在第 10 帧上仍然可用。我会研究那个,但仍然没有解释删除计时器事件。 编辑: 没关系,这会解决它。我不知道删除时间线并稍后再次添加会导致中断。感谢您的帮助。
    猜你喜欢
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-03
    相关资源
    最近更新 更多