Skip to main content
stratumvstein
Participant
April 5, 2015
Question

AS3 Playback control of nested movieclips

  • April 5, 2015
  • 1 reply
  • 467 views

Hey all,

I'm trying to figure out how to control a movieclip symbol from the timeline.

I've created a Main Timeline with one symbol per frame, a labels layer and an action layer.

Each frame has its own label, and each action keyframe has a listener attached to the current symbol like so:

symb = title_mc;

symb.cacheAsBitmap = true;

symb.mask = f_mask;

symb.focusRect = false;

stage.focus = symb;

symb.addEventListener(KeyboardEvent.KEY_DOWN, mc_pager);

I need the following structure:

  1. From Main timeline Frame
  2. Identify symbol instance (labeled as <name>_mc)
  3. Inside symbol timeline, play from first frame (labeled '0') until next labeled frame ('1' and so on)
  4. stop and wait for next pg_down to start playing from next labeled frame to the following (i.e. '1'-'2'), or pg_up to start playing from the previous labeled frame (i.e. '0' - '1')
  5. on last frame (labeled 'final') exit symbol focus and return keyboard control to main timeline to allow pg_down and pg_up to move to the next / previous frame. on pg_up on symbol.currentFrame == 0, do same.

This is the code I'm currently stuck with:

import flash.events.Event;

import flash.display.MovieClip;

import flash.events.KeyboardEvent;

stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;

stop();

f_mask.cacheAsBitmap = true;

var symb:MovieClip;

symb = MovieClip(root); //assign symbol I want to be controlled by pg_up/pg_down

symb.focusRect = false;

symb.addEventListener(KeyboardEvent.KEY_DOWN, mc_pager);  //add keyboard event listener

stage.focus = symb; //focus on current symbol

function mc_pager(e:KeyboardEvent):void{

    var myKey = e.keyCode;

    if (myKey == Keyboard.PAGE_DOWN){

        do{

            symb.play(); // it plays, then checks if the lbl is null or final, then quits

            trace("current: " + symb.currentFrameLabel);

        } while (symb.currentFrameLabel == null && symb.currentFrameLabel != 'final');

        symb.stop();

        symb.removeEventListener(KeyboardEvent.KEY_DOWN, mc_pager);

        stage.focus=MovieClip(root); //return focus to main timeline (in the next keyframes, the focus is on the nested _mc

    }

    if (myKey == Keyboard.PAGE_UP){

        do{

            symb.prevFrame();

        } while (symb.currentFrameLabel == null && symb.currentFrameLabel != '0');

        symb.stop();

        symb.removeEventListener(KeyboardEvent.KEY_DOWN, mc_pager);

        stage.focus=MovieClip(root);

    }

}

So far, I've tried several different things (including multiple eventhandlers) to no avail. This is what looks best so far, being logically sound (I think). But it doesn't work. Please, I need a hand with this.

This topic has been closed for replies.

1 reply

kglad
Community Expert
Community Expert
April 5, 2015

you can't use a while (or for or do) loop to check frame changes or anything changing on stage.

those loops execute from beginning to end before a frame changes and before anything changes on-stage.

use enterframe or timer events.

stratumvstein
Participant
April 5, 2015

Ok, I hear you. The thing is, I am already attaching an eventListener to capture the Keystroke. Apparently (and I might very well be mistaken), attaching multiple listeners does only cause one of them to be ignored. Originally, I had tried with ENTER_FRAME, but that impeded the keystroke capture (and hence, I couldn't control the playback inside the movieclip). Any chance you might give me an example of how you would make it work? Thanks a lot!

(BTW, you might have noticed I'm way over my head here, so thanks a lot for your patience)

EDIT: I did have a version with timer events, but it would force me to adjust to the timers pacing, and since this is for a live presentation, it's not an option.

EDIT2: From what I've seen ENTER_FRAME does dispatch that event constantly (at the rate of the set framerate). But what I'm trying to achieve is to go once into the symbol, control it with pg_up / pg_dwn (it has to be as those are the keys that are mapped to the Logitech remote presenter I have), and run the animation until it finds a labeled frame (back or forth), and only exit the symbol once it's reached the end (or the beginning if I'm paging back). Does that make sense?

kglad
Community Expert
Community Expert
April 5, 2015

use:

function mc_pager(e:KeyboardEvent):void{

    var myKey = e.keyCode;

    if (myKey == Keyboard.PAGE_DOWN){

symb.removeEventListener(KeyboardEvent.KEY_DOWN, mc_pager);

            symb.play(); // it plays, then checks if the lbl is null or final, then quits

            trace("current: " + symb.currentFrameLabel);

             symb.addEventListener(Event.ENTER_FRAME,checkNextFrameF);

        }

     

    }

    if (myKey == Keyboard.PAGE_UP){

       symb.addEventListener(Event.ENTER_FRAME,checkPrevFrameF);

}

function checkNextFrameF(e:Event):void{

if(i don't know what you want to check here || symb.currentFrame==symb.totalFrames);

        symb.stop();

symb.removeEventListener(Event.ENTER_FRAME,checkNextFrameF);

symb.addEventListener(KeyboardEvent.KEY_DOWN, mc_pager);

whatever else

}

}

function checkPrevFrameF(e:Event):void{

symb.prevFrame();

if(i don't konw what you want to check here || symb.currentFrame==1){

symb.removeEventListener(Event.ENTER_FRAME,checkPrevFrameF);

symb.addEventListener(KeyboardEvent.KEY_DOWN, mc_pager);

//whatever else

}

}