Copy link to clipboard
Copied
Hey once again,
I'll try to do my best to explain. I can get this to work correctly, but I'd like to understand why what I was doing earlier wasn't working.
I'm having a little trouble understanding why an event listener continues listening even after I remove it. I have a set-up where, a Parent MovieClip ("CampScene") is established, and an event listener is added to listen for a function ("walkUpToCampfire") to see if a condition is true ("comingFromAx == true", which won't be true until later).
If it is true, an animation plays, an event listener is added to see if the animation is done, and if it is an event listener is added to listen for a click ("campScene.goToAx") for a new animation to play and other events to occur. (It won't be set to true until later.)
If it isn't true (which is the situation I'm working with initially), the event listener told to listen for a click on "campScene.goToAx" is set up immediately. The function that follows removes the event listener, thus it's suppose to stop listening for a click and let an animation play all the way through.
The problem is a click continues to be listened for, and if one keeps clicking the animation restarts each time, which is what I don't want to happen.
--------------------------------------
I'm able to solve the problem by adding the line "campScene.removeEventListener(Event.ENTER_FRAME, walkUpToCampfire);" or by setting mouseEnabled to false for "campScene.goToAx", but I'm trying to understand what is going on.
Is it, even though I'm removing the ("campScene.goToAx") listener in one function ("goToAxScene"), "campScene.addEventListener(Event.ENTER_FRAME, walkUpToCampfire);" continues to listen for a mouse click unless it is removed also?
Again, I'm just trying to understand how this is working.
--------------------------------------
This should be all the relevant AS. Naturally, let me know if more information is needed. (I can post the FLA/AS files if need be.)
public function practice_adventure8() {
...
//initial event listeners
addEventListener(Event.ENTER_FRAME, CampScene);
}
public function CampScene(event:Event) {
//remove the event listener
removeEventListener(Event.ENTER_FRAME, CampScene);
//add the initial camp scene
campScene.x = -120;
campScene.y = -10;
addChild(campScene);
setChildIndex(campScene, 0);
//add event listener to see if guy walking to campfire or not
campScene.addEventListener(Event.ENTER_FRAME, walkUpToCampfire);
}
//IF WALKING BACK TO CAMPSCENE
public function walkUpToCampfire(event:Event) {
//if guy is walking back from ax
if (comingFromAx == true) {
//event listeners
campScene.guyAtCampScene.gotoAndPlay("guyComingFromAx");
campScene.addEventListener(Event.ENTER_FRAME, ifGuyDoneWalking);
//else if initial creation
} else {
//remove old event listener
//campScene.removeEventListener(Event.ENTER_FRAME, walkUpToCampfire);
//trace("comingFromAx=FALSE");
//event listeners
campScene.addEventListener(Event.ENTER_FRAME, sceneHoverInfo);
campScene.goToAx.addEventListener(MouseEvent.MOUSE_UP, goToAxScene);
//campScene.goToBridge.addEventListener(MouseEvent.MOUSE_UP, goToBridgeScene);
}
}
//IF WALKING BACK TO CAMPSCENE DONE
public function ifGuyDoneWalking(event:Event) {
//if guy has finished walking
if (campScene.guyAtCampScene.currentLabel == "guyAtCampSceneNormal") {
//reset the scene booleans
comingFromAx = false;
//add the event listeners
campScene.addEventListener(Event.ENTER_FRAME, sceneHoverInfo);
campScene.goToAx.addEventListener(MouseEvent.MOUSE_UP, goToAxScene);
}
}
//GET READY FOR NEW SCENE
public function goToAxScene(event:MouseEvent) {
//remove any movement event listeners
campScene.goToAx.removeEventListener(MouseEvent.MOUSE_UP, goToAxScene);
//stop all relevant sounds
SoundMixer.stopAll();
//play clip of guy walking to AxScene
campScene.guyAtCampScene.gotoAndPlay("guyGoingToAx");
//check for label to see if axScene should appear
campScene.guyAtCampScene.addEventListener(Event.ENTER_FRAME, addScene);
}
YOur best bet to resolve why things happen is to make use of the trace function. In this case you could have a trace execute anytime that listener gets addedand any time it gets removed. That way you should be able to see whether it was added back in after you removed it. If there are multiple places where it gets added, then adjust your traces to indicate which line is involved as well.
Copy link to clipboard
Copied
You have so many event listeners in the code you show that it is difficult for me to associate it with your explanation. I cannot tell which listener is in question. The listener has to still be present in order for it to function.
Copy link to clipboard
Copied
Ned Murphy wrote:
You have so many event listeners in the code you show that it is difficult for me to associate it with your explanation. I cannot tell which listener is in question. The listener has to still be present in order for it to function.
EDIT: If this is still hard as hell to understand, don't worry about it. I understand that having so much code that one didn't write - especially written unprofessionally - can be hard to understand. Thanks anyways for attempting anyways.
Sorry, the event listener in question is "campScene.goToAx.addEventListener(MouseEvent.MOUSE_UP, goToAxScene);". It is used in two or three different places, but it is only suppose to run once depending on whether a condition is true or false.
I remove it in the function goToAxScene(event:MouseEvent), the bottom-most function. I do have that same event listener in question listening elsewhere (in the function ifGuyDoneWalking), but it's only set to listen if a condition is true, and my code is not set to run the condition as true (the }else{ is what runs in walkUpToCampfire). Nevertheless, that event listener seems to still be listening, even though the removal "campScene.goToAx.removeEventListener(MouseEvent.MOUSE_UP, goToAxScene);" runs in the bottom-most function.
I'm wondering if this is because "campScene.addEventListener(Event.ENTER_FRAME, walkUpToCampfire);", the event listener in the second function from the top, was not removed and thus it was still listening for a MouseEvent, or something to that extent. If I remove that event listener under the "}else{" in "walkUpToCampfire"("campScene.removeEventListener(Event.ENTER_FRAME, walkUpToCampfire);"), I appear to have no problems.
public function CampScene(event:Event) {
...
campScene.addEventListener(Event.ENTER_FRAME, walkUpToCampfire);
}
public function walkUpToCampfire(event:Event) {
if (condition == true) {
campScene.guyAtCampScene.gotoAndPlay("guyComingFromAx");
campScene.addEventListener(Event.ENTER_FRAME, ifGuyDoneWalking)
} else {
//if I have the line of code below running, the click is only listened for once, which is what I want.
//I'm trying to understand why I have to remove this event listener if the listener I want to turn off
//"campScene.goToAx.addEventListener(MouseEvent.MOUSE_UP, goToAxScene);", is turned off
//in function "goToAxScene".
//campScene.removeEventListener(Event.ENTER_FRAME, walkUpToCampfire);
campScene.addEventListener(Event.ENTER_FRAME, sceneHoverInfo);
campScene.goToAx.addEventListener(MouseEvent.MOUSE_UP, goToAxScene);
//campScene.goToBridge.addEventListener(MouseEvent.MOUSE_UP, goToBridgeScene);
}
}
// only suppose to run if (condition == true), which it isn't
public function ifGuyDoneWalking(event:Event) {
if (campScene.guyAtCampScene.currentLabel == "guyAtCampSceneNormal") {
condition = false;
campScene.goToAx.addEventListener(MouseEvent.MOUSE_UP, goToAxScene);
}
}
public function goToAxScene(event:MouseEvent) {
//suppose to remove the movement event listener, but it seems to keep listening elsewhere
campScene.goToAx.removeEventListener(MouseEvent.MOUSE_UP, goToAxScene);
}
Copy link to clipboard
Copied
YOur best bet to resolve why things happen is to make use of the trace function. In this case you could have a trace execute anytime that listener gets addedand any time it gets removed. That way you should be able to see whether it was added back in after you removed it. If there are multiple places where it gets added, then adjust your traces to indicate which line is involved as well.
Copy link to clipboard
Copied
I had actually been using various trace statements, but for what it's worth, your comment about so many event listeners encouraged me to try to find "a better way" to write my code, having only a handful of event listeners, constantly listening when appropriate, and instead turning on and off the ability for the mouse to click on things.
Copy link to clipboard
Copied
My guess would be that you've got more than one campScene instance involved, so you may not be removing the listener from the instance where it was added. My recommendation would be to do one of two things:
public function get campScene():MovieClip {//also, please start specifying return types on your functions!
return _campScene;
}
public function set campScene(value:MovieClip):void {
if (value != _campScene) {
if (_campScene) {
_campScene.removeEventListener('someEvent', someHandler);
}
_campscene = value;
if (_campScene) {
//if you want to make sure you're listening to the new instance, add listeners here
}
}
}
Copy link to clipboard
Copied
I solved this, but thanks. I'm sure your advice is useful but still a bit out of my league of understanding. (Like, I don't know why I want to return something.) Could you give me an example of how I could make use of REMOVED_FROM_STAGE with a listener and the follow-up function?
Amy Blankenship wrote:
My guess would be that you've got more than one campScene instance involved, so you may not be removing the listener from the instance where it was added. My recommendation would be to do one of two things:
- Listen to campScene for REMOVED_FROM_STAGE whenever you add any other listeners, then clean up those listeners in the handler.
- Use a Getter/setter pair for campScene, and clean up all outgoing instances when the value of campScene changes. That would look something like this:
public function get campScene():MovieClip {//also, please start specifying return types on your functions!
return _campScene;
}
public function set campScene(value:MovieClip):void {
if (value != _campScene) {
if (_campScene) {
_campScene.removeEventListener('someEvent', someHandler);
}
_campscene = value;
if (_campScene) {
//if you want to make sure you're listening to the new instance, add listeners here
}
}
}
Copy link to clipboard
Copied
If you're not returning something, you should specify a return type of void (the exception being the constructor, and in that case the lack of a return type then makes it easier to determine that what you're looking at is the constructor.
You'd use the REMOVED_FROM_STAGE listener something like this:
//note lack of return type. This is the constructor, but I don't know the name of your Class so I can't make it match
public function MainDocument() {
super();
//removed from stage doesn't bubble, need to listen on capture
addEventListener(Event.REMOVED_FROM_STAGE, checkForCampSceneRemoval, true);
}
protected function checkForCampSceneRemoval(e:Event):void {
//This will trigger whenever anything is removed, which is why the other solution
//is preferable in most cases. Check to see if this is the thing we care about.
var instance:MovieClip = e.target as MovieClip;
if (instance.name=='campScene') {
instance.removeEventListener('someEvent', someHandler);
}
}
Find more inspiration, events, and resources on the new Adobe Community
Explore Now