Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411716 Posts in 69402 Topics- by 58450 Members - Latest Member: FezzikTheGiant

May 21, 2024, 10:07:12 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Removing a child clip and all his children
Pages: [1] 2
Print
Author Topic: Removing a child clip and all his children  (Read 2980 times)
davidp
Level 6
*



View Profile WWW
« on: May 16, 2010, 06:26:57 AM »

hello, this is davidp.

i'm having yet another flash problem. this time i'm working on a level transition and i've stumbled across this problem i can't solve myself.

so i have each level in seperate .as file (level1.as, level2.as, level3.as), each one with it's enter_frame events and so on.

so normally levelX.as will execute, making things happen and when i hit certain point in the game i want that level to end and move on to next one.

so i have a code where Main.as checks if (level.hasFinished) and then executes function that should remove level and all his children.

remove all children of current level:

Code:
public function clearLevelOfAllInstances():void
{
    while (level.numChildren)
    level.removeChildAt(0);
}

and then i remove current level:

Code:
removeChild(level);
(returning to main menu for now)

but the problem is that everything in current level still happens (i hear sounds of enemies firing), but that clip is "gone" - i see main menu and stuff. so i guess i didn't really removed current level clip or should i also stop it's enter frame loop or anything?

i thought removing a child will simply remove all its content (arrays, variables, etc), but i guess i'm wrong.

any thoughts about the problem at hand?
« Last Edit: May 16, 2010, 06:32:33 AM by davidp » Logged

Draknek
Level 6
*


"Alan Hazelden" for short


View Profile WWW
« Reply #1 on: May 16, 2010, 07:11:23 AM »

removeChild stops an object being rendered, it doesn't do anything else. The object is still there, and it could be re-added later if you wanted to. Flash doesn't know that there's any connection between that display object being visible and some enterFrame event listener which should be called.

So you should add the enterFrame event handler at the same time you call addChild, and remove the enterFrame event handler when you call removeChild.
Logged

Triplefox
Level 9
****



View Profile WWW
« Reply #2 on: May 16, 2010, 07:46:20 AM »

Removing children only takes them off the display list; it won't remove references from code, and removing all references doesn't remove event listeners unless you create them with a weak reference. There have been nasty AVM memory leak bugs related to weak references so it's not a good plan to rely on those either.

You should be able to fix this by clearing all data structures and manually removing all possible listeners in try{} blocks. If your gameplay data is organized in bundles for "Game" or "Level", it's not so hard to reset when a scene transition or game restart is needed, but it's exactly the problem of stage and event management that makes me avoid using them for gameplay elements - I prefer being able to disable and remove stuff by nulling it or taking it out of a loop.

For that reason I use draw() and copyPixels() for visuals; you can compose a DisplayObject hierarchy that is off of the stage, draw() it to a screen bitmap, and then throw the entire hierarchy away without any manual management. Input is harder to resolve, so you might want to compromise there and put together a static UI, put the entire thing on the stage at boot, and then just toggle visibility. If you want to be able to click on DisplayObjects used in gameplay, you can pass events from the screen bitmap into your own code and use DisplayObject.hitTest() or Rectangle.contains() on the relevant elements.
Logged

davidp
Level 6
*



View Profile WWW
« Reply #3 on: May 16, 2010, 08:27:39 AM »

wow, thanks for comprehensive replies guys.

this clears up al lot of confusion.
Logged

bateleur
Level 10
*****



View Profile
« Reply #4 on: May 16, 2010, 09:03:13 AM »

For that reason I use ...

Perfectly reasonable if you find it easier of course, but for the benefit of any less experienced Flash coders reading this I should make clear that it is absolutely not necessary to avoid use of DisplayObject hierarchies, vector graphics and so on. It all works perfectly straightforwardly and doesn't create weird, freaky problems unless you decide not to read the docs and instead guess what it's going to do. Roll Eyes

The main problem likely to arise in practice is if you've done a lot of work in languages without garbage collectors. Working with a garbage collector is not magic - although the garbage collector is very good at working out when you've finished with your resources there are a few things that it can't deal with. One of those things is when you create a callback or closure of some sort that points back to some object you're done with. You think of the object as pointing to the closure you defined within its class file somewhere, but really it's the other way around and this innocent little unnamed function will keep the entire class instance alive if you leave it lying around. Adding event listeners is a common way to make this mistake.

Fortunately the fix is really easy. Keep track of all the handlers you add and call removeEventHandler() on each of them when you remove your level from the screen.
Logged

davidp
Level 6
*



View Profile WWW
« Reply #5 on: May 17, 2010, 12:14:04 AM »

Quote
Fortunately the fix is really easy. Keep track of all the handlers you add and call removeEventHandler() on each of them when you remove your level from the screen.

excatly what I'm using right now and works great.

should i also clear all arrays and other data in level i just removed? if i leave everything as it is, can it effect game perfomance later on? i guess not?
« Last Edit: May 17, 2010, 03:09:59 AM by davidp » Logged

CiroContinisio
Level 3
***


Eat this!


View Profile WWW
« Reply #6 on: May 17, 2010, 01:56:55 AM »

