PDA

View Full Version : how to access main timeline from external swf



sger_error
July 16th, 2007, 03:58 AM
hello,

my main application is a sprite heres my code:
package {
import flash.display.Sprite;
import flash.display.Loader;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.URLRequest;

public class ROOT extends Sprite
{
public function ROOT()
{
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.CO MPLETE, onComplete);
loader.load(new URLRequest("file.swf"));
addChild(loader);
}

public function traceMe():void{
trace("traceMe();");
}

private function onComplete(event:Event):void{

}
}
}


from my external swf (file.swf) contains a shape code:

package {
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.display.MovieClip;

public class file extends Sprite
{
public function file()
{
var shape:Sprite = new Sprite()
shape.graphics.beginFill(0xff0000);
shape.graphics.drawRect(0, 0, 100, 100);
shape.graphics.endFill();
addChild(shape);
shape.addEventListener(MouseEvent.CLICK, onClick);
}

private function onClick(event:MouseEvent):void{
MovieClip(this.parent.parent).traceMe();
}
}
}


when my main app is a MovieClip (extends MovieClip) is working.

but my main app is a sprite i take this message

cannot convert ROOT@16b26df1 to flash.display.MovieClip.

can i change this line

MovieClip(this.parent.parent).traceMe();

to something like this Sprite(this.parent.parent).traceMe();

CarlLooper
July 16th, 2007, 04:13 AM
public class ROOT extends Sprite
{
var clip:MovieClip;
public function ROOT()
{
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.CO MPLETE, onComplete);
loader.load(new URLRequest("file.swf"));
// addChild(loader); <-- remove
}

public function traceMe():void{
trace("traceMe();");
}

private function onComplete(event:Event):void{
clip = MovieClip(loader.content);
addChild(clip);
}
}
}

sger_error
July 16th, 2007, 04:24 AM
ok but now i get this cannot convert file@16b25e49 to flash.display.MovieClip.

file.swf is my external swf

CarlLooper
July 16th, 2007, 04:29 AM
public class ROOT extends Sprite
{
var sprite:Sprite;
public function ROOT()
{
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.CO MPLETE, onComplete);
loader.load(new URLRequest("file.swf"));
// addChild(loader); <-- remove
}

public function traceMe():void{
trace("traceMe();");
}

private function onComplete(event:Event):void{
sprite = Sprite(loader.content);
addChild(sprite);
}
}
}

---
loader.content returns a DisplayObject - which you must cast (coerce) to the correct type of object you have otherwise passed - but it seems the loader prefers MovieClips rather than Sprites - as the above didn't work for me.

sger_error
July 16th, 2007, 04:35 AM
already try this and ...

cannot convert flash.display::Stage@16b251e9 to flash.display.MovieClip.

click event code at external swf

private function onClick(event:MouseEvent):void{
MovieClip(this.parent.parent).traceMe();
}

CarlLooper
July 16th, 2007, 04:50 AM
The following code is now correct - but had to make file.swf a MovieClip - which sort of defeats what you were after - eh?

Both were compiled using SDK compiler and works.



package {
import flash.display.Sprite;
import flash.display.Loader;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.URLRequest;
import flash.display.MovieClip;

public class ROOT extends Sprite
{
var clip:MovieClip;
var loader:Loader;

public function ROOT()
{
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.CO MPLETE, onComplete);
loader.load(new URLRequest("file.swf"));

}

public function traceMe():void{
trace("traceMe();");
}

private function onComplete(event:Event):void{
clip = MovieClip(loader.content);
addChild(clip);
clip.setParent(this);
}
}
}

package {
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.display.MovieClip;
import ROOT;

public class file extends MovieClip
{
private var _parent:ROOT;

public function file()
{
var shape:Sprite = new Sprite()
shape.graphics.beginFill(0xff0000);
shape.graphics.drawRect(0, 0, 100, 100);
shape.graphics.endFill();
addChild(shape);
shape.addEventListener(MouseEvent.CLICK, onClick);
}

public function setParent(_parent:ROOT):void
{
this._parent = _parent;
}

private function onClick(event:MouseEvent):void{
_parent.traceMe();
}
}
}

sger_error
July 16th, 2007, 05:03 AM
first thanks for your help

heres your code in flex builder

main class:

package {
import flash.display.Sprite;
import flash.display.Loader;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.URLRequest;
import flash.system.LoaderContext;

public class ROOT extends Sprite
{
public var sprite:Sprite;
public var loader:Loader;

public function ROOT()
{
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.CO MPLETE, onComplete);
loader.load(new URLRequest("file.swf"));

}

public function traceMe():void{
trace("traceMe();");
}

private function onComplete(event:Event):void{
sprite = Sprite(loader.content);
addChild(sprite);
sprite.setParent(this);
}
}
}


file.swf

package {
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.display.MovieClip;
import flash.display.DisplayObjectContainer;

public class file extends Sprite
{
private var _parent:DisplayObjectContainer;

public function file()
{
var shape:Sprite = new Sprite()
shape.graphics.beginFill(0xff0000);
shape.graphics.drawRect(0, 0, 100, 100);
shape.graphics.endFill();
addChild(shape);
shape.addEventListener(MouseEvent.CLICK, onClick);
}

public function setParent(parent:DisplayObjectContainer)
{
this._parent = parent;
}

private function onClick(event:MouseEvent):void{
_parent.traceMe();
}
}
}

