addEventListener in SWF Nesting - actionscript-3

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

Related

Root Reference After Loading External swf

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 :)

In flash with as3.0, I have to call a function on the main stage from a movieClip

I have to call a function that is defined on the main stage of my project, and I have to call it from a MovieClip, what can I do?
I'm using flash cs5.5 and AS3.0
There are multiple ways to access the MainTimeline from objects on the stage. Probably the most reliable is 'root', but there is also 'parent' (but only if you MovieClip is a direct child of the main timeline).
// root should always work
Object(root).myFunc();
// parent will only work if your movieclip is a direct child of the main timeline
Object(parent).myFunc();
Note that you have to cast these are generic Objects (or MovieClip would work) because they return typed classes that don't have a 'myFunc' function in them.
You'll need this code on your main timeline:
function myFunc():void {
trace("My function got called!");
}
When I read your question it sounds as though you have a function defined in an action frame of your main timeline.
My answer may be out of reach for your current project, and ToddBFisher's answer is perfectly right. That said - I'm going to answer the question differently.
Instead of defining a function on the main timeline, set up a document class, define your functions there, and access the class's functions in your code. Keep as much code off your timelines as possible.
Downloadable files for Document Class example: http://www.isgoodstuff.com/2008/06/06/actionscript-30-documentclass-in-plain-english/
Setting up an AS3 class: http://www.adobe.com/devnet/flash/quickstart/creating_class_as3.html
Assuming your movie clip is a direct child of your main stage, in you movie clip you can do:
MovieClip(parent).theFunctionToCall();
if your MovieClip has a class, just add it to your main class using like:
var m:MovieClip = new MovieClip();
**addChild(m);
then you can get access into it's public function like typing:
m."functon name";

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.

Flash CS5 / AS3, after preloading main class constructor can't reference movieclips

I modified an Adobe Flash CS5 sample to create a swf with a preloader.
In my FLA I've two stopped frames:
In the first frame I only put this code (and a textfield showing percentage):
stop();
this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, onLoading);
this.loaderInfo.addEventListener(Event.COMPLETE, onComplete);
function onLoading(evt:ProgressEvent):void {
var loaded:Number = evt.bytesLoaded / evt.bytesTotal;
percent_txt.text = (loaded*100).toFixed(0) + "%";
};
function onComplete(event:Event):void {
this.loaderInfo.removeEventListener(ProgressEvent.PROGRESS, onLoading);
this.loaderInfo.removeEventListener(Event.COMPLETE, onComplete);
gotoAndStop(2);
};
In the second frame I:
exported the Main class;
I have all the needed graphics assets on stage;
When I test the Adobe sample (it has no main class on frame 2, only a large image) anything works fine, but when I compile the modified version I get strange errors.
In the Main class constructor I reference three movieclips, eg. this way: myClip.alpha=0, but it seems now Flash can't see them anymore (they are null). Why?
How can I make this preloader work?
Thanks in advance.
When you say Main class, are you referring to a class you have set as the Document Class? If I'm following you correctly, the problem is likely that the Document Class is always instantiated on the first frame, so your instances on stage wouldn't yet exist.
It's not possible to have the Document Class wait to instantiate until later frames. You'll probably have to remove your class from the Document Class assignment in order to create your instance on frame 2. At that point, you can pass a reference to your movieclips or stage through to the constructor of your class.

flash as3: can children not run their own actionscript?

I thought I was being slick by having movieclips that I export for actionscript and then addChild later. I've made this one movieclip that loads html text through as, and it works fine when I drag it to the stage; but if I do
var trackListingBox:trackListingScreen = new trackListingScreen();
addChild(trackListingBox);
it either doesn't run the actionscript, or it's somehow broken. Can children not run their own action script?
Maybe try adding some code to your MovieClip which will fire when the movie clip is added to the stage. Something like this:
this.addEventListener(Event.ADDED_TO_STAGE,onAddedToStage);
function onAddedToStage(e:Event):void {
functionWhichLoadsHTML();
}
They can "run their own actionscript" fine. There's probably a bug in your code in the child clip, but I can't give any advice on it without actually seeing the code.
the problem was that the actionscript was loading before the items it was referring to, thereby giving me errors that items were not found.