Reputation: 11
I am new to Flash
and I'm creating an educational application in AS3
in Flash CS4
for Adobe Air
. I want to use buttons to play and pause all content (movieclips
AND sound
).
I have created play
and pause
buttons that worked by switching the frame rate between 0
and 20
, unfortunately I've realized that it's never really 0 fps
, but rather 0.01 fps
, and so it continues playing, albeit very very slowly. Also this doesn't affect the audio; I have set sound files to Stream which are synced to movieclips
on their timelines, but even when the application is set to 0 fps
the audio continues.
Since I have various levels with numerous movieclips
each with synced audio, what i'd like is to be able to do is pause absolutely everything within each movieclip
with one button and to be able to resume from the same place using another button. Is this possible? If not, is there a global function to pause
/resume
the entire application
/program
?
Upvotes: 1
Views: 1136
Reputation: 189
My solution
private var pausedArr:Array = [];
// recursive function to store all MovieClip children and their currentFrame values
public function pause(mc:*, rootObj:Boolean = false):void
{
if (!mc is MovieClip) return;
if (rootObj) {
pausedArr = [];
mc.addEventListener(Event.ENTER_FRAME, stepOneFrame);
}
pausedArr.push( { mc:mc, frame:mc.currentFrame, paused: false } );
if (mc.numChildren > 0) {
for (var i:int = mc.numChildren - 1; i >= 0; i--) {
if (mc.getChildAt(i) is MovieClip) pause(mc.getChildAt(i));
}
}
}
// resume only paused MovieClips
public function resume():void
{
for (var i:int = 0; i < pausedArr.length; i++) {
if (pausedArr[i].mc && pausedArr[i].paused) pausedArr[i].mc.play();
}
pausedArr = [];
}
// see if MovieClips' frame changed, this is to avoid resuming stopped MovieClips before pause
private function stepOneFrame(e:Event):void
{
pausedArr[0].removeEventListener(Event.ENTER_FRAME, stepOneFrame);
for (var i:int = 0; i < pausedArr.length; i++) {
if (pausedArr[i].mc.currentFrame != pausedArr[i].frame) {
pausedArr[i].mc.stop();
pausedArr[i].paused = true;
}
}
}
Use com.reintroducing.sound.SoundManager
to play/pause sounds.
Use com.greensock.TweenMax
for timers and tweens, it can pause/resume both.
Upvotes: 0
Reputation: 3728
An alternative solution to adding listeners to all of your MovieClip instances is to employ recursion to pause and resume a MovieClip and all of its children (and children's children, and so on):
/**
* Recursively pause a display object and all contained display objects
* @param clip
* @param rewind whether to go to the first frame
*/
public function recursivePause(clip:DisplayObject, rewind:Boolean = false):void
{
if (clip is MovieClip)
{
if (rewind)
{
(clip as MovieClip).gotoAndStop(1);
}
else
{
(clip as MovieClip).stop();
}
}
if (clip is DisplayObjectContainer)
{
for (var i:uint = 0; i < (clip as DisplayObjectContainer).numChildren; i++)
{
recursivePause((clip as DisplayObjectContainer).getChildAt(i), rewind);
}
}
}
/**
* Recursively play a display object and all contained display objects
* @param clip
* @param rewind whether to go to the first frame
*/
public function recursivePlay(clip:DisplayObject, rewind:Boolean = false):void
{
if (clip is MovieClip)
{
if (rewind)
{
(clip as MovieClip).gotoAndPlay(1);
}
else
{
(clip as MovieClip).play();
}
}
if (clip is DisplayObjectContainer)
{
for (var i:uint = 0; i < (clip as DisplayObjectContainer).numChildren; i++)
{
recursivePlay((clip as DisplayObjectContainer).getChildAt(i), rewind);
}
}
}
Usage: recursivePause(stage)
or recursivePause(myMainMovieClip)
This is slightly more convenient than the event method, as it will work "out of the box" if/when you add a new MovieClip to the mix.
Upvotes: 2
Reputation: 810
Setting the framerate to 0 does not stop all movieclips. The only way to do this is to stop each individual movieclip and sound. One way to do it is with a custom event system:
First, dispatch a custom event when the stop/start button is clicked (dispatched from the stage, to make it easy accesible. (the sounds on the timeline of the stopped movieclips will be stopped aswell. If you play the sounds from script (SoundChannel), then you should stop them aswell.
btnStop.addEventListener(MouseEvent.CLICK, onClick_stop);
function onClick_stop(e:MouseEvent):void {
stage.dispatchEvent(new Event("STOP_EVERYTHING"));
}
btnStart.addEventListener(MouseEvent.CLICK, onClick_start);
function onClick_start(e:MouseEvent):void {
stage.dispatchEvent(new Event("START_EVERYTHING"));
}
then, on each movieclip you want to stop, listen to the events:
stage.addEventListener("START_EVERYTHING", onStart_everything);
function onStart_everything(e:Event):void {
//play this movieclip
play();
}
stage.addEventListener("STOP_EVERYTHING", onStop_everything);
function onStop_everything(e:Event):void {
//stop this movieclip
stop();
}
Upvotes: 0