Get Child of loader from externally loaded swf - actionscript-3

READY? Here it is:
var TheLoader:Object = parentObj.TheExit as Object;
This line gets me to the swf I loaded and I can now change the alpha, move it etc...
BUT HOW HOW HOW... do I get one of its children and control get that same control?
Example Code:
TheLoader.TheChild.alpha = .3; // Does not work!
5 days on this issue is WAY TOO LONG! Here is the 3rd post with the same issue but more detail. as3 externally loaded swf from network to control externally loaded swf from network
I just made this shorter to get attention to the ONE LINE I NEED!!!
THANKS!

If you look at the documentation for Loader, you'll see that it has a content property. This is how you access your loaded content. So, for example, if TheLoader is a Loader, and if TheChild was an instance on the timeline of the loaded SWF, you could do:
var child : Sprite = MovieClip(TheLoader.content).TheChild;
This child is not available until the content has been actually loaded, so be sure to listen to for the COMPLETE event on the Loader's contentLoaderInfo before accessing the content:
TheLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
function onLoaded(event : Event):void
{
trace(MovieClip(loader.content).theChild);
}
Also note that you may run into security issues if the loader and loadee SWFs are not on the same domain. In this case, you will have to call Security.allowDomain in the SWFs to allow the cross-scripting.

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!

External Swf issues

I am working with external swfs. A main class loads in many external swfs immediately. They are shown later on after user input.
Just one of the external swfs is an issue. I wrote this, it is a different interaction then the rest and the audio played is separate from the main class unlike the other swfs.
So my question is, in the external swf code, is there an event listener I can use to know when this external swf is being displayed in The main class? I don't want to change the main class code since it is setup for a template that this one swf can't and won't match. Any suggestions would be great Thanks!
I guess it depends on what you are doing with this child swf, it is a pity that you are not in a position to change your main class, I mean this is in charge of the children right.
I think you could possibly do the following in your child swf:
this.addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler, false, 0, true);
function addedToStageHandler(event:Event):void
{
var child:Movieclip = MovieClip(event.currentTarget);
// do something with child
}

Loading and using SWF files

