en AS3, removeEventListener(Event.ENTER_FRAME) ne fonctionne pas
J'ai eu affaire à ce problème depuis des jours déjà. Je suis à mon esprit " fin!
Je n'arrive pas à trouver une réponse définitive n'importe où sur l'un des forums, de la documentation, etc.
Tout semble parfait à la première exécution, ou lorsque je charge un niveau supérieur pour l'utilisateur de jouer. Mais si l'utilisateur appuie sur la touche ÉCHAP pour charger un autre niveau, le CADRE d'ENTRÉE de l'écouteur n'est pas supprimé et il reprend tous les déclencheurs, montrant le joueur va vraiment vite, et tous les funky, car il repose sur le dessus de la déjà instancié CADRE d'ENTRÉE de l'auditeur.
Je ne sais pas si j'ai un problème d'une fonction anonyme, ou un inconnu instance d'être référencées dans mon removeEvent... commande... Bas de ligne, je donne et j'ai besoin de cette AIDE de travail!!!
Voici le code:
function initPlay():void
{
//code here determining what display object to add to the list and assign it to the currentLevel variable (a movieclip)
if(userIsLoadingOtherLevel){
removeEnterFrameListener();
addChild(currentLevel);
}
if(userIsGointToNextLevel)
addChild(currentLevel);
currentLevel.addEventListener(Event.ENTER_FRAME, onEnterFrame);
function onEnterFrame(event:Event):void
{
//collision detection, parallax scrolling, etc, etc is done here.
if(allCoinsCollected)
loadNextLevel();
if(ESCKeyPressed)
ESCKeyPressHandler();
}
function loadNextLevel():void
{
removeChild(currentLevel);
newLevelToLoad++
removeEnterFrameListener();
initPlay();
}
function ESCKeyPressHandler():void
{
removeChild(currentLevel);
initPlay();
}
function removeEnterFrameListener();
{
currentLevel.removeEventListener(Event.ENTER_FRAME,onEnterFrame)
trace("currentLevel.hasEventListener(Event.ENTER_FRAME) = "+currentLevel.hasEventListener(Event.ENTER_FRAME)); //outputs TRUE if called from loadNextLevel but FALSE if called from initPlay() !!!
}
}
J'ai aussi essayé d'ajouter et de supprimer l'eventListener à la scène, MovieClip(Racine), ou rien du tout et le résultat est toujours le même.
Je sais qu'il peut y avoir d'autres façons de concevoir un tel processus, mais s'il vous plaît noter je ne suis pas vraiment souple au moment de le faire, car le projet est très long (environ 4000 lignes de code) et de supprimer le CADRE d'ENTRÉE de cette façon, à la folie ou pas doivent encore travailler!!
MERCI d'avance pour tous ceux qui sont prêts à aider.
J'ai le sentiment aussi que ce qui se passe est que le ENTER_FRAME Écouteur d'Événement sont attachées à tous les enfants de la currentLevel Objet d'affichage, et lorsque je le supprime pour ajouter un autre niveau, il reste encore dans certains currentLevel Enfants, ou quelque chose comme ça. Je pense que cela peut se produire parce que, après le chargement d'un nouveau niveau, le joueur est toujours en conflit avec "l'invisible" objets probablement encore présent à partir de l'avant ...
Oui Pan, qui fonctionne très bien. Je n'ai qu'un problème quand j'utilise le ESCKeyPress gestionnaire. Il n'a tout simplement pas l'enlever!
Est le code ci-dessus est correcte? Je demande parce que vous semblez être de définir des fonctions à l'intérieur de la
initPlay()
fonction. Syntaxe sage, c'est parfaitement OK. Mais, logiquement, il peut-être une partie de votre problème. Peut-être que c'est juste une faute de frappe, et vous avez oublié de coller/type dans un crochet de fermeture...Le
trace()
déclaration est un excellent outil de débogage. Mettre trace()
consolidés au début de chaque méthode. Puis exécutez votre code dans les deux scénarios (quand il fonctionne correctement et quand il tombe en panne). Comparez le résultat que vous obtenez à partir des instructions de suivi et vous allez peut-être voir où en sont les choses aller détraque. Votre travail en cours autour de la fin mai jusqu'à vous mordre plus tard, en causant des problèmes de performance w/avoir un tas de cadre d'entrée auditeurs en cours d'exécution.OriginalL'auteur Leo Perez | 2013-09-03
Vous devez vous connecter pour publier un commentaire.
Le problème semble être les fonctions imbriquées à l'intérieur du
initPlay()
méthode.Chaque fois que vous appelez
initPlay()
vous définissez nouveau fonctions. Certaines de ces fonctions imbriquées appelinitPlay()
eux-mêmes.Les fonctions sont des objets (les références de mémoire). Donc, chaque fois que vous appelez
initPlay()
vous faire de nouvelles références à de nouvelles fonctions. Ainsi, lorsque vous essayez de supprimer un écouteur d'événement, vous êtes en mesure de supprimer l'un de ces gestionnaires d'événements (l'un dans le périmètre en cours d'exécution).Je ne suis pas sûr si je suis d'expliquer cela clairement, peut-être cet exemple va nous aider. Je vais utiliser les nombres pour représenter les références à chaque fonction, et un scénario simple qui est semblable à la vôtre:
Lors de l'exécution de cette fonction, la première fois, une nouvelle fonction est définie dans le champ d'application de la
example()
fonction. Permet d'utiliser le numéro 1 pour représenter la référence pour cette fonction imbriquée.someCondition
esttrue
sur le premier tour, et ainsi de laexample()
fonction est appelée de nouveau.Sur la deuxième exécution de la
example()
fonction, une nouvelle référence à la souris gestionnaire d'événement est créé (#2). Nous avons également ajouter l'écouteur d'événement nouveau. À ce stade, il y a deux cas les fonctions de gestion de mémoire, et les deux seront exécutés lorsque l'événement est déclenché.Disons que dans la deuxième invocation de
example()
quesomeCondition
estfalse
et maintenant, nous voulons supprimer l'auditeur. Lorsque nous appelons:Il parle de gestionnaire d'événement #2. Gestionnaire d'événement #1 existe toujours, et parce qu'il est caché dans le champ d'application de la première invocation de
example()
il ne peut pas être supprimé ici.Mon exemple simple tombe en panne après cela... mais j'espère qu'il fait clair pourquoi vos gestionnaires d'événements ne devrait pas être imbriquées à l'intérieur d'une fonction. Certes, c'est difficile à décrire et encore plus dans un monde réel exemple comme la vôtre. Mais je suis assez confiant que c'est la source de la plupart, si pas tous les problèmes que vous décrivez.
Par la façon dont, à l'aide de fonctions imbriquées pour les gestionnaires d'événements (ou même des fonctions anonymes) est OK, mais pas quand la logique devient compliqué comme dans votre situation. C'est là où il sera préférable de déplacer ces fonctions à l ' "extérieur" de la portée, de sorte qu'il n'y a pas de confusion sur ce qu'est être ajoutés/supprimés.
En fait, vous avez tout à fait logique. Ce que je vais faire est de déplacer les fonctions imbriquées à l'extérieur, sauf si c'est absolument nécessaire pour laisser imbriqués. Cela devrait également simplifier d'autres tâches au cours du développement. Ma solution temporaire d'ajouter le champ d'application variable fixe car il me permet de supprimer le gestionnaire d'événements de formulaire "entrer dans le cadre" d'elle-même, mais il ne semble pas être trop compliqué pour ce qu'il fait... MERCI BEAUCOUP @SunilD !! Il va me prendre un certain temps pour déplacer l'ensemble de ces fonctions à l'extérieur, et beaucoup de références nulles peuvent apparaître à cause de cela, mais je pense que ça vaut le coup de simplicité
OriginalL'auteur Sunil D.
Voici comment j'ai été en mesure de contourner ce problème sans modifier la portée de l'fonctions imbriquées (même si je suis d'accord que ce serait la meilleure solution) par la création d'une variable booléenne appelée "loadingNewGame" et modifier la valeur vrai à partir de l'extérieur de la onEnterFrame (en fait, cette mission a été effectuée à partir de initPlay() et puis à partir de onEnterframe j'ai appelé removeEnterFrameListener() fonction. Cela a fait le tour.
voici le code au cas où quelqu'un est intéressé:
OriginalL'auteur Leo Perez