Nested MovieClip subclass gotcha in ActionScript 2

May 25th, 2007 § 5 comments

[UPDATE: It looks like Colin Moock‘s excellent book Essential ActionScript 2.0 talks about this very situation, on page 328. His workaround is to use setInterval to poll the object to see if the custom methods/properties have been set up yet.]

This kind of stuff is always a bit difficult to describe clearly, so I might not even try :P So here are some scratched-in notes for myself:

  • Imagine a MovieClip (mc1) which contains another MovieClip inside it (mc2). This nested instance is created in the authoring tool. It would look like this in the Movie Explorer:
    example
  • Both MovieClips have (different) custom class: let’s call them MovieClass1 and MovieClass2.

The constructor for MovieClass1 looks like this:

class MovieClass1 extends MovieClip {
    function MovieClass1()
    {
        trace("MovieClass1 ctor " + this);
    }
}

MovieClass2‘s constructor looks shockingly similar:

class MovieClass2 extends MovieClip {
    function MovieClass2()
    {
        trace("MovieClass2 ctor " + this);
    }
}

Ok. Now we place an instance of MovieClass1 on the stage, name it mc1, and test the movie. Here is the traced output:

MovieClass1 ctor _level0.mc1
MovieClass2 ctor _level0.mc1.mc2

So we know that the constructor for the parent clip is called before the constructor of the child clip.

Note that this is quite unlike C++, for example, where member objects are created before the containing object’s constructor is called (see here for an example), and in fact can cause real issues. For example, suppose MovieClass1‘s constructor wants to call custom methods of MovieClass2. Those calls will fail because mc2 has not yet been initialized! Note that this only applies to methods and properties that exist in the custom class — the MovieClip exists, as a plain old MovieClip, but the custom class hasn’t been associated with it yet.

Example:
MovieClass1.as:

class MovieClass1 extends MovieClip {
    var mc2:MovieClip; /* placed in Flash authoring tool */
    function MovieClass1()
    {
        trace("MovieClass1 ctor " + this);
        mc2.customMethod();
    }
}

MovieClass2.as:

class MovieClass2 extends MovieClip {
    function MovieClass2()
    {
        trace("MovieClass2 ctor " + this);
    }
 
    function customMethod()
    {
        trace("MovieClass2 customMethod()");
    }
}

The results of running this test:

MovieClass1 ctor _level0.mc1
MovieClass2 ctor _level0.mc1.mc2

Yep. customMethod() is never called!

I hope to continue this in a later post… there are more details about the constructor-calling process that are weird and intriguing!

§ 5 Responses to Nested MovieClip subclass gotcha in ActionScript 2"

  • Tim says:

    Argh!!

    Thanks for perfectly outlining the problem i’ve been having.

    So what’s the solution?

  • bunnyhero says:

    I ended up changing my code so that I didn’t need to call methods on the child clip. That probably doesn’t help you much :( Colin Moock uses setInterval() to continually check the child clip until the method appears, but I find that inelegant.

  • Tom says:

    Two more possible solutions:

    – Have the child MC “report” to its parent in its constructor that it’s ready. This assumes that the parent will have a pre-determined function name (something like childReady()).

    – Use attachMovie() to create the child MC dynamically; in this situation, the child class seems to be ready right away.

    I really have to get on the AS3 boat, because I cry a little inside every time I have to make my classes interdependent to avoid a Flash quirk.

  • Using “childObject.onLoad” in the parent constructor seems to work well for me on this. I then make a function that deals with all the things I want to tell the child to do. The only issue I have had with this is that the child renders one frame as a movie clip before all its methods are called, so I often need to turn off then on the alpha.

  • Bart says:

    Hi, You can indeed use attachMovie or you can wait for the movieClip.onLoad.

    mc2.onLoad = Delegate.create(this, onInitClass);

    Now you can call your methods of MovieClass2.

    When you call mc1.mc2.customMethod() directly from the stage you don’t have to wait for the onload.

What's this?

You are currently reading Nested MovieClip subclass gotcha in ActionScript 2 at bunnyhero dev.

meta