should i also clear all arrays and other data in level i just removed? if i leave everything as it is, can it effect game perfomance later on? i guess not?
If you remove listeners everything should be fine: when Flash loses all of the references to those arrays and variables, he will remove them for you.
In the case of display objects, you only need to remove all references to them and then remove the uppermost display object (the parent of all the others) from the display list.
Logged

davidp
Level 6
*



View Profile WWW
« Reply #7 on: May 17, 2010, 03:11:19 AM »

thank you, that halps a lot Smiley
Logged

st33d
Guest
« Reply #8 on: May 17, 2010, 03:59:55 AM »

I personally use a recursive dive into a MovieClip to stop all animations when I remove it. That means I can put animations together with sound in and not have to have a premeditated approach to putting my project together. I just animate, and go...

Here's the stopClips method I use (I use it for pausing the game as well):

Code:
package {
import flash.display.DisplayObjectContainer;
import flash.display.MovieClip;

/* Pause hack - freezes mc and all of its children */
public function stopClips(mc:DisplayObjectContainer):void{
for(var i:int = 0; i < mc.numChildren; i++){
if (mc.getChildAt(i) is MovieClip){
(mc.getChildAt(i) as MovieClip).stop();
}
if(mc.getChildAt(i) is DisplayObjectContainer){
stopClips(mc.getChildAt(i) as DisplayObjectContainer);
}
}
}

}
Logged
ishlilith
Level 0
**


View Profile WWW
« Reply #9 on: May 17, 2010, 04:52:16 AM »

If you remove listeners everything should be fine: when Flash loses all of the references to those arrays and variables, he will remove them for you.

Don't count on that. If there are enough circular references the GC will never remove them.
Logged

BorisTheBrave
Level 10
*****


View Profile WWW
« Reply #10 on: May 17, 2010, 11:47:25 AM »

Don't count on that. If there are enough circular references the GC will never remove them.
Citation please?
Logged
increpare
Guest
« Reply #11 on: May 17, 2010, 12:37:26 PM »

Don't count on that. If there are enough circular references the GC will never remove them.
Citation please?
see here

Quote
In practice (maybe this is in the spec, I don't know, but I missed it if it was), there seems to be a limit on just how big an orphaned group of objects can be before the GC just gives up and assumes the whole group is still being used.
Logged
ishlilith
Level 0
**


View Profile WWW
« Reply #12 on: May 17, 2010, 12:47:18 PM »

Don't count on that. If there are enough circular references the GC will never remove them.
Citation please?

http://www.andymoore.ca/2010/03/motherfucking-as3-garbage-collection/

http://tomgabob.blogspot.com/2009/11/as3-memory-management.html

EDIT: Too late. Perhaps I shouldn't read the pages I link to before posting them Smiley
Logged

Matt Thorson
Level 7
**

c'est la vie


View Profile WWW
« Reply #13 on: May 17, 2010, 01:19:37 PM »

I haven't personally run into any problems with the garbage collector aside from the event listener issue, but that makes sense to me. Make sure you remove your listeners.

I also use System.gc(); to force a garbage collector sweep on level load/restart, since that's a moment where slowdown isn't noticeable and it could reduce drastically the amount of collecting that will go on during gameplay.

Something else worth mentioning is that object creation can be costly, so for things like particle systems where lots of instances are being created then quickly reference nulled I usually just recycle instances (basically I do what he calls "object pooling"). I haven't found object pooling to be necessary for much else (yet).
Logged

BorisTheBrave
Level 10
*****


View Profile WWW
« Reply #14 on: May 17, 2010, 01:54:08 PM »

I've hit object pooling pretty hard for Box2DFlash, but always laughed at the idea of nulling references. I guess I'll have to start introducing it now, pretty sure a large physics world could qualify for this gotcha.
Logged
increpare
Guest
« Reply #15 on: May 17, 2010, 02:33:20 PM »

I've hit object pooling pretty hard for Box2DFlash, but always laughed at the idea of nulling references. I guess I'll have to start introducing it now, pretty sure a large physics world could qualify for this gotcha.
Probably worth profiling first, seeing if you can find anything sexy. : )
Logged
ishlilith
Level 0
**


View Profile WWW
« Reply #16 on: May 17, 2010, 02:42:40 PM »


I also use System.gc(); to force a garbage collector sweep on level load/restart, since that's a moment where slowdown isn't noticeable and it could reduce drastically the amount of collecting that will go on during gameplay.

I think you are mistaken.
From https://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/system/System.html#gc%28%29

Quote
Forces the garbage collection process.

For the Flash Player debugger version and AIR applications only. In an AIR application, the System.gc() method is only enabled in content running in the AIR Debug Launcher (ADL) or, in an installed applcation, in content in the application security sandbox.
Logged

Matt Thorson
Level 7
**

c'est la vie


View Profile WWW
« Reply #17 on: May 17, 2010, 02:50:53 PM »

I stand corrected!
Logged

davidp
Level 6
*



View Profile WWW
« Reply #18 on: May 17, 2010, 11:56:31 PM »

a lot of useful stuff here! Beer!

nice, keep it going, i might learn even more :D
Logged

bateleur
Level 10
*****



View Profile
« Reply #19 on: May 18, 2010, 01:39:47 AM »

Wow, that GC misfeature is Seriously Weak Sauce. Shocked
Logged

Pages: [1] 2
Print
Jump to:  

Theme orange-lt created by panic