How can I make removeChild() work like unloadAndStop()? - actionscript-3

I'm building an "interactive book" using Flash and Air for iOS, and have VERY little AS3 experience...
I had planned to load "pages" in as external SWFs then banish them with unloadAndStop - so that each time a user "turned the page" the SWF loaded in and the nested mini-games in those pages would play "fresh" for the first time. Well - apparently reloaded SWFs are a no-go for AIR and iOS.
I suppose I'm left with replacing those external SWFS with Internal MCs and using AddChild / RemoveChild - but that doesn't reset the variables so that the mini-games play fresh and I'm a little too green to know a better solution.
Is there any way to beef up RemoveChild so the MC loads "fresh" every time I put it on stage?

if you you added movie clip by time line, just rename its instance name from property panel, then new instance of MovieClip created in that frame.
if you want to add it by AS3, you must set a linkage for it first, a class name which would start by a letter (recommended capital letter)
and then :
var mc:MovieClip = new Game1();
addChild(mc);
when you removed it, to adding it again with refreshed properties (as you said)
you must do:
mc = new Game1(); // make a new instance of Game1
addChild(mc);
Edit
note: for saving performance, after calling removeChild freeze your movieclip and make it ready for garbaging by removing its eventListeners, dont scare :d
tke a look at this & this (i just find this refrences by fast searching but i now they are helpful)

Related

How to properly add "Replay" functionality to a self-preloaded Flash movie?

I made a Flash project in FlashDevelop to create an Ad.
The Preloader is setup by making use of the Additional Compiler argument:
-frame=NameOfLabel,NameOfMainClass
My main class is simply called "Main", at the top / default package level.
So frame #1, being the Preloader portion of the SWF, has:
Very few bitmaps, vector-graphics and text (to stay under 50kb);
A YouTube video player in the center (does not count in the filesize limit);
The frame #2 has everything else (the Main class basically embeds all it's dependencies). This includes:
Assets from precompiled SWF (Bitmaps, Symbols, Fonts, XML data);
All classes imported (this is recursive for every classes importing other classes);
Now my big problem is, my client requested the "replay" functionality long after I've completed 99.9% of the project.
I have the project more-or-less broken into different states (Intro, Ready, SlideMenu, etc.), but I'm not sure how I can easily reset the Flash movie back to the very beginning (where it was preloading and showing the YouTube video).
The easy solution would be to simply call an ExternalInterface JavaScript method that would refresh the Flash container, BUT I don't think I have control over what's going on the HTML / JavaScript side.
Is there an easy way to invoke a replay function from AS3?
Would not simply going back to frame 1 do the trick ?
The following seems to do the trick!
private function onReplayClick(e:MouseEvent):void {
var theStage:Stage = this.stage; //Temporarly store the stage.
//Kill any animations happening:
TweenMax.killAll(); //3rd party, may not be applicable for you :P
//Remove ALL containers / child DisplayObjects
SpriteUtils.recursiveRemove(theStage); //custom-made
// (this object is no longer attached to the stage at this point)
//Nullify any Singleton / Static variables:
Main.INST = null;
// Load the 'bytes' of the current SWF in a new Loader, then...
// add it to the stage
var swf:Loader = new Loader();
swf.loadBytes( theStage.loaderInfo.bytes );
theStage.addChild( swf );
}
By doing a deep recursive cleanup of the DisplayObjects, and any static variables (like Singleton instances), it leaves you with a blank stage.
After that, you can instantiate a new Loader that will load the SWF itself via the current LoaderInfo's bytes property.
Add the Loader to the Stage, and you're up and running again!

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.

AS3.0 Replay the whole movie (*SWF file)

I made a small game in Actionscript 3.0 and flash.
When the player wins the game or is 'game over' the player should have a option to replay the game.
So my question is: Is there a way to replay the whole movie with Actionscript? I know, i could reset the timeline back to 0, and re-instantiate all the classes, movieclips, var's ect... but i was wondering if anyone knows a easier solution.
Simply do this:
import flash.net.*;
//...
navigateToURL(new URLRequest(stage.loaderInfo.url), "_level0");
You can remove the swfObject and add it again. Look here. This is the swfObject reference.
Reload the page, where you've embedded the swf into, may be the easiest way.
The programmers way would be to encapsulate your whole application into a single class (extending Sprite or MovieClip) which will be attached to the stage. For restarting the game you could simply remove that instance from the stage and add a newly created onto the stage.
Or make a loader swf, that loads your game. Then if the game should be restarted, discard (unload) the instance and load it again.
Its hard to tell you what you can do, if we don't know, how your project is structured.

AS3 preloader sorrows, unable to load symbols from library

I created an AS3 preloader, and placed the code for that on frame one.
I then made a symbol, and placed it in the library. It was set to NOT export on frame 1, and the fla's settings had all classes exported on frame two. There were no references to the object until frame two.
Then, flash crashed whenever I compiled without the "Export in frame one" box checked.
To fix this, a friend suggested I start my game logic on frame 3, so it will have properly loaded frame 2. That seemed to work fine, the class was instantiating properly.
Then, it turned out that it was not loading the movieclip, only instantiating the class. Again, this could be fixed by exporting in frame 1, but I really cannot afford to do that.
The same friend suggested I place an instance of the symbol on the stage on frame 3, and perform game logic on frame 4. They said this would initialize the movieclip properly.
However, this was not the case. How can I load the entire symbol, graphics and all, without exporting to frame 1? This single symbol will contain probably 10-20 MB of graphics, so it needs to be preloaded.
Thanks for the help!
EDIT: To make a long story short, all I need is some way to load a movieclip so it can be used and visible and everything.
EDIT: Is there any way to force-load a movieclip via AS3?
Hard to figure out from descriptions.
If you make a new .fla file, paste your large(10-20MB) clip on frame 2,
set your export frame as 2, then try to preload from frame 1 and access the large clip's content in frame 2, do you get the same error ?
say you have this in frame 1:
stop();
this.loaderInfo.addEventListener(Event.COMPLETE, onComplete);
function onComplete(event:Event):void{
gotoAndStop(2);
}
and in frame 2:
trace(myLargeClip);//where myLargeClip would be your 10-20MB clip
It should be ok, otherwise, in case tracing your large clip returns null, you might want to try to invalidate the stage:
on frame 2:
stage.addEventListener(Event.RENDER,onRender);
stage.invalidate();
function onRender(event:Event):void{
trace(myLargeClip);
}
Basically what I'm suggesting is:
Isolate the problem. See if your large clip is causing problems in a similar, but simplified scenario and why, then once you got a fix use it in your main fla.
Try the stage invalidation, although, since I don't fully understand your setup, it's just a wild guess.
HTH,
George