AS3 Loader's unloadAndStop odd behavior - actionscript-3

I know the AS3 Loader's class unloadAndStop() supposes to unload and stop everything on a SWF's stage when I load one, but does it also changes objects within the library (even if they are not on stage?).
I'll describe my problem to clear it up: I am loading SWFs dynamically into my AS3 application and extract required symbols from them using applicationDomain and getDefinition. The stage of the SWF/FLA I am loading is empty, and all I have are exported symbols in my library.
The problem happens when I load symbols which have pre-compiled clips inside of them (in my case, a Partigen emitter, but I don't think it really matters), which probably has event listeners or timers - the code on these clips stops working and acts weird when unloadAndStop() is called by the Loader which loaded the clip's parent SWF. I assumed unloadAndStop() removes a required event listener from it, but not sure why (again, it's not on the stage).
I'd write my own kind of unloadAndStop() that filters these pre-compiled clips or checks what's truly going on there, but I am pretty sure that unloadAndStop() does things which are unavailable through the API.
What can explain this behavior? Anyone can think of a possible solution?
Thank you.

Make your loader in this way:
myLoader.contentLoaderInfo.addEventListener( Event.INIT , myLoaderHandler, false, 0, true);
It solves some problems due to unloadAndStop().

Related

Internal AS3 preloader & stage issues

I need to create a single SWF with no external files, so I'm trying to add an internal preloader to my Flash project which has [embed] assets. I know [embed] causes problems with preloaders because it puts the assets on frame 1. I have tried the solutions recommended in these posts, where you set the document class to your preloader class:
Preloader for SWF with embed bytearray
How to create Preloader in AS3
I can get it to work, but ONLY if I comment out any lines of code that involve the stage, otherwise I get an "Error #1009: Cannot access a property or method of a null object reference." Those lines are essential though, so does anyone know how to fix those errors with the stage?
You haven't posted your code or your fla, so all I can do is share what works for me.
First, I wouldn't use Embed. Instead, use a swc. I have found that Embed can be unreliable as far as actually getting the entire asset in there (at least when publishing with Flash Builder + Flash Pro, which is my workflow).
Once you have your assets in a swc, try the following steps:
Set your export frame to Frame 10 (or any frame other than 1--I like frame 10 because then you can read the label that says "Preloader")
Put your actual content on frame 11. You can structure this a lot of ways. Since I program to Interfaces, I give whatever is on frame 11 an instance name and then use a setter to determine that my "first thing" has been placed on stage. I can get away with this because my main Document Class just knows the definition of the Interface, not the full implementation of the Class, so the Class does not need to load for the main Document Class to work. You probably aren't truly using the timeline and probably didn't program to interfaces, so you'll probably just set the base class of the symbol that's on frame 11 to the main logic of whatever you're trying to do.
Put your preloader graphics in Frame 1. I'm not sure why your stage references are so important. I, personally, don't use any logic in the preloader. Instead, I use a spinner that spans frames 1-10 (plus the word "Loading...". The spinner just spins while the classes load. The embed frame acts as a temporary "stop" that just holds the timeline back until those classes have been loaded. Once the classes have been loaded, the timeline will act like you called play() on it. So it really can be that simple. If you need it to be more complicated, give one of your preloader graphics an instance name and set up a getter/setter pair for it, then use the setter to trigger your logic that accesses the stage. You are pretty much guaranteed to have a valid stage at that point.
Word of warning: if you did make use of the timelime, you will get strange results if you try to jump to a frame that isn't loaded yet, so make sure to check to see if a given frame is loaded if it's near the end of your main timeline and your main timeline is heavy with assets before calling goToAndPlay() or goToAndStop().
Some references that might help you further:
Preloaders vs as 3 (I'd recommend you read the entire series this is part of. This is an amazing series I wish I'd found 3 years ago)
Solving the Frame 2 Problem Presentation and code
Combining the Timeline with OOP The example code for that is here (long story)

As3 preload/render a single movieclip before addChild to stage

I have some problems. I want to preload a single movieclip instead of preloading the whole project. Is there a way to that.
Concept Game.
Intro Displayed - Intro removed - Title Dislplayed - Title removed "after pressing on screen"
[[[[[[[PRELOAD CUT SCENE]]]]]]] if completed display CUT SCENE.
Thats the plan, but i do not know how.
Yes, there is a way to do that. But you need several SWFs for that, each containing a single movie clip that you want to be separately preloaded. You make a Loader object for each one, you have an URL for each one, then you call Loader.load() at appropriate time (say, after successfully preloading previous one) and assign a Event.COMPLETE listener that would fire once the movieclip is loaded. Don't forget to assign an error event loader as well, otherwise your game would stuck should it fail to preload a cut scene. More in the documentation for Loader class.

Why would a keyframe in Flash fail to update an object's position as defined in the keyframe when the play head is sent to that frame?

I have a background MovieClip in a custom button class, which moves the play head to a different frame (via gotoAndStop("framename")) depending on which mouse events it receives.
When the mouse up event is received, it sends the play head back to the "release" frame, where the background should shift back to its original location, but instead nothing happens and the background remains where it was. It's as though Flash is not honoring the background's position defined by the key frame it enters.
The only workaround is to add a frame script to each frame which manually sets the x and y position to what it should be, but this defeats the purpose of using keyframes for the position.
What is going on?
Try calling event.updateAfterEvent(), it's supposed to
Instructs Flash Player or Adobe AIR to render after processing of this event completes, if the display list has been modified.
from here: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/events/MouseEvent.html#updateAfterEvent%28%29
This appears to have been a bug in the Flash IDE, specifically some kind of corruption in a timeline layer.
The corruption originated in Flash CS4, but persisted when opened and compiled in Flash CS5, which is why I suspect it was some kind of content-generation bug, rather than something specific to either IDE version. The IDE probably gets confused when you construct the timeline out of order or drag things around, rename things, copy things in from other files, etc. I think, specifically... it was the fact that I copied this particular object in from another file. And it wasn't even a complex object, it was just a MovieClip that contained a rounded rectangle and had a drop shadow applied, seriously.
Steps I took to resolve the issue were to remove any classes associated with the library item, reverting it back to a standard MovieClip. I then completely removed the problematic layer. I then reassigned the class to the library object and exported it for ActionScript. Finally, I rebuilt the layer from the first frame, adding subsequent keyframes as necessary. I reapplied filters, and adjusted the clips location on each frame.
Now, everything is functioning as expected. The clip's position, filters, etc. are all updated as expected when the playhead moves to any frame. It's working now as expected, so I wasn't doing anything wrong or not possible. It simply must have been some kind of incrementally constructed key framing confusion within the data structures of the IDE. Glad it's working now.

Flash memory management and Actionscript

There was many discussions about this problem, but I want to pay attention on the situations that IMHO seems not so clear:
Yes the general rules are:
Remove chachedAsBitmap
Stop movieClip if playing
Remove events
Delete references
etc.
But let's look:
First Example:
I have nested sprite (ex: mainSprite), it contains other sprites with dynamic textFields in it (and are chached as bitmaps), just textFileds and MovieClips with event listeners on it (with weak reference).
When I need to remove this sprite I need first to remove all it's nested content via loops or just
removeChild(mainSprite);
mainSprite=null;
is just enough?
Second Example:
I have some sprite in which I'm loading bitmap and manipulating with bitmapData, later I'm just replacing content of this sprite with another bitmap, is allocated memory for older bitmap automatically erases and is overwritten or it still exists?
Third example:
I have some "graphics template" MovieClip (in library with Export for Actionscript property set on it) which I'm adding on the stage and filling with dynamic data (and adding event listeners), let's say that it's one scene of the app, on another scene I need same MovieClip with other dynamic data, but inbetween need to clear my stage (need something like transition animation which is also library MovieClip), what's the best way: to set this MovieClip visible property to false (while transition animation is plays) and then reuse it, or just remove it with removeChild and then add when add with addChild once more?
All I wrote is more about Air Mobile, cause in most cases for the desktop these situations aren't so problematic, but in case of mobile development they are.
You can visually monitor memory usage along with fps etc using this lib: http://code.google.com/p/flash-console/
hope that helps.
P.S. gc in flash is always a weird thing :)
First example: removing mainSprite from display list is enough if there are only weak listeners on its children.
Second example: I'd advice reusing the same object with visible = false. Recreating the same object is more resource expensive plus you get another instance of the same thing being in memory before it gets gc'ed.

as3 removeChild issue

I'm loading some swf files at 0 on my stage. They are the pages of my site.
To change from page to page I use removeChildAt(0) and then I addChildAt("page_title", 0).
The problem is that removeChild dont delete the functions from the first swf file loaded (before unloaded).
How can I stop then?
Do I have to use other way to removeChild?
Thanx!
It sounds to me like you aren't actually removing them. First things first, removing something from the display list is only a visual/interactive change. It is still running until you remove any references to it, being event listeners or w/e, and then you must set it to null so that garbage collection will grab it on the next cycle.
If you are using Flash Player 10, spender is correct that unloadAndStop will work for you as they just recently created it to fix your very problem.
I just thought I should explain what is going on, because people should not only know about the fix, but why things happen.
One other suggestion, I wouldn't load these movies to stage, I would create a container Sprite/MovieClip to hold them, that way even if you add other things later, they are separated, clean, and easy to access through their parent (imageContainer_mc for instance).
Assuming you are loading with a Loader you can use the unloadAndStop method.
More info here:
http://www.gskinner.com/blog/archives/2008/07/additional_info.html
Alternatively, you can load the submovie into a different ApplicationDomain to insulate the loaded code from your main app. Take a look at the flash.system.ApplicationDomain class (it's a parameter to the Loader.load() method).