Skip navigation
Cyber.Knight
Currently Being Moderated

AS3 gotoAndPlay Frame in a prevFrame

Aug 5, 2013 10:20 AM

I think this should be a easy fix. I am self taught using Flash and putting together a photo gallery. I have a 2 swf files that when you enter play from frames 1 through 15. I have a back button that I am trying to play frames 16 to 30. I am trying to use as little code as possible and the swf files are nested in a Movieclip. I am trying to target frame 16 in each of the swf movieclip when they hit the back button.

 

This is the code I have that works.

 

left_btn.addEventListener(MouseEvent.CLICK, backward);

function backward(e:Event):void {

   photos_mc.prevFrame();

}

 

 

What I like it to do is

 

left_btn.addEventListener(MouseEvent.CLICK, backward);

function backward(e:Event):void {

   photos_mc.prevFrame(16);

}

 
Replies
  • Currently Being Moderated
    Aug 5, 2013 10:55 AM   in reply to Cyber.Knight

    If you'd like to go to frame 16 and stop:

     

    photos_mc.gotoAndStop(16);

     

    If you'd like to go to frame 16 and play:

     

    photos_mc.gotoAndPlay(16);

     

    You can add math in there and do things like go back 15 frames from where you currently are, or advance 15 frames, etc. You just use the .currentFrame property of the MovieClip. You can also put in some logic to make sure it's possible:

     

    Examples:

     

     

    // advance 15 frames from where I am and play, if I can

    if ( (photos_mc.currentFrame + 15) < photos_mc.totalFrames)

    {

         photos_mc.gotoAndPlay(photos_mc.currentFrame + 15);

    }

     

     

    // go back 15 frames and stop

    if ( (photos_mc.currentFrame - 15) > 0)

    {

         photos_mc.gotoAndStop(photos_mc.currentFrame - 15);

    }

     

     

    You can decide what to do based on where it currently is as well using the same properties of the MovieClip.

     

    For example, to play if you're on frame 1 but to return back to frame 1 if you're past that frame:

     

    // are we on frame 1?

    if (photos_mc.currentFrame == 1)

    {

        // on frame 1, play

         photos_mc.play();

    }

    else

    {

        // we're past frame 1, return to frame 1

         photos_mc.gotoAndStop(1);

    }

     
    |
    Mark as:
  • Currently Being Moderated
    Aug 6, 2013 8:28 AM   in reply to Cyber.Knight

    The scope of where the function runs from is what matters. As you've identified, my code is affecting the scope of "photos_mc" and you want it to affect a different scope (level) inside (imagexx_mc).

     

    If your function is on the main timeline then you'd just have to append imagexx_mc to make that work.

     

    e.g.:

     

    function backward(e:MouseEvent):void

    {

         // from main timeline, go in photos_mc and affect image01_mc

         photos_mc.image01_mc.gotoAndPlay(16);

    }

     

    If the function exists inside a timeline script inside photos_mc then you just won't need to preface photos_mc, because the script is already inside it. So:

     

    e.g.:

     

    function backward(e:MouseEvent):void

    {

         image01_mc.gotoAndPlay(16);

    }

     

    Timeline scripts can just daisy.chain.instance.names with a period. Every time you put a period in there you're saying the item after the period is inside the item before the period. So when I say photos_mc.image01_mc I'm saying 'image01_mc' is inside 'photos_mc'.

     

    Things get a bit more complex if the button you click exists inside image01_mc or image02_mc.

     
    |
    Mark as:
  • Currently Being Moderated
    Aug 6, 2013 2:26 PM   in reply to Cyber.Knight

    I'm pretty sure I understand what you mean. You want to jog around certain clips with the same 2 buttons based on some logic.

     

    Maybe an example that's similar to what you have will be easier. Here's a saved-down CS5 FLA that lightly mimics what you have. There's a clip (photos_mc) and inside it there's 2 frames. On frame 1 is image01_mc which has 30 frames in it, with a stop() at frame 15 and 30. On frame 2 is basically the same thing, image02_mc with 30 frames, stop()s at frames 15 and 30.

     

    Example Source

     

    Watch your trace panel. It will tell you where the playhead lands.

     

    The buttons just check the current frame certain clips are on to determine what to do. Code is commented.

     

    Season to taste but you should have the building blocks to do what you want with the combinations of play(), gotoAndPlay(#) and gotoAndStop(#), based upon checking where other clips currently are.

     
    |
    Mark as:
  • Currently Being Moderated
    Aug 7, 2013 8:42 AM   in reply to Cyber.Knight

    I've re-saved the above source code link down to Flash CS4. Give it a try.

     
    |
    Mark as:
  • Currently Being Moderated
    Aug 9, 2013 7:35 AM   in reply to Cyber.Knight

    Had the day off yesterday.. The examples were just to show you how to jump around. If you want to start from frame 16 when you switch back to frame 1 then simply tell it to do that right after you tell it to switch frames.

     

    e.g.:

     

    // image02_mc is less than frame 30, set photo_mc to framee 1

    this.gotoAndStop(1);

    // now that I'm on that frame, play from frame 16

    image01_mc.gotoAndPlay(16);

     

    Just add that second line of code in my example (or your project) and it will obey.

     

    It's not my preferred way of doing this type of thing because if your image01/02/03 etc are very heavy then on a slow system you could see a flicker when you switch between frames.

     

    Once you change frames the image##_mc on that frame is initialized on frame 1. Therefore possibly on a slow system you might see frame 1 flicker visible. What you're hoping is the second line is synchronously called fast enough to turn image01_mc to frame 16 and the user will never see frame 1.

     

    Another version of this that would avoid any possible flicker but would keep all images in memory is to toggle a property like .visible on the clip that should show and use some first frame logic. This may avoid a first frame flicker but will litter timelines with code. I'm not an advocate of timeline scripts, as easy as they are. Regardless if you have a lot of images this wouldn't be very ideal as your condition logic would expand a lot (if image01? 02? 03? ... 99?). But just for example:

     

    Example Visible Toggle Source

     
    |
    Mark as:
  • Currently Being Moderated
    Aug 9, 2013 9:40 AM   in reply to Cyber.Knight

    Are you trying to make this wrap around? When I see you advance the timeline forward in a function called backward() I assume you're trying to wrap around these two (or more) frames in your actual project.

     

    The img01_mc and img02_mc isn't helping you because you're using different frames. It's actually making you write more code to handle it. I'd recommend naming every image on a frame to the same name so the code can be re-used. Rename img01_mc and img02_mc to img_mc. Because they're on different frames it doesn't matter that the name is the same, they won't collide.

     

    After you rename them all to the same name you can do something like this to wrap:

     

    // back

    function backward(e:Event):void

    {

           if (img_mc.currentFrame > 15)

           {

                 // past frame 15 in current clip, replay from frame 1

                 img_mc.gotoAndPlay(1);

           }

           else if ((img_mc.currentFrame <= 15) && (this.currentFrame > 2))

           {

                 // reverse one frame in photos_mc on timeline

                 gotoAndStop(this.currentFrame - 1);

                 // play this previous clip from frame 16

                 img_mc.gotoAndPlay(16);

           }

           else if ((img01_mc.currentFrame <= 15) && (this.currentFrame == 2))

           {

                // on frame 2 and under frame 15, wrap to end

                 gotoAndStop(this.totalFrames);

                // play this previous clip from frame 16

                 img_mc.gotoAndPlay(16);

           }

    }

     

    // forward

    function forward(e:Event):void

    {

           if (img_mc.currentFrame <= 15)

           {

                // under or at frame 15 in current clip, play from frame 16

                 img_mc.gotoAndPlay(16);

           }

           else if ((img_mc.currentFrame > 15) && (this.currentFrame < this.totalFrames))

           {

                // over frame 15 in current image, more frames available in photos_mc, advance frame

                 gotoAndStop(this.currentFrame + 1);

                // clip should auto-play 1-15 itself

           }

           else if ((img01_mc.currentFrame > 15) && (this.currentFrame == this.totalFrames))

           {

                // on last frame in photos_mc, wrap to beginning, frame 2

                 gotoAndStop(2);

                // clip should auto-play 1-15 itself

           }

    }

     

    The idea here is to start your first image on frame 2, add as many frames with an image on it as you like expanding the timeline naming each image the same instance name img_mc. Each function will respectively check the current frame the image is on as well as the available frames in photos_mc and advance or reverse as needed. If frame 2 or the last frame in the timeline is encountered it should wrap.

     

    I wrote it quickly here so you might need to fix a typeo, missing period, etc. It should give you enough to do what you want.

     
    |
    Mark as:
  • Currently Being Moderated
    Aug 12, 2013 7:12 AM   in reply to Cyber.Knight

    As long as it does what you want it's all good . If you're all set please mark the thread answered (correct) so we can filter unanswered questions. Good luck!

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points