Root Reference After Loading External swf - actionscript-3

I am loading a game swf into my swf. However the preloader of the game (which is from a library) has a problem with the root when it tries to reference it. I assume this is because the root is now my main swf rather than the preloader swf. Does anyone know of a way to load a swf and allow it to keep its own root? It is much easier for me to change my loading code than the game preloader code.
Thank you!

I think it's easier if you reference the explicitly reference the main.swf root with a name and not "root" and then use "this" for the preloader.
For example, say if you document class is called Main (like Main.as).
Then in your Preloader MovieClip code...if you are writing a class for the preloader, do something like:
public function Preloader() {
addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);
}
private function init(e:Event):void {
var main = (root as Main);
// do stuff with "main here"
main.addEventListner(...); // reference the main.swf
this.addEventListener(...); // reference the preloader
}

Sorry but this was a problem that I never really solved and had to do a workaround for by altering the code in the swf I was loading. I could find no other way to get it to reference the correct data.
Thank you all for you help though :)

Related

ActionScript Frame metadata not working

I know there exist a lot of posts about the Frame metadata tag in ActionScript,
but I still didn't find an answer to my question.
The problem is, I have specified a Frame metadata tag above my Main class header:
package gameUI {
...
[Frame(factoryClass="gameUI.MyPreloader")]
public class Main extends Sprite {
public function Main()
{
if (stage)
init();
else
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{ ...
I also have a preloader class in the same package (gameUI) called MyPreloader.as
package gameUI
{
// imports..
public class MyPreloader extends MovieClip
{
// private vars ..
public function MyPreloader()
{
trace('preloader START');
...
In my IDE, i don't get any errors or warnings. It compiles without problems.
But when I run it, it just skips over the Frame meta tag and just runs the code of the Main class. (The trace in the constructor of MyPreloader is never printed out).
I'm thinking maybe it has something to do with some arguments specified in the compiler settings. I've tried some couple of things, aditional compiler arguments but it never worked.
Does anyone know why he ignores the Frame metatag?
I'm really frustrated right now..
I'm using Flash Builder 4.6.
Compiling with Flex SDK 4.6.
thanks.
Your Main Class is a Sprite, so it can't have two frames. That may be part of your problem.
However, it might be that you can use a process that's easier to debug to accomplish the ultimate goal. For example, this is one approach. I personally usually just set my default export frame as 10, put a spinner on frame 1 and issue a play().
The only assets that need to be compiled on Frame 1 are in the spinner. It will then pause while the spinner spins and the assets load (because it has to load everything compiled there before it can proceed). Once all the assets have loaded, it will naturally advance to Frame 10. I will have an instance on the timeline at Frame 10 that has an associated getter and setter, so when the setter triggers, I know that loading is complete.
I only check "Export in Frame 10" for assets that absolutely have to be loaded at startup (for example, sounds or visual objects that are never used on the timeline).
The advantage of this approach is that you can get to the real content earlier (because only assets compiled on your default frame have to load before you can show anything), but the disadvantage is that it makes no sense to show % progress, since you have no idea what percent of the movie is compiled on frame 10 and needs to load before it will start.
So, in summary:
Try making the Base Class for your fla a MovieClip
If that doesn't work, consider changing approach

How to extend class that is inside a loaded swf

I've got an swf loaded externally to my app with loader component. It is loaded to the Application Domain of my loader. I've got a class in that swf wich I would like to extend and override some functions from it. Is it possible somehow?
Here is some code to explain what I want(of course, it is fully incorrect and wold not work):
public var ClassFromLoadedSwf:Class = ApplicationDomain.currentDomain.getDefinition("path.to.needed.class") as Class;
public class MyClass extends ClassFromLoadedSwf
{
override protected function initMovie() : void
{
//function logic goes here
}
}
Thank you for your answers and sorry for my bad english.
No you can't. Basically you don't understand the meaning of ApplicationDomain. Using a loader and Applicaiton Domain you just merge some code to your SWF in Runtime. Before it reaches the Runtime state, it can't be accessed. So at the Compile time you can't do what you're trying to do now. But you can try to use SWC instead of SWF. You just include it in your Project Library and that's all. You'll be able to access all the classes at compile time. Try reading this Article. It will help you understand the meaning of SWCs.

External Swf issues

I am working with external swfs. A main class loads in many external swfs immediately. They are shown later on after user input.
Just one of the external swfs is an issue. I wrote this, it is a different interaction then the rest and the audio played is separate from the main class unlike the other swfs.
So my question is, in the external swf code, is there an event listener I can use to know when this external swf is being displayed in The main class? I don't want to change the main class code since it is setup for a template that this one swf can't and won't match. Any suggestions would be great Thanks!
I guess it depends on what you are doing with this child swf, it is a pity that you are not in a position to change your main class, I mean this is in charge of the children right.
I think you could possibly do the following in your child swf:
this.addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler, false, 0, true);
function addedToStageHandler(event:Event):void
{
var child:Movieclip = MovieClip(event.currentTarget);
// do something with child
}

Loading SWF in AS3 but flash keeps repeating constructor function, what should I do?

I am importing several external files using the Loader-class, and one of them is an swf-file. When doing so (I had done it successfully before, so did not expect any issues), I ran into all sorts of errors, and finally Flash crashed.
I put down a trace in the constructor function, and it didn't trace just once, but kept on tracing, suggesting that the constructor was stuck on loop. I guess the loading of too many of the same swf is what causes flash to eventually crash.
Here is my code (the swf im loading is now a simple test-file which contains an image and no code):
private var slides:Loader = new Loader();
public function DocumentClass()
{
trace(1)
slides.load(new URLRequest("Resources/Slides.swf"));
slides.contentLoaderInfo.addEventListener(Event.COMPLETE, SlidesComplete);
}
public function SlidesComplete(evt:Event):void
{
slides.contentLoaderInfo.removeEventListener(Event.COMPLETE, SlidesComplete);
addChild(slides);
}
This traces "11111111111..." and everything dies in the end.
HELP!
Try putting a stop() action at the top of the swf you load in (either in actionscript, or on the timeline). It's possible that the swf is being loaded in and is running a play and running on loop in the mean time (hence your code running over and over).
I would do a progress watch until the swf is fully loaded, then jump to your display frame:
Create a section for loading (your choice if you want to use a preloader)
Create another section (set of keyframes) for loaded content. I use keyframes because it's easy, but you could also wait to instantiate classes until loading is complete.
Below is a snippet I occasional build from:
// stop the playhead from moving ahead
stop(); // you can also use gotoAndStop("loading"); if you want
function loaderProgressHandler(event:Event):void {
// switch the framehead to main which will show your content
if(event.bytesLoaded >= event.bytesTotal) {
event.target.removeEventListener(Event.PROGRESS, this.loaderProgressHandler);
this.gotoAndStop("main");
}
}
this.loaderInfo.addEventListener(Event.PROGRESS, this.loaderProgressHandler);
Hope that helps!
I was just stuck on this same problem.
In my case it turned out that the problem was down to the swf having the same document class name as the swf that was loading it.
eg. Main.as was loading another swf that also had its document class called Main.as - Changing this to anything else solved the infinite loop.

addEventListener in SWF Nesting

I currently have a .swf file that is nested into another .swf file.
In the parent SWF file I use a UILoader to load the other .swf file.
uiLoader.source = "data/child.swf";
-
In the child SWF file I have
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyPressedDown);
and when I run it on it's own, it works perfectly; but when I run child.swf through parent.swf stage.addEvent... give me a null reference exception.
Is the stage part of what is causing the issue?, and if so, is there a way to fix this?
Ok this is a good question, took me a little while to figure it out.
Basically Flash does this wierd thing (maybe a bug?) but runs the functions before actually initializing the objects. This happens with initializing movieclips with just on stage as well:
var mc:something = new something();
addChild(something)
now in something.as if you had a reference to a stage in the initialize function it would give null. (reference: http://www.emanueleferonato.com/2009/12/03/understand-added_to_stage-event/)
So basically taking that same problem and extending it to urlLoader it's running your code before actually building its hierarchy stage -> movie clips
now in order to solve this problem do something like this in your child swf:
import flash.events.KeyboardEvent;
import flash.events.Event;
import flash.display.MovieClip;
addEventListener(Event.ADDED_TO_STAGE, init);
function init(event:Event){
trace("test");
stage.addEventListener(KeyboardEvent.KEY_DOWN, moveBox);
var testMC:test = new test();
addChild(testMC);
}
function moveBox(event:KeyboardEvent){
trace("a");
testMC.x += 11;
}
The above is my code, you can scrap most of it, but the main thing to note is that:
addEventListener(Event.ADDED_TO_STAGE, init);
executes after your objects are initialized.
I'm not entirely sure, but it could be that because the MovieClip with the event listener is nested inside another MovieClip, it doesn't have access to the 'stage' Object.
One thing to try, would be to remove the eventListener from stage, so it simply looks like this:
addEventListener(KeyboardEvent.KEY_DOWN,keyPressedDown);
That might work. Alternatively, you could just keep the event code in the parent MovieClip. Hope these things might help.
Debu