PDA

View Full Version : Loading external swf


SanderDeclerck
12-07-2007, 09:22 AM
I have the following AS3 code:
sSource = "external.swf";

var mLoader:Loader = new Loader();
var mRequest:URLRequest = new URLRequest(sSource);
mLoader.contentLoaderInfo.addEventListener(Event.C OMPLETE, onCompleteHandler);
mLoader.load(mRequest);

private function onCompleteHandler(loadEvent:Event):void{
contentSwf = loadEvent.currentTarget.content;
contentSwf.y = 30;
addChild(contentSwf);
//trace("toegevoegd");
}

so now that works, the swf loads correctly, but now i want to pass a String (the chosen language) to the loaded swf (external.swf)
does anyone know how i can do that?

Digital_Utopia
12-07-2007, 11:34 AM
first thing you need to do is make the variable that's holding the loaded swf (contentSwf) either accessible outside the function (for instance, declaring contentSwf outside of onCompleteHandler instead of inside it) or pass contentSwf to another function inside that function.

second, once that variable has content you access whatever clips are in that external swf by basically viewing that variable as "root"

for instance, if you had a text field in that swf, with the name "myText_txt" located on frame one of the main timeline, you would access it like:

contentSwf.myText_txt

likewise, you can call functions in that external swf like this:

contentSwf.myFunction();

where myFunction is on the main timeline in the loaded swf.

hope this helps

SanderDeclerck
12-07-2007, 11:51 AM
Well, now i did this:

sSource = "external.swf";

var mLoader:Loader = new Loader();
var mRequest:URLRequest = new URLRequest(sSource);
var contenSwf:DisplayObject;
mLoader.contentLoaderInfo.addEventListener(Event.C OMPLETE, onCompleteHandler);
mLoader.load(mRequest);

private function onCompleteHandler(loadEvent:Event):void{
contentSwf = loadEvent.currentTarget.content;
contentSwf.y = 30;
addChild(contentSwf);
contentSwf.traceTest("test");
//trace("toegevoegd");
}

then in the movieclip (external.swf) i placed the following code on an actions layer:

function traceTest(sString:String):void{
trace(sString);
}

and i get this error:
1061: Call to possibly undefined method traceTest through a reference with static type flash.dispaly:DisplayObject.

Digital_Utopia
12-07-2007, 12:17 PM
well I think the problem is that you misspelled the variable you declared. you declared contenSwf while you assigned the content of the loaded swf to contentSwf

SanderDeclerck
12-07-2007, 12:24 PM
no, that's not the problem, i have mistyped in this message, but in the actionscript file it's correct, but i'll show you the full files:

file1.as
it's the functions laadContent and onCompleteHandler that are used to load the external file
package{
import flash.display.Sprite;
import flash.display.Loader;
import flash.display.DisplayObject;
import flash.text.TextFormat;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.Font;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestHeader;
import flash.events.Event;
import flash.events.MouseEvent;
public class Navigatie extends Sprite{
private var tekstFormat:TextFormat;
private var navigatieItems:Array;
private var navigatieXMLLoader:URLLoader;
private var contentSwf:DisplayObject;

public function Navigatie():void{
spriteToevoegen();
initFonts();
itemsToevoegen();
laadContent("paginas/home.swf", false);
}

private function spriteToevoegen():void{
var sprite:Sprite = new Sprite();
sprite.graphics.beginFill(0xF6E497);
sprite.graphics.drawRect(0,0,800,30);
sprite.alpha = 0.4;
addChild(sprite);
}

private function initFonts():void{
var monotypeCorsiva:Font = new MonotypeCorsiva();
tekstFormat = new TextFormat();
tekstFormat.font = monotypeCorsiva.fontName;
tekstFormat.size = 25;
tekstFormat.color = 0x000000;
}

public function itemsToevoegen(){
loadXML();
}

private function loadXML():void{
navigatieXMLLoader = new URLLoader();
navigatieXMLLoader.addEventListener(Event.COMPLETE , navigatieXMLLoadHandler);
navigatieXMLLoader.load(new URLRequest("assets/xml/navigatie.xml"));
}

private function navigatieXMLLoadHandler(evt:Event){
var navigatieXML:XML = XML(navigatieXMLLoader.data);
navigatieItems = new Array();
for each(var navigatieItemXML:XML in navigatieXML..item){
navigatieItemXML.tekst
var item:NavigatieItem = new NavigatieItem;
item.sTekst = navigatieItemXML.tekst;
item.sSource = navigatieItemXML.source;
navigatieItems.push(item);
}
tekstInvullen();
}

private function tekstInvullen():void{
var i:Number = 130;
for each(var navigatieItem:NavigatieItem in navigatieItems){
var tekstSprite:Sprite = new Sprite();
tekstSprite.buttonMode = true;
tekstSprite.mouseChildren = false;
var tekst:TextField = new TextField();
tekst.embedFonts = true;
tekst.selectable = false;
tekst.text = navigatieItem.sTekst;
tekst.autoSize = TextFieldAutoSize.LEFT;
tekst.setTextFormat(tekstFormat);
tekstSprite.x = i;
tekstSprite.addChild(tekst);
addChild(tekstSprite);
tekstSprite.addEventListener(MouseEvent.CLICK, selectItem);
//trace("textWidth: " + tekst.textWidth);
i += 20;
i += tekst.textWidth;
}
}

private function selectItem(evt:MouseEvent):void{
//trace(evt.target.getChildAt(0).text);
var item:NavigatieItem = new NavigatieItem();
for each(var navigatieItem:NavigatieItem in navigatieItems){
if(navigatieItem.sTekst == evt.target.getChildAt(0).text){
item = navigatieItem;
}
}
laadContent(item.sSource, true);
}

private function laadContent(sSource:String, isLoaded:Boolean):void{
//trace(sSource);
if(isLoaded){
removeChild(contentSwf);
}
var mLoader:Loader = new Loader();
var mRequest:URLRequest = new URLRequest("paginas/home.swf");
mLoader.contentLoaderInfo.addEventListener(Event.C OMPLETE, onCompleteHandler);
mLoader.load(mRequest);
}

private function onCompleteHandler(loadEvent:Event):void{
contentSwf = loadEvent.currentTarget.content;
contentSwf.y = 30;
addChild(contentSwf);
contentSwf.traceTest();
//trace("toegevoegd");
}
}
}