in both cases i see undefined methods setParent and traceMe which is ok

any ideas thanks again dude!!!!!!

CarlLooper
July 16th, 2007, 05:12 AM
Have corrected code - see prior post

To avoid the smileys in your posts, and to maintain indents, place your code between tags which I have to articulate:

openbracket code closebracket code-goes-here openbracket forwardslash code closebracket

sger_error
July 16th, 2007, 05:19 AM
well your code not working in my flex builder

CarlLooper
July 16th, 2007, 05:41 AM
Files attached.

Also tested in Flash CS3 so I could see the trace - worked fine.

During SDK compilation I did get warnings but ignored them:




Warning: var 'clip' will be scoped to the default namespace: ROOT: internal.
It will not be visible outside of this package.

var clip:MovieClip;
^

Warning: var 'loader' will be scoped to the default namespace: ROOT: internal.
It will not be visible outside of this package.

var loader:Loader;
^

C:\Tests\LoadedSWF\file.swf (1116 bytes)

Press any key to continue...
Warnings easily fixed with scope qualifiers:

private var clip:MovieClip;
private var loader:Loader;

.

sger_error
July 16th, 2007, 05:53 AM
missing type declaration

ok its working but any extra idea without importing the main class ROOT into file.swf?

thanks again dude!!!!

CarlLooper
July 16th, 2007, 06:06 AM
missing type declaration

ok its working but any extra idea without importing the main class ROOT into file.swf?

thanks again dude!!!!

YES INDEED

But first of all:

The import of ROOT won't add any additional bytes to your swf as no ROOT object is actually created in file.swf

All that's created is a reference to a ROOT object - not the object itself.

The import is required so the compiler knows how to compile the reference, otherwise it doesn't know where to find the "traceMe" method of your actual ROOT object - so it complains (eg. if you tried casting it as a Sprite).

But yes - you don't need to import ROOT if you do this:

NOT IMPORTING ROOT

// this works:

private var _parent:Object; //<-- note Object type rather than ROOT type
...
private function onClick(event:MouseEvent):void{
_parent.traceMe();
}

Because the _parent reference is typed here as an Object reference (rather than a ROOT reference) _parent is now a dynamic reference. Such a reference is also known as a polymorphic reference - which basically means that the reference doesn't have to know what type of object it will be referencing. It will be told this later (when the program is actually running).

One can think of the _parent reference as being left "uncompiled" (so to speak).

At runtime the reference will be told what sort of object it is otherwise referencing and will then know where to find the traceMe method of such objects.

It is a little less efficient as runtime binding is performed instead of compile-time binding. But it is nevertheless very useful.

Anyway here is the polymorphic version (fully tested and working)



package {
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.display.MovieClip;

public class file extends MovieClip
{
private var _parent:Object;

public function file()
{
var shape:Sprite = new Sprite()
shape.graphics.beginFill(0xff0000);
shape.graphics.drawRect(0, 0, 100, 100);
shape.graphics.endFill();
addChild(shape);
shape.addEventListener(MouseEvent.CLICK, onClick);
}

public function setParent(_parent:Object):void
{
this._parent = _parent;
}

private function onClick(event:MouseEvent):void{
_parent.traceMe();
}
}
}

Runtime binding is, of course, useful when your swf is being distributed to an unknown parent. The parent will still need to know how to interface with your swf, which in our test case, the parent is doing by calling the setParent() method of the loaded swf.

SlowRoasted
October 13th, 2007, 01:10 PM
Carl, thx for the great info. This was really helpful and saved me a lot of time:P

Hacker
January 28th, 2009, 08:57 PM
Hi!
I have a simillar problem!

I had this aplication all programmed and working for about 3 or 4 months.
BUT!
It was in AS 2 and I really needed to use XML....
And I had...
But the syntax was a ******* (sorry)
you would remember..


var getSomething = this.childNodes[2].childNodes[_global.counter].firstChild.nodeValue;
a

nd now the syntax is very improved (in my opinion one of the good things in AS3)



var getSomething = getFromXML.item[2].name[MovieClip(parent).counter].persons_name.text();
My problem is this:

I need to load a SWF into a specific container called "container"
and it is DONE!



var PrivateTemplateTwO ="swf/"+systemFile.playlist[playlist].template_name.text();
var mLoader2:Loader = new Loader();
var mRequest2:URLRequest = new URLRequest(PrivateTemplateTwO);
mLoader2.contentLoaderInfo.addEventListener(Event. COMPLETE, onCompleteHandler2);
mLoader2.load(mRequest2);
function onCompleteHandler2(loadEvent2:Event):void
{
container.addChild(loadEvent2.currentTarget.conten t);
trace("container carregado");
removeEventListener(Event.COMPLETE, onCompleteHandler2);
}/
/End Function
removeEventListener(Event.ENTER_FRAME, CarreGaConteNt); //Limpa o onEnterFrame

and in the loaded MC I have a timeline width 20 seconds (+/-) and in the end I have the folowing action:



_root.play();
unloadMovie(this);

how do I do this last part in AS3?
WITHOUT PACKAGES!!! I DONT USE THAT!!
(ONLY COMPLICATES)