Communicating to and from External SWFs

Created August 24, 2009    Last Updated: September 18, 2011

Skill Level: Intermediate. Actionscript version: AS3

Flash skills needed:
  1. Creating MovieClip symbols
  2. Simple animation
  3. Using ActionScript panel

This tutorial is going to show you how to load an external SWF( the 'externally loaded swf") into another swf ( the main swf i.e. the 'main time-line") and how to use actionscript to communicate between the two.

Here is the finished piece that we will be aiming for:

This file consists of a 1 frame "main time-line" swf that will be the 'shell' that will load in the external SWF. This SWF will contain a button which will load the External SWF. It will also have 2 other sets of buttons. The first set will call to the external SWF to stop and start its animation of a red ball bouncing back and forth. It will also have another set of buttons, which will, using Caurina's Tweener class, slowly fade in , or out, the transparency(alpha) of a small stationery green ball in the external SWF.

The code to operate all of this will be written solely on the main time-line SWF. There will also be code on the main time-line which will target the green ball as a button to unload itself from the main time-line.

This might seem like a lot of different abilities to put into one example, but I believe that these all relate to desired 'real world' situations. If we can understand and work with these concepts, then we are well on the way to mastering the manipulation of 2 way communication between the main time-line SWF and the externally loaded SWF. Along the way we will discuss some key concepts which make all of this work.

LET'S SET UP THE EXTERNAL SWF FIRST:

external SWF layout

The background layer just has a blank box with a green border, just to give the area some definition. The next layer has 2 movieclip symbols. The red ball has the instance name of "ball" and the green ball has the instance name of "ball2". The green ball MC is just a 1 frame MovieClip Symbol. "ball", the red ball MC, has it's own timeline to give it the movement back and forth. It does not have any code, not even a stop action, so it will keep cycling back to the beginning , in a seamless manner.

"Ball" MovieClip Symbol's Timeline:

external SWF timeline

You can see that this is just a 40 frame animation. The red ball, inside its own timeline, was turned into ANOTHER symbol, so that we can animate/tween it. Frame one has it in the upper left corner. On frame 20 was placed a keyframe, and the red ball was moved to the lower right. It was given a motion tween between these 2 keyfames. These 20 frames were copied by right clicking and choosing 'copy frames'. Then frame 21 was right clicked and "paste frames" was choose. Frames 21-40 were choosen, then right clicked, and "reverse frames" was choosen.

MAIN SWF TIMELINE:

main SWF layout

The background layer contains the red box, as well as the text inside of it. The next layer contains 3 movieclip symbols to act as buttons. The first one has the instance name of "btn1" and will be the button that once clicked, will load in the external SWF. "btn2" will call a stop action to the red ball inside the external SWF. "btn3" will tell the red ball to resume play.

The next layer has 2 more movieclip symbols to use as buttons. These have the instance names of "tween_btn" which will use Tweener to slowly fade out the green ball ( instance name "ball2"). The other one has the instance name of "tweenIN_btn" which will cause the green ball to slowly fade back in.

The top layer holds the Actions, which make this all work. Here are the actions, which will be explained below:

ACTIONS

external SWF actions

Explanation of the ActionScript:

We first import the caurinaTweener class that I will use for the 2 buttons. I am doing this just to prove that you can use the Tweener transitions by calling them in the main timeline to effect something inside the externally loaded swf. Tweener can be downloaded for free at: http://code.google.com/p/tweener/downloads/list

If you don't want to use these transitions, you don't import the class.

On lines 3 we declare a variable which I named "myClip". This step isn't totally necessary but it makes life, and this process, so much easier. We are basically declaring that our entire main SWF ( i.e, the 'root') to be a MovieClip symbol. This makes referencing back to it eminently easier and pain free.

Line 4 and 5 declare 2 more variables. I create a MovieClip called "ExtSWFContainer" which ultimately will be the externally loaded SWF's container. Line 5 declares a loader I called "myLoader".

Now, here comes a simple, but very important concept. We must understand the nature of a Loaded object in Flash. Flash sees anything in the loader ( which can typically be an image ( .jpeg,.jpg, .png .gif, ) or a SWF(.swf)) as a display object.However, and this is the important part - the loader itself that the object ( be it an image or a swf) is loaded into is a display object, and not a MovieClip.

If your loaded SWF has animations, etc, as long as it is self contained ( not referenced from the outside, nor trying to effect anything on the outside), then all is well. But as soon as we want to try to communicate to or from the loaded SWF, then we run into trouble. By declaring the loader ,and its contents to be treated as a MovieCLip ( see line 9 of the Actionscript), then all will be well.

So, we created a Loader called "myLoader". We have this MovieClip still floating around called "ExtSwfContainer" that we haven't done anything with yet.

On line 8 , we ask our loader, to attach an eventListener to the 'contentLoaderInfo'. Really all we want from this is for the loader ( called "myLoader") to understand when the content has loaded, and then to perform a function we name "loaderCompletedhandler". The important part of this function ( line 9 ) is that it then tells the content of myLoader to be a MovieClip, the very same MovieClip variable that we declard in line 4 ( "ExtSwfContainer"). We also threw in a trace statement just to give us the feedback that it is working up until this point.

As part of the same function, we can now call items inside the loaded SWF. Line 10 tells ball2 inside the loaded SWF ( now called ExtSwfContainer, and therefore referenced as ExtSwfContainer.ball2) to add an eventListenr to listen for a CLICK, and to perform the function "extCommunicate". This "nested" function( a function within another function) is written in line 11 and 12. It first outputs another trace statement, then it tells ball2 inside the loaded swf to decrease its alpha. It also tells btn1 which is in the main time line - the button used to load the external swf, to decrease its alpha also. This is just one more 'proof' of an event begun in the loaded SWF effecting and calling back to the main SWF. If you notice, btn1 is actually referenced as " myClip.btn1". This is where declaring the root as a MovieClip ( line 4 ) comes into play, and just makes the reference to anything in the main time-line oh so easy.

The next command ( still line 12) tells the loader ( "myLoader") to unload the externally loaded MovieClip. I normally would not do it this way, but I was asked how this could be done , so there it is. I would normally want the 'unload' button on the main timeline, but I know that there are reasons and scenarios why people might want it otherwise. At any rate, it can be done.

Lines 15 & 16 set up the URL Request to prepare to load the clip we want.

Lines 18-22 set up btn1 to upon CLICK, to actually place the Loader into the Display List ( to make it appear) via addChild, and to actually now load the external SWF that we are asking for. By default it loads at the upper left hand corner of the main SWF ( position x=0, y=0). So if you want it placed elsewhere, tell it where to be positioned.

Lines 25-26 tell btn2 to stop the movement of the red ball inside the loaded SWF ( so we are therefore communicating TO the loaded SWF).
Lines 28-29 do the same thing for btn3 to start the red ball inside the loaded swf.

Lines 31-38 tell the other 2 buttons to use the imported Tweener Class to decrease/increase the alpha of the green ball inside the loaded SWF.

Lines 40-41 tell btn to appear like a regular button, and show the hand cursor. This is of course not neccessary, but part of giving your viewer visual feedback that yes indeed, this is a button.

Hope this all makes sense. It might seem complicated, but it really is not so bad. This is a subject and concept that many people get stuck on and very frustrated with. I have tried to present it in a way that you can grasp all the main concepts, and then use them for yourselves.

HERE's THE CODE:

import caurina.transitions.Tweener;

var myCLip:MovieClip = root as MovieClip;
var ExtSwfContainer:MovieClip;
var myLoader:Loader = new Loader();

myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderCompletedHandler);
function loaderCompletedHandler(evt:Event):void { ExtSwfContainer = myLoader.content as MovieClip; trace("hello");
ExtSwfContainer.ball2.addEventListener(MouseEvent.CLICK, extCommunicate);
function extCommunicate(evt:MouseEvent):void{
trace("LOOLOO"); ExtSwfContainer.ball2.alpha=.25; myCLip.btn1.alpha=.5; removeChild(myLoader);}

}
var externalSTRING:String = "externalClip4.swf";
var urlREQ:URLRequest = new URLRequest(externalSTRING);

btn1.addEventListener(MouseEvent.CLICK, swfLoads);
function swfLoads(evt:MouseEvent):void {
addChild(myLoader);
myLoader.load(urlREQ); myLoader.x=40; myLoader.y=20;
}

btn2.addEventListener(MouseEvent.CLICK, nowStop);
function nowStop(evt:MouseEvent):void {ExtSwfContainer.ball.stop(); }

btn3.addEventListener(MouseEvent.CLICK, nowPlay);
function nowPlay(evt:MouseEvent):void {ExtSwfContainer.ball.play(); }

tween_btn.addEventListener(MouseEvent.CLICK, tweenPlay);
function tweenPlay(evt:MouseEvent):void
{Tweener.addTween(ExtSwfContainer.ball2, {alpha:0, time:5, transition:"linear"}); }

tweenIN_btn.addEventListener(MouseEvent.CLICK, tweenPlayIn);
function tweenPlayIn(evt:MouseEvent):void
{Tweener.addTween(ExtSwfContainer.ball2, {alpha:1, time:5, transition:"linear"}); }

btn1.buttonMode=true;
btn1.useHandCursor=true;


If you have questions or comments, feel free to let me know.

You must have 'styles' or 'CSS' disabled. That's OK.

If so, and you see this, please DO NOT fill out the next 3 fields: name, email and zipcode. Thank you.

Name:

Email:

Just continue on to the rest of the form below this. Thank you.








Thanks for helping us control spam by filling in this question:
What is 10 + 3 = ? (Use numerals only)