Удаление прослушивателей событий в функции, которые были запущены в другой функции
Поэтому я работал над обновлением простой игры в догадки, которую я сделал в ранние годы обучения в школе. В основном я понял это, но есть кое-что, чего я, кажется, всегда упускаю, и которое удаляет списки событий и таймеры в конце игры, поэтому пользователь может начать новый сеанс, если он захочет это сделать.
Исследуя вопрос, я не смог найти ничего такого, что могло бы пролить свет на эту же информацию. За исключением этой ссылки, но она все еще не совсем помогает.
Могу ли я создать 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
}