PDA

View Full Version : AS3 - Loading swf once and use it twice?



tahadaf
September 8th, 2009, 09:46 AM
Hi,

There's something about loading external swf files into your project that I'm not sure if it's possible or not, so hopefully you can give me some advice?

This is what I know:
I know how to load an external swf file into my main flash file and I have also been able to build an interface class so that I can call public functions in the loaded swf from the main flash file... all works perfect.

This is what I don't know:
I wonder how I can use the very same loaded swf file twice in my file?! that is, I load it once and then somehow create two or more instances of the loaded swf file...! is it possible at all?

For your notice, this is how I have loaded the current swf file into my project:

This is the interface class


package
{
public interface IInput
{
function label(a:String):void;
}
}


This is how the codument class of the loaded SWF looks (this is just the important codes for your notice of course)


package
{
public class Main extends Sprite implements IInput
{
public function Main():void
{
}
public function label(a:String):void
{
// do something
// main document class will call this function
}
}
}



And below is how the document class of the main file looks like after completly loading the external swf file in itself...


private function onSwfDone(e:Event):void
{
mySwf = e.currentTarget.content as IInput;

// add the loaded swf class to your project
this.addChild(mySwf as Sprite);

// call a function on the loaded swf
mySwf.label("I am called from the main stage!");
}



As you see above, I am able to easilly work and call different public function in the above "mySwf" variable... but I do not know how to create another instance of the loaded swf file!

If anything you can think of, that would be great if you can share it.
Thanks,
Hadi

IQAndreas
September 8th, 2009, 10:40 AM
Try messing around with the "constructor" property.


private function onSwfDone(e:Event):void
{
mySwf = e.currentTarget.content as IInput;

//This creates more clones, and adds them dynamically:
var classDef:Class = mySwf.constructor;
var instance2:classDef = new classDef();
var instance3:classDef = new classDef();

// add the loaded swf class to your project
this.addChild(mySwf as Sprite);

this.addChild(instance2 as Sprite);
instance2.x = 200;

this.addChild(instance3 as Sprite);
instance3.x = 400;

// call a function on the loaded swf
mySwf.label("I am called from the main stage!");
instance2.label("I'm almost #1, but I'm better, because 1 is the lonliest number.");
instance3.label("I'm the best, because 2 can be as bad as 1 if...");
}

Note that I haven't used this method for testing on SWFs, only other classes, but since I believe that Flash treats a SWF as if it is a Class (or instance of one, at least), it should theoretically work.

Post whatever error messages you get if not.

tahadaf
September 8th, 2009, 11:47 AM
A very good idea and maybe we can think of a similar approach, but the above code you suggested has a quick problem when saying:

var classDef:Class = mySwf.constructor;

because the interface class has no constructor at all!
(The only reason I'm using the interface is because I'm trying to find a way to access and call functions on the loaded swf...)

anyway, the error message also talks about the same problem as above.

1119: Access of possibly undefined property constructor through a reference with static type IInput.

tahadaf
September 8th, 2009, 02:07 PM
Ok, I finally figured it out :) the best idea is to load the swf not with the Loader class but with the URLLoader and save the source bytes and reuse them again and again whenever needed...

if anyone wants to hear more, read here http://www.calypso88.com/?p=41&cpage=1#comment-33723

IQAndreas
September 8th, 2009, 02:44 PM
Ah. Try this:

var classDef:Class = (mySwf as Object).constructor;

Also, instead of declaring the items as type "classDef", delcare them as type "Object":

var instance2:Object = new classDef();
var instance3:Object = new classDef();

//...

if (instance2 is DisplayObject)
{
this.addChild(instance2 as DisplayObject);
instance2.x = 200;
}

if (instance3 is DisplayObject)
this.addChild(instance3 as DisplayObject);
instance3.x = 400;
}

It should work that way.