I'm new to AS3, and am trying to understand how externally loaded SWFs work in AS3. Since Flash 4/5, it was common to have one main SWF file in a Flash web project, and then load other SWF files into it, often for various "sections" of a website or web project. In the main file, we'd have masks animating the container movieclip(in which external sections/SWF files were loaded) and have animations and transitions play as the section finished loading and the loaded content was displayed.
In AS3, I've used the Loader class to load and display the external file, my main problem is in communicating with the loaded content, call it's functions, or call root functions from it.
In AS2, we could use someMovieClip.loadMovie("ExternalContent.swf") and the ExternalContent file would load inside someMovieClip. You could access functions on the "External.swf" main timeline using someMovieClip.function();. And inside the "ExternalContent.swf", we could use _root.function() to access functions in the main file ExternalContent was being loaded into. Doing this in AS3 seems bizarre and neurotic, and I feel like I'm missing something fairly basic here.
//Loading in ExternalContent.swf into the sprite
//ExternalContent has a movieclip called "boxes" on it's main timeline
//boxes has a boxesPrompt() function in it's timeline.
var sprite:Sprite = new Sprite();
addChild(sprite);
var loader:Loader = new Loader();
loader.load(new URLRequest("ExternalContent.swf"));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoaded);
function onLoaded(event:Event):void
{
sprite.addChild(event.target.content);
sprite.boxes.boxesPrompt();
//Flash gives the following compiler error at the above
//Scene 1, Layer 'Layer 1', Frame 1, Line 21 1119: Access of possibly undefined property boxes through a reference with static type flash.display:Sprite.
//But when I comment out sprite.boxes.boxesPrompt() and use this, it works:
event.target.content.boxes.boxesPrompt()
}
The boxesPrompt() function inside the "ExternalContent.swf" just traces it's parent, grand-parent, and great grand-parent - trace(this.parent.parent.parent);. And when I call that function inside the onLoaded event-handler using "event.target.content.boxes.boxesPrompt()", it shows that the Boxes object(which was on the main timeline of External.SWF), has a parent movieclip, a grand-parent sprite, and a great grand-parent object mainTimeline.
I thought re-parenting the loaded content into the sprite would allow me to access the loaded content as easily as loadMovie() used to be - accessing loaded content like it was present directly inside the clip it was loaded in. But that doesn't work at all.
So to rephrase, my question is:
How do I communicate from the main "loader" SWF file, with the content that's loaded in. I don't want to communicate using event.target.content.{etc} because then I'd only be able to address the loaded content inside the Loader's event.complete event handler.
How do I "re-parent" loaded content, so I can place it inside some movieclip/sprite on the main timeline of the loader file, rather than using some really long convoluted way.
How to communicate from inside the loaded content, to the main/loader file. Previously, we'd use _root.functionName() to do stuff like play some animation transitioning from the current externally loaded "section" to another section. How'd I go about doing that.
AS2 & AS3 is vastly different. But you will have to swallow the fact that AS3 has been developed as an improvement over AS2. So any transition you make, is also for the better.
For eg : The _root in AS2 allowed global objects & variables to accessed & changed anywhere, which is a bad practice & leads to non maintainable code in a project.
Having said that, let me address your questions:
If you are able to get access to the loaded content with
event.target.content... you should save it inside a,say class
variable & may access it later elsewhere in the class.
You must understand that you will be able to access the content only
after loading it, so have to wait for it to complete anyway &
event.complete handler is probably your best bet.
I doubt if you can pick random content from a loaded swf & re-parent it into the current swf.As explained you might not have a long convoluted way.
Accessing the parent could be done in many ways. You can use .parent or actually call a function from the parent swf passing its reference to the child.
var sprite;
addChild(sprite);
var loader:Loader = new Loader();
loader.load(new URLRequest("ExternalContent.swf"));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoaded);
function onLoaded(event:Event):void
{
sprite = event.target.content;
//This should work
sprite.boxes.boxesPrompt();
}
See this example for more info.

Loading SWF in AS3 but flash keeps repeating constructor function, what should I do?

I am importing several external files using the Loader-class, and one of them is an swf-file. When doing so (I had done it successfully before, so did not expect any issues), I ran into all sorts of errors, and finally Flash crashed.
I put down a trace in the constructor function, and it didn't trace just once, but kept on tracing, suggesting that the constructor was stuck on loop. I guess the loading of too many of the same swf is what causes flash to eventually crash.
Here is my code (the swf im loading is now a simple test-file which contains an image and no code):
private var slides:Loader = new Loader();
public function DocumentClass()
{
trace(1)
slides.load(new URLRequest("Resources/Slides.swf"));
slides.contentLoaderInfo.addEventListener(Event.COMPLETE, SlidesComplete);
}
public function SlidesComplete(evt:Event):void
{
slides.contentLoaderInfo.removeEventListener(Event.COMPLETE, SlidesComplete);
addChild(slides);
}
This traces "11111111111..." and everything dies in the end.
HELP!
Try putting a stop() action at the top of the swf you load in (either in actionscript, or on the timeline). It's possible that the swf is being loaded in and is running a play and running on loop in the mean time (hence your code running over and over).
I would do a progress watch until the swf is fully loaded, then jump to your display frame:
Create a section for loading (your choice if you want to use a preloader)
Create another section (set of keyframes) for loaded content. I use keyframes because it's easy, but you could also wait to instantiate classes until loading is complete.
Below is a snippet I occasional build from:
// stop the playhead from moving ahead
stop(); // you can also use gotoAndStop("loading"); if you want
function loaderProgressHandler(event:Event):void {
// switch the framehead to main which will show your content
if(event.bytesLoaded >= event.bytesTotal) {
event.target.removeEventListener(Event.PROGRESS, this.loaderProgressHandler);
this.gotoAndStop("main");
}
}
this.loaderInfo.addEventListener(Event.PROGRESS, this.loaderProgressHandler);
Hope that helps!
I was just stuck on this same problem.
In my case it turned out that the problem was down to the swf having the same document class name as the swf that was loading it.
eg. Main.as was loading another swf that also had its document class called Main.as - Changing this to anything else solved the infinite loop.

AS3: add event listener to loaded swf

I'm trying to listen for a custom event from an SWF I've loaded and I'm just not able to capture it. The loading code right now is just:
public function loadGame(gameSrc:String,gX:Number,gY:Number):void {
var loader = new Loader();
var addedDefinitions:LoaderContext = new LoaderContext();
addedDefinitions.applicationDomain = new ApplicationDomain();
loader.load(new URLRequest(gameSrc));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoaded);
function onLoaded(evt:Event):void {
var game:MovieClip = MovieClip(evt.target.content);
game.x = gX;
game.y = gY;
chamber.mc_gameHolder.addChild(game);
Tweener.addTween(chamber.mc_gameTitle,{alpha:1,time:.75});
game.addEventListener("showQuiz",showQuiz);
}
}
I know the event is being fired from my loaded SWF because I also have a listener in there that traces out a "hello" when it's fired.
Anyone? And apologies if this has been posted before - search didn't turn up anything specific.
I ran into the same problem. Here is what you need to do. When instantiating your LoaderContext, make sure the LoaderContext is using SecurityDomain.currentDomain. That will solve your problem.
This would work only if both SWFs are AVM2Movie (made using AS3), which I assume is the case here because otherwise casting to MovieClip would have thrown an error on run-time.
Are you sure that the event is dispatched by the document class of the loaded swf and not by one of its children? Because you are calling addEventListener on game which is the document class (root) of the loaded SWF and it won't catch events dispatched by its children. Can you show the code where you dispatch the event?
It may be possible that the event is being dispatched before the Event.COMPLETE event. Try adding a listener for the Event.INIT event. The Event.INIT event is dispatched when the Loader first has access to the loaded swf's document object.
hm, shouldn't it be :
addedDefintions.applicationDomain = ApplicationDomain.currentDomain to permit the loaded video to 'access' the parent one ?
Also for testing purposes I suggest to bubble the event up to make you haven't missed out a display object in between.
Things to consider:
The loaded clip should be from a security-enabled domain. If it's not the same domain the loading flash resides at, it should be included in the crossdomain.xml file. And loaded too.
Manually setting "allowDomain" via Security.allowDomain towards the loaded clip's domain is never bad.
The event should be bubbling, as Flash might add a layer or two of containers between the "game" var and the actual content.
Both loading and loaded clips MUST be AS3.
It is possible that the target clip is trying to load things from it's own proper location, so when you load it under a different URL, it can't find the files and fails, never reaching the event-firing phase in the first place.
Create a LoaderContext that sets the ApplicationDomain to the currentDomain, then pass it with your load() call:
loader = new Loader();
loader.contentLoaderInfo.addEventListener( Event.COMPLETE, handleLoaded );
var loaderContext:LoaderContext = new LoaderContext(false, new ApplicationDomain( ApplicationDomain.currentDomain ) );
loader.load( new URLRequest("yoMama.swf"), loaderContext );
You can confirm that you don't have a crossdomain issue by having the loading swf trace a var or function call from the loaded swf. If you get the expected result, crossdomain.xml is not your issue.
You have to consider some things in your situation.
(1) if you are loading code from the SAME domain, the app domain is not necessary.
(2) if you are loading code form DIFFERENT domains, check the [crossdomain.xml] policy file first... second... if you dont want to waste time fixing this... use PHP and curl the file to your domain... then load that (Flash will think its loading it from the same domain).