Stop All Child MovieClips in Flash with Actionscript 3.0

While trying to come up with a way to get two different movies loaded at the same time, to play at different frame rates, I came up with a method to recursively stop all child movies of an as3 MovieClip. I didn’t end up using it, but I thought it might be useful for someone, so here it is:

import flash.display.DisplayObjectContainer;
import flash.display.MovieClip;

function stopAll(content:DisplayObjectContainer):void
{
    if (content is MovieClip)
        (content as MovieClip).stop();
   
    if (content.numChildren)
    {
        var child:DisplayObjectContainer;
        for (var i:int, n:int = content.numChildren; i < n; ++i)
        {
            if (content.getChildAt(i) is DisplayObjectContainer)
            {
                child = content.getChildAt(i) as DisplayObjectContainer;
               
                if (child.numChildren)
                    stopAll(child);
                else if (child is MovieClip)
                    (child as MovieClip).stop();
            }
        }
    }
}

The plan was to use that to stop playing movies, every other frame, and restart them on the alternative frames, but there is apparently no way to tell if a MovieClip is currently playing or not, to know which ones to restart.

I did end up hacking Tweener to add support for a Timer based update method. That way I can adjust the stage FPS to match the older timeline content (at 12fps) and have my Tweener based interactions work at a silky smooth 60 FPS.

I’ll post more on that later.

18 thoughts on “Stop All Child MovieClips in Flash with Actionscript 3.0”

  1. Actionscript 2.0 is a whole different thing. I found this in actionscript.org forums, it might work (untested):

    stopMovies(_root);
    function stopMovies(mov:MovieClip) {
      mov.stop();
      for (movs in mov) {
        if (typeof mov[movs] == "movieclip") {
          mov[movs].stop();
          stopMovies(mov[movs]);
        }
      }
    }
  2. Hi,
    Thank very much you for this script.
    I just have a question for my personal example:
    on the main timeline i have only one Frame that contains a Movie Clip named “mc_mc” with an loop animation in it. So i would like to stop it, when it loaded to a player with the stop function. How i can use your script in relation to this case? Thank you very much in advice for the answer.

  3. That depends on how the clip “mc_mc” is scripted. If it’s just a MovieClip (even with nested playing MovieClips), this script should work. Just call stopAll(root.mc_mc) (assuming it’s an AS3 timeline). If it’s just one playing MovieClip, with nothing nested, the normal stop() method should be sufficient. You may need to cast – this a is difficult concept for some users new to AS3 – (root.mc_mc as MovieClip).stop();

  4. hai,

    I need script for Timer and following buttons.

    1) Single button for timer ON/OFF/Display timer
    2) Reset

  5. Hi there..

    Heheh, I just wrote a recursive function to do the same thing. However, I just hit a roadblock when it came to restarting the clips.

    How do you know which ones to restart??!! Only method I could think of would be to wait for 1/stage.frameRate milliseconds and see if the currentFrame changes, but that would be pretty useless as depending upon the number of children to pause, the delay could be quite significant.

    Only other way would be to extend MovieClip and keep a Boolean state, but this is a lot of authoring work and defeats the purpose of writing this general functionality.

    Ideas anyone?? Did you have any breakthroughs?

  6. Well I think I have a solution for this problem.

    The first technique I described in my previous post seems to do the trick. What I do is upon PAUSE being required, I maintain a Dictionary of all the child objects and their current frame.

    Then set a Timer with a delay of 500/stage.frameRate. I agree that 500 is a bit abitrary, but its to make sure that the frame will have changed. Of course if you have a very slow running application where there its not running at your desired frame rate, then I guess this logic could be a problem. In my case its ok, as my screens are very basic and its known what hardware I will be running on. So this may not be the *perfect* solution, but its close enough for my needs.

    Then when the Timer ticks over, compare each key in the Dictionary and its value and see if the currentFrame of the key has changed, if not, remove it from the dictionary, if so, then stop the item and update the value of the key to its new frame.

    I then use the dictionary when it comes to unpausing and gotoAndPlay(value) of each key in the dictionary. Seems to work so far..

  7. Thanks for the script! funny thing though, I have 4 instances of the same movieclip, playing out of sync, in the main movieclip which I’m stopping with the script. Instance 1 stops fine. Instance 4 stops fine. Instances 2 and 3 stop, but are sent back in their timelines to the same frame as Instance 4 stopped at.

  8. Unfortunately, you can’t easily figure out if the MovieClip instance you are stopping is currently playing or not in Flash 10.3 and lower (actually, there is no general way to do it – you have to build a framework). They did add a “playing” property for Flash Player 11 content, so going forward, this will become possible.

  9. That makes sense, though I can imagine some edge cases where that might fail (what if the currentFrame ticks forward, but a frame based stop event is meant to stop the clip?).

    You could probably use a self removing ENTER_FRAME event listener instead of the timeout to make it work for a wider range of framerates.

    MovieClip.player and Flash Player 11+ seems like a good way to go. :-)

  10. That is pretty strange. I’d probably have to see the fla to determine why that happens – unless it’s Flash 9 publish target. Flash 9′s MovieClip functionality is way buggy. If you are targeting Flash 9, I’d suggest kicking it up to Flash 10. They fixed enough bugs to make it worth it.

  11. I got this error..

    TypeError: Error #1034: Type Coercion failed: cannot convert flash.events::MouseEvent@3c8ef299 to flash.display.DisplayObjectContainer.

    can anybody help me out …

  12. That looks like you are trying to pass a instance of MouseEvent to something that expects DisplayObjectContainer (like stopAll). You may have done this:

    someBtn.addEventListener(MouseEvent.CLICK, stopAll)

    When you need to do this:

    someBtn.addEventListener( MouseEvent.CLICK,
        function stopHandler( event:MouseEvent ):void {
            stopAll( yourMovie );
        }
    );

Leave a Reply

Your email address will not be published. Required fields are marked *

Connect with Facebook

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>