Access parent of Loader - how? - actionscript-3

This should be simple, but I can't figure it out. I have:
myMovieClip = new MovieClip();
myMovieClip.myLoader = new Loader();
This goes for a number of MovieClips. Later, I need to be able to refer back to the parent MovieClip from the Loader itself (because it happens in an event triggered by the Loader finishing loading). "evt.target.loader.parent" doesn't work. Any ideas?

with loaders you'll be able to define complete and error events.
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, LoaderComplete);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, LoaderError);
from those functions, if they are handled by the parent class you speak of you are already scoped to the parent object, so you can call all those methods in the callbacks you define.

Related

Access of Undefined Property "loader"

So I'm working on a project in flash, and recently decided that I wanted to switch my test file to become the main class inside my project. The file is called ColorClass.as, and the associated .fla file is ColorClass.fla. They are located in the same directory, and the Document class of ColorClass.fla is ColorClass. I am using a loader inside ColorClass.as to load an external SWF as follows:
public var loader:Loader = new Loader();
addChild(loader); //adding loader
loader.load(new URLRequest("../Resource/flash/WheelClasses.swf"));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,wheelsLoaded);
I am trying to create a test file, color_Test.as (and an associated color_Test.fla) that loads ColorClass.swf and gets the class definition to be used in the test file.
However, when I try and compile ColorClass.as/.fla and create a .swf file, I am receiving multiple instances of
Access of undefined property loader.
and
Call to a possibly undefined method addChild.
These errors are occurring completely independent of color_Test. Am I going about something the wrong way here? I'm just trying to compile ColorClass.as/.fla, which I could do so before trying to change it to become another class.
In an AS3 class, all functional code needs to be contained in a function.
So, aside from the first line (which is a variable declaration), the rest are just floating in the class not wrapped in a function:
public var loader:Loader = new Loader(); //THIS LINE IS FINE
//THESE THREE LINES NEED TO LIVE IN A FUNCTION
addChild(loader);
loader.load(new URLRequest("../Resource/flash/WheelClasses.swf"));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,wheelsLoaded);
If you want the code above to execute right away, place it in the constructor function (the function whose name matches the name of the class).
public function ColorClass {
addChild(loader); //adding loader
loader.load(new URLRequest("../Resource/flash/WheelClasses.swf"));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,wheelsLoaded);
}

AS3...instantiating movieclips from library and also creating them dynamically...is stop() needed?

In the past, we've put a stop() action in the timeline of movieclip symbols so that the timeline would not play and we would control all animations via code.
We've also done that to the main timeline as well.
Is this still needed for performance reasons? Is this needed for dynamically created movieclips?
I know that the Sprite class should be used if there is no timeline associated with it.
You don't need to do this. When you create your instance, if your movieClip has more than one frame simply call stop on that instance:
var ball:MovieClip = new Ball();
ball.stop();
addChild(ball);

Is there a way to use a sound channel on a movieclip?

The only way i can describe this is showing the code I have already then trying to explain what i want to do..
Basically, I am creating a soundboard game, where at the bottom of the screen I will have a bar which is a movieclip, and I will be dragging other movieclips onto it and then clicking pay, and using an array and .push they will play in order. I am trying to put the sounds onto the movieclips using code. So far, I have this:
var snd1:Sound = newSound();
snd.load(newURLRequest("naturefrog.wav"));
var channel:SoundChannel;
snd.addEventListener
I am now stuck with what I would put for the listener to listen for.
See this answer for knowing when sounds have finished loading, if the sound is external:
Loading a sound from an external source
Now once you're ready to play the sound and listen for when it completes, that's answered here:
demonstrates setting up listeners for sound_complete, as well as looping
You should use the Flash API for Sound to determine what listeners to add. There are some helpful examples at the bottom of the page.
I assume you'll want to add:
snd.addEventListener(Event.COMPLETE, completeHandler);
snd.addEventListener(Event.ID3, id3Handler);
snd.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
snd.addEventListener(ProgressEvent.PROGRESS, progressHandler);
You are pushing the sound reference of a movieclip into an array when user drag it into a particular movieclilp, right? If you do so you can shift an element from array(array.shift, usually this removes and returns the first element of the array).
function playSoundInArray(){
if(array.length){
var snd:Sound = array.shift() as Sound;
channel = snd.play();
channel.addEventListener(Event.SOUND_COMPLETE, onSoundPlayed);
}else{
//Do something here if there is no sound reference or the array is empty
}
}
function onSoundPlayed(e:EVent){
channel.removeEventListener(Event.SOUND_COMPLETE, onSoundPlayed);
playSoundInArray();
}

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

AS3: add event listener to loaded swf

I'm trying to listen for a custom event from an SWF I've loaded and I'm just not able to capture it. The loading code right now is just:
public function loadGame(gameSrc:String,gX:Number,gY:Number):void {
var loader = new Loader();
var addedDefinitions:LoaderContext = new LoaderContext();
addedDefinitions.applicationDomain = new ApplicationDomain();
loader.load(new URLRequest(gameSrc));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoaded);
function onLoaded(evt:Event):void {
var game:MovieClip = MovieClip(evt.target.content);
game.x = gX;
game.y = gY;
chamber.mc_gameHolder.addChild(game);
Tweener.addTween(chamber.mc_gameTitle,{alpha:1,time:.75});
game.addEventListener("showQuiz",showQuiz);
}
}
I know the event is being fired from my loaded SWF because I also have a listener in there that traces out a "hello" when it's fired.
Anyone? And apologies if this has been posted before - search didn't turn up anything specific.
I ran into the same problem. Here is what you need to do. When instantiating your LoaderContext, make sure the LoaderContext is using SecurityDomain.currentDomain. That will solve your problem.
This would work only if both SWFs are AVM2Movie (made using AS3), which I assume is the case here because otherwise casting to MovieClip would have thrown an error on run-time.
Are you sure that the event is dispatched by the document class of the loaded swf and not by one of its children? Because you are calling addEventListener on game which is the document class (root) of the loaded SWF and it won't catch events dispatched by its children. Can you show the code where you dispatch the event?
It may be possible that the event is being dispatched before the Event.COMPLETE event. Try adding a listener for the Event.INIT event. The Event.INIT event is dispatched when the Loader first has access to the loaded swf's document object.
hm, shouldn't it be :
addedDefintions.applicationDomain = ApplicationDomain.currentDomain to permit the loaded video to 'access' the parent one ?
Also for testing purposes I suggest to bubble the event up to make you haven't missed out a display object in between.
Things to consider:
The loaded clip should be from a security-enabled domain. If it's not the same domain the loading flash resides at, it should be included in the crossdomain.xml file. And loaded too.
Manually setting "allowDomain" via Security.allowDomain towards the loaded clip's domain is never bad.
The event should be bubbling, as Flash might add a layer or two of containers between the "game" var and the actual content.
Both loading and loaded clips MUST be AS3.
It is possible that the target clip is trying to load things from it's own proper location, so when you load it under a different URL, it can't find the files and fails, never reaching the event-firing phase in the first place.
Create a LoaderContext that sets the ApplicationDomain to the currentDomain, then pass it with your load() call:
loader = new Loader();
loader.contentLoaderInfo.addEventListener( Event.COMPLETE, handleLoaded );
var loaderContext:LoaderContext = new LoaderContext(false, new ApplicationDomain( ApplicationDomain.currentDomain ) );
loader.load( new URLRequest("yoMama.swf"), loaderContext );
You can confirm that you don't have a crossdomain issue by having the loading swf trace a var or function call from the loaded swf. If you get the expected result, crossdomain.xml is not your issue.
You have to consider some things in your situation.
(1) if you are loading code from the SAME domain, the app domain is not necessary.
(2) if you are loading code form DIFFERENT domains, check the [crossdomain.xml] policy file first... second... if you dont want to waste time fixing this... use PHP and curl the file to your domain... then load that (Flash will think its loading it from the same domain).