Skip to main content
Inspiring
August 5, 2013
Answered

AS3 gotoAndPlay Frame in a prevFrame

  • August 5, 2013
  • 1 reply
  • 12650 views

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);

}

This topic has been closed for replies.
Correct answer 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.


Well that is good to know. I figured I would get a ton of errors if I didn't give each instance a unique name. I decided to junk the looping effect (too much of a headache). You've been a great help. This is the code I used in the end.

right_btn.addEventListener(MouseEvent.CLICK, forward);

function forward(e:Event):void {

          nextFrame();

}

left_btn.addEventListener(MouseEvent.CLICK, backward);

function backward(e:Event):void {

          if ((img_mc.currentFrame <= 30) && (this.currentFrame > 2)) {

                    gotoAndStop(this.currentFrame - 1);

                    img_mc.gotoAndPlay(16);

          }

}

1 reply

sinious
Legend
August 5, 2013

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);

}

Inspiring
August 6, 2013

Thanks for the response. I probably should have mentioned that it is a nested movieclip. photos_mc has two frames (so far). Within each of those frames I have a SWF (movieclip). So it is nested. I am going to get an error from the other script because photos_mc only has two frames.

What I am trying to do is do a next and previous step. The next step works fine. It plays frames 1 to 15 (stop action) normally. The instantaces of them are img01_mc and img02_mc. The problem I am having is when I hit the back button it either errors or plays frames 1 to 15 instead of 16 to 30. I figure there is some simple coding that can be done on stage 1. I haven't found any code that has been helpful for parenting either.

Flow Chart

  • Click back button to go back one frame on photos_mc to gotoAndPlay on imgxx_mc frame 16 (already have a stop action on frame 30).

I am testing these first two out before I start putting more in. Eventually I am going to have about 20 SWF movieclips and like it to loop.

sinious
Legend
August 6, 2013

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.