AS3: add event listener to loaded swf - actionscript-3

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).

Related

When the game of an external swf is finished, remove the external swf

I am creating a series of mini games and animations and plan on bringing them all into one flash file. Each of the games need to disappear when the player has finished them. I don't know what to put into the section in the external swfs when the game is done. I currently just have a trace ("finished").
In my main swf you should click start and a game swf appears and when you are finished it, it should disappear.
I have looked up tutorials and they something about accessing variables in the external swfs but I got nowhere with them.
in place of trace("finished");, dispatch something like a complete event:
dispatchEvent(new Event(Event.COMPLETE));
Then listen for that event in the container swf and respond appropriately.
Here is an example for the host (parent) swf:
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loadDone, false,0,true);
loader.load(new URLRequest("temp2.swf"));
function loadDone(e:Event){
trace("CONTENT LOADED");
addChild(loader.content);
loader.content.addEventListener(Event.COMPLETE,go,false,0,true); //listen on the capture phase (third parameter true) if you're complete event is NOT on the main timeline of your child swf
}
function go(e:Event):void {
trace("Content is all done");
removeChild(loader.content);
loader.unloadAndStop(); //tries to free the app of all memory used by the loaded swf
loader = null;
}
Another way, is in place of trace("finished"), you could have the child swf remove itself (as per a comment on the question). I would consider this a less desirable solution (though more encapsulated) as it lessens re usability and will likely still leave the swf in memory:
stop();
if(this.parent){
this.parent.removeChild(this);
}

How to play two swf files in as3

hai i want play two swf files in my action script project.In this two files one swf file works on the detection face in front of the system.Other swf plays the flv file.when face is detected player must be stooped if not player must be plays the flv file.
I know how to load the swf file but i cant handle the functionality regarding starting and stoping player.
the snippet of code shows how can i load external swf file .and i will explain each line of code in comments
public function videos(view:Sprite)
{
this.box = view;//IT GETS Sprite object from other class because of need to display the player also.
request = new URLRequest("Untitled-1.swf");
currentSWF=new MovieClip();
loader= new Loader();
loader.load(request);
box.addChild(loader);
currentSWF = MovieClip(loader.content);
loader.addEventListener(Event.COMPLETE,loadComplete);
//addChild(loader);
currentSWF.gotoAndPlay(1);//when i put this line of code in comments it plays the external swf also.
}
I hope u understand my doubt .can any one explain how to handle my things .i am new to this action script.please help me
Loaded files automatically play, unless you tell them explicitely not to. You’ll have to listen to the Event.INIT event, and stop the movie there:
loader.AddEventListener(Event.INIT, initLoader);
function initLoader (event:Event)
{
MovieClip(event.currentTarget.content).stop();
}
This will stop the movie before it is attached to the stage, and before it starts playing—so it won’t do that unless you start it again.
Note that you shouldn’t access loader.content in any way before the INIT or COMPLETE events, as it’s very likely that the content isn’t loaded then. As such you should put all your manipulating actions into the COMPLETE event:
box.addChild(loader);
loader.addEventListener(Event.COMPLETE, loadComplete);
function loadComplete (event:Event)
{
// Now it’s safe to access the `content` member:
currentSWF = MovieClip(loader.content);
// Of course this one would play the movie again, so you probably want
// to call that later on a button click or something.
currentSWF.gotoAndPlay(1);
}

Unloading external SWF files

I'm loading multiple swf files from the main menu which is never unloaded. I've done this with the following code... Only issue is that instead of unloading to the main menu I just see a white screen as if nothing is loaded.
function BackToMenu(i:MouseEvent):void
{
var BaseMovie:MovieClip = parent.parent as MovieClip;
BaseMovie.parent.removeChild(BaseMovie);
}
EDIT: I'll explain from the start I have a MainMenu.swf. The games are loaded from MainMenu.swf when the button relating to the game is clicked. When a game button is clicked on MainMenu.swf the game loads. When the player completes a game they are presented with the exit button which unloads the current game and shows the MainMenu.swf without having to re-load it.
First, you should remove one parent to make sure you are actually removing only the game:
function BackToMenu(i:MouseEvent):void
{
var BaseMovie:MovieClip = parent as MovieClip;
BaseMovie.parent.removeChild(BaseMovie);
}
This should take care of your most pressing problem, and allow you to return to the menu. You have, however, not really unloaded the game, but only removed it from the display list. This often means, that there are still sounds running, active key and/or mouse listeners, etc. - these must all be taken care of!
And, like I said, this will only fix your immediate problem. It is, however, neither a permanent solution, nor a good one: Since the main SWF is responsible for loading the games, it should also be responsible for disposing of them. You should put cleanup code into your game, but it should only be concerned with stopping any running scripts, sounds, etc. - simple rule: anything that is started within the game, should be stopped within the game. But it should not try to access objects further up in the display hierarchy, or try to unload itself.
The much better way to do this is by replacing all the above code, and letting the main SWF take care of removing the game, as well as unloading it from memory. For this, you have to do three things:
Instead of writing actual removeChild calls, etc., let your button dispatch a custom event to notify the main SWF that it should now be removed:
function onBackButtonClicked( event:MouseEvent ):void {
destroyGame(); // this would be the function that stops all the scripts
dispatchEvent( new Event( "FINISH_GAME", true ) );
}
Note that "FINISH_GAME" is now a "bubbling" event, i.e. it travels downward in the display hierarchy. We can now listen for this event in any ancestor display object containing the game.
In your main SWF, add an event listener to the Loader when the game was successfully loaded. This is done in the event listener that is called when the load process completes:
function onLoadComplete( event:Event ):void {
var loader:Loader = event.target.loader;
loader.addEventListener( "FINISH_GAME", onFinishGame, true );
}
Use the corresponding event handler to remove the game clip:
function onFinishGame( event:Event ):void {
var loader:loader = event.currentTarget;
loader.parent.removeChild( loader );
loader.unloadAndStop();
}
A few more things to consider:
The naming conventions in ActionScript advise us to use lower case names for methods and variables, and upper case only for types.
The same naming conventions suggest we use either "on" or "handle" as a prefix for event listeners, along with the name of the event. Thus, it should be onBackToMenu or rather, onBackButtonClicked, etc.
Since I don't know anything about the code you use for loading, I just assumed you have a complete listener, and you don't keep references to the loader. If you use a member variable, you can use that instead of event.target, resp. event.currentTarget.

Get Child of loader from externally loaded swf

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.

AS3 ScrollPane dispatch event to content

i've loaded external swf into ScrollPane and i need to dispatch click event to this external swf. is it possible? ScrollPane.content.dispatchEvent(new MouseEvent(MouseEvent.CLICK,true)); doesn't work. this is obvious cuz ScrollPane.content is an DisplayObject and it have not CLICK event...
I can't use MovieClip as container for external swf cuz external swf is a documents converted to swfs using openoffice and it doesn't want to load inside MovieClip but perfectly loads inside ScrollPane and react on mouse clicks,but i need to simulate mouse click on it.
so you're saying that the following won't work or you haven't tried it?
var exSWF:MovieClip = MovieClip( ScrollPane.content );
or
var exSWF:Sprite = Sprite( ScrollPane.content );
Not sure to understand what you mean when you say that your external SWF won't load into a MovieClip.
Do you know what version of Actionscript was used for the external SWF, you can check that in debug mode by looking at the properties of the ScrollPane.content?