content.swf uses the following AS file (Content.as):
package{
import flash.display.Sprite;
public class Home extends Sprite{
public function Home():void{
//trace("test");
}

public function testTrace():void{
trace("test");
}
}
}

Digital_Utopia
12-07-2007, 12:53 PM
hmm interesting...

there's only two possibilities that I can think of then.

either a)try listening for Event.INIT instead of Event.COMPLETE or b) try making contentSwf a MovieClip instead of a DisplayObject.

those are the only two differences that I can see between your test code, and the code I used for the music player I'm working on (loads at least 15 external .swf and png files on load)

so if neither of those two things fixes it...I'm not sure what exactly is going on.

SanderDeclerck
12-07-2007, 01:03 PM
i tried to make it a movieclip but then i get:
TypeError: Error #1034: Type Coercion failed: cannot convert Home@3579451 to flash.display.MovieClip. at Navigatie/::onCompleteHandler()

Digital_Utopia
12-07-2007, 01:22 PM
I dunno....this is my code for loading a swf...and it works fine. after the first song starts playing, a timer is started which calls vis.updateVis(); which draws a SoundMixer based audio visualization.

Unfortunately I don't really see anything different than what you're trying....do you?


var vis=new MovieClip();
var _loader

function partLoader(req) {
_loader = new Loader( );
_loader.contentLoaderInfo.addEventListener( Event.INIT, handleInit );
_loader.load( new URLRequest(req) );
}

function handleInit( event:Event ):void {
vis=_loader.content;
visCont_mc.addChild(vis)
vis.x=prefXML.vis.locX
vis.y=prefXML.vis.locY
}

SanderDeclerck
12-07-2007, 02:02 PM
i made a small testproject and in attachement i send all the .fla and .as files, i hope it helps to find my problem...

5566
12-07-2007, 02:02 PM
try Home(contentSwf).testTrace();

SanderDeclerck
12-07-2007, 02:09 PM
try Home(contentSwf).testTrace();
that works, but i want to load other swf's as well, i have an xml with the swf files i have to load...

5566
12-07-2007, 02:20 PM
u can try this hack
contentSwf["testTrace"]();

Digital_Utopia
12-07-2007, 02:42 PM
i made a small testproject and in attachement i send all the .fla and .as files, i hope it helps to find my problem...

okay...the tough part here for me is that I'm a little new to the seperate classes thing.

but, using what you've provided (after putting swf2.fla & the .as file in a subfolder (remember when you compile a clip, it loads all .as files in the same folder as your .fla) I've come across the realization that

1. you cannot directly call functions that are part of the loaded swf via include

2. if you add the loaded swf as a child of the swf that loads it...any functions with the same name as the class will run automatically (i.e. renaming traceTest to Swf2 will display "test" in the output panel of Swf1.swf

Edit: never mind...that's pretty cool. thx 5566, I'm sure that'll come in handy sometime lol

SanderDeclerck
12-07-2007, 03:05 PM
u can try this hack
contentSwf["testTrace"]();

tried it, but doesn't work:
ReferenceError: Error #1069: Property traceTest not found on Swf2 and there is no default value. at Swf1/::onInit()

Digital_Utopia
12-07-2007, 03:35 PM
tried it, but doesn't work:
ReferenceError: Error #1069: Property traceTest not found on Swf2 and there is no default value. at Swf1/::onInit()

did you try doing an addChild first on contentSwf?


private function onInit(e:Event):void{
contentSwf = e.currentTarget.content;
addChild(contentSwf);
contentSwf["traceTest"]();

}

SanderDeclerck
12-07-2007, 05:22 PM
thanks, after addChild it works :)
i also found another way to do it :)

loadEvent.currentTarget.content.testTrace();