A Flash Developer Resource Site

Results 1 to 6 of 6

Thread: Reference array in parent

  1. #1
    anyone else hear that? flashpipe1's Avatar
    Join Date
    Jan 2003
    Location
    Upstate NY
    Posts
    1,929

    Reference array in parent

    I've got a movie that calls a class which loads an array. I can reference that array from the movie using:

    Actionscript Code:
    trace("config "+this.course.ConfigTitles.toString());

    (ooooo...new as tag...)

    Now, I'm using the following code to load another movie:

    Actionscript Code:
    var request:URLRequest = new URLRequest("media/conf"+Number(Number(selectedConfig)+Number(1))+".swf");
    var loader:Loader = new Loader()
    loader.load(request);
    imagePH_mc.addChild(loader);

    and, in that movie, I play a movie and, when it's finished, I need to display the content from the array. I've tried:

    Code:
    trace("ComponentsTitle "+MovieClip(parent).course.ConfigTitles.toString());
    and I get the following error:
    Code:
    TypeError: Error #1034: Type Coercion failed: cannot convert flash.display::Loader@267da581 to flash.display.MovieClip.
    	at conf1_fla::MainTimeline/setBackImage()
    	at flash.events::EventDispatcher/dispatchEventFunction()
    	at flash.events::EventDispatcher/dispatchEvent()
    	at fl.video::FLVPlayback/http://www.adobe.com/2007/flash/flvplayback/internal::handleVideoEvent()
    	at flash.events::EventDispatcher/dispatchEventFunction()
    	at flash.events::EventDispatcher/dispatchEvent()
    	at fl.video::VideoPlayer/http://www.adobe.com/2007/flash/flvplayback/internal::httpDoStopAtEnd()
    	at fl.video::VideoPlayer/http://www.adobe.com/2007/flash/flvplayback/internal::httpNetStatus()
    If I remove the trace statement, it works fine with no errors. I've also tried it with 2 and 3 "parent" references with slightly different errors:

    Using 2 "parent" references:
    Code:
    TypeError: Error #1010: A term is undefined and has no properties.
    	at conf1_fla::MainTimeline/setBackImage()
    	at flash.events::EventDispatcher/dispatchEventFunction()
    	at flash.events::EventDispatcher/dispatchEvent()
    	at fl.video::FLVPlayback/http://www.adobe.com/2007/flash/flvplayback/internal::handleVideoEvent()
    	at flash.events::EventDispatcher/dispatchEventFunction()
    	at flash.events::EventDispatcher/dispatchEvent()
    	at fl.video::VideoPlayer/http://www.adobe.com/2007/flash/flvplayback/internal::httpDoStopAtEnd()
    	at fl.video::VideoPlayer/http://www.adobe.com/2007/flash/flvplayback/internal::httpNetStatus()

    Using 3 "parent" references:
    Code:
    ReferenceError: Error #1069: Property course not found on Configurator and there is no default value.
    	at conf1_fla::MainTimeline/setBackImage()
    	at flash.events::EventDispatcher/dispatchEventFunction()
    	at flash.events::EventDispatcher/dispatchEvent()
    	at fl.video::FLVPlayback/http://www.adobe.com/2007/flash/flvplayback/internal::handleVideoEvent()
    	at flash.events::EventDispatcher/dispatchEventFunction()
    	at flash.events::EventDispatcher/dispatchEvent()
    	at fl.video::VideoPlayer/http://www.adobe.com/2007/flash/flvplayback/internal::httpDoStopAtEnd()
    	at fl.video::VideoPlayer/http://www.adobe.com/2007/flash/flvplayback/internal::httpNetStatus()

    Any ideas??

    Thanks!!
    Love like you've never been hurt, live like there's no tomorrow and dance like nobody's watching.

  2. #2
    Total Universe Mod jAQUAN's Avatar
    Join Date
    Jul 2000
    Location
    Honolulu
    Posts
    2,429
    You need to use Events. A huge difference between as2 and as3 is the delegation of work vs. the ol' bucket brigade. Consider a job site where each worker merely hollers out "I'm done!" when a task is completed instead of having to pass the message through co-worker after co-worker until the foreman gets it. If the foreman decides he want's to hear that yell, he simply "listens" for it.

    It's a little difficult to show you a comparison without knowing your class names or hierarchy but I'll take a swing at it.

    I'm assuming you're working in the Flash IDE so we'll consider frame 1 as the pinnacle of your code. Lets say you have a class called Course.as and in frame 1 you create an instance of it like so:

    Actionscript Code:
    var course:Course = new Course();

    also in frame 1 you load myExternal.swf and add it as a child of imagePH_mc
    myExternal.swf has a movie clip inside of it called someMovie_mc which plays automatically

    Actionscript Code:
    var request:URLRequest = new URLRequest("myExternal.swf");
    var loader:Loader = new Loader()
    loader.load(request);
    imagePH_mc.addChild(loader);

    Now, what you're trying to do is have someMovie_mc tell myExternal.swf to tell the Loader that loaded it to tell your instance of course to do something. Seems a little overkill and rigid no?

    What if the last frame of someMovie_mc could simply yell out "I'm done!" and have our pinnacle hear it and respond by telling course to do something? That is what events are for.

    Now in a more advanced example I'd go into creating custom event classes but you just need a simple notification at this point instead of both a notification and some data to go with it. So we'll just use the built in Event class and it's COMPLETE constant. (COMPLETE is really just a class property with the value of "complete" permanently assigned.

    Every object in as3 has the ability to create a list of events it wants to hear. If a flash movie had say four events that got broadcast but a particular object only wanted to react to two of them, it would have two items on its listener list.

    So all we need to do is have our pinnacle add a single entry to its listener list that specifies which event it wants to hear, and what function to call when it does. We do this through addEventListener(event, function);

    Actionscript Code:
    //First we have to import the Event class
    import flash.events.Event;  //you only have to do this once
    //then we assign our listener
    this.addEventListener(Event.COMPLETE, onPlayBackComplete);
    //now create the onPlayBackComplete function which flash will call and pass it
    //an instance of Event that is created and dispatched by another object, in this case someMovie_mc
    function onPlayBackComplete(e:Event):void{
      trace("someMovie_mc has finished playing");
    }

    Now to make this work, an event actually has to be created and dispatched by someMovie_mc. Since every display object class in flash extends EventDispatcher, someMovie_mc already has the ability to do this.

    On the last frame of someMovie_mc write:

    Actionscript Code:
    dispatchEvent(new Event(Event.COMPLETE));

    Thats it.

    Now, why does this work? Without going into the details of event bubbling, any display object that dispatches an event object basically tosses it skyward passing through each of its parents until it hits our target object, in this case the pinnacle. The result is as if each of someMovie_mc's parents dispatched the event. This means that if another object in that hierarchy were to dispatch a COMPLETE event, our pinnacle would hear both of them and call onPlayBackComplete for each one. There's ways to handle any event scenario you run into but thems the basics.

    hth.

    Oh and you're welcome for the AS tag.

  3. #3
    anyone else hear that? flashpipe1's Avatar
    Join Date
    Jan 2003
    Location
    Upstate NY
    Posts
    1,929
    jAQUAN,

    Thanks for the explanation of dispatching events. I've done a bit of that, but your explanation clears up some of my questions.

    The big problem I'm having here is that I need to access the elements of an array (which is created in course.as when it parses an xml file) from the loaded clip.

    In the main timeline, if I call:
    trace("config "+this.course.ConfigTitles.toString());

    it returns the contents of the array.

    I've tried a variety of ways to access that array from the loaded movie and nothing seems to work. I know the array is already loaded before the child is added, but I can't seem to access it from the child...

    I've tried using many different variations of:
    trace("ComponentsTitle "+MovieClip(parent).course.ConfigTitles.toString() );

    THANKS!!!
    Love like you've never been hurt, live like there's no tomorrow and dance like nobody's watching.

  4. #4
    Total Universe Mod jAQUAN's Avatar
    Join Date
    Jul 2000
    Location
    Honolulu
    Posts
    2,429
    Again, events are going to save you need to manually climb up a display list.
    Altering what I described before, you can simply create a reference to the array directly on the loaded movie so that it need only look at itself when accessing the data.

    If the loaded .swf does not have a document class, put on frame 1:
    var courseArray:Array = [];
    If you are using a document class, create the variable as public there:
    public var courseArray:Array = [];

    Then the event you want to listen for is the completion of your loader at which point you can assign your array as the value of the courseArray variable.

    Keep in mind a Loader is just a display object with some built in loading skills. The Loader itself can't detect when something is done loading but its contentLoaderInfo property can so we assign a listener to it.

    Code:
          var request:URLRequest = new URLRequest("media/conf"+Number(Number(selectedConfig)+Number(1))+".swf");
          var loader:Loader = new Loader();
          loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onSWFComplete);
          loader.load(request);
          imagePH_mc.addChild(loader);
    and then create the onSWFComplete function

    Actionscript Code:
    function onSWFComplete(e:Event):void{
        //here you'll want to remove the listener just to be tidy
        loader.contentLoaderInfo.removeListener(Event.COMPLETE, onSWFComplete);
        // then simply assign the array to the variable you created.
        // Couple notes on that:
        // 1) A loaded .swf is essentially a movie clip which is a dynamic class which means you technically didn't have to create the courseArray variable ahead of time but it's just good form
        // 2) The Loader is NOT your loaded movie, its .content property is
        loader.content.courseArray = course.ConfigTitles;
    }

    Now, on the last frame of the loaded movie, simply reference courseArray.

  5. #5
    anyone else hear that? flashpipe1's Avatar
    Join Date
    Jan 2003
    Location
    Upstate NY
    Posts
    1,929
    Aha!! You are the MAN!!! I've got to get used to passing items back and forth between parents/children using events instead of just trying to scurry up and down the list.

    I'm slowly picking up on AS3/OOP conventions, but, coming from no programming background, through lingo/AS1/AS2, I'm playing catch up to teach myself the "right" way to build my code...and, of course, trying to fit all that into deadlines.

    Thanks again! Now the customer can see the descriptions they wrote.
    Love like you've never been hurt, live like there's no tomorrow and dance like nobody's watching.

  6. #6
    Total Universe Mod jAQUAN's Avatar
    Join Date
    Jul 2000
    Location
    Honolulu
    Posts
    2,429
    Glad it worked out. Decoupling is a bit of a strange concept at first, but eventually you'll wonder how you got by without it. Just think of how easy it would be to switch out loaded movies at different depths now.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center