• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

AS3 gotoAndPlay Frame in a prevFrame

Explorer ,
Aug 05, 2013 Aug 05, 2013

Copy link to clipboard

Copied

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

}

TOPICS
ActionScript

Views

11.5K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Explorer , Aug 10, 2013 Aug 10, 2013

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

...

Votes

Translate

Translate
LEGEND ,
Aug 05, 2013 Aug 05, 2013

Copy link to clipboard

Copied

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

}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 05, 2013 Aug 05, 2013

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Aug 06, 2013 Aug 06, 2013

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 06, 2013 Aug 06, 2013

Copy link to clipboard

Copied

I appreciate the help and I understand the code that you are using (even tested it). I since moved the as3 code and buttons from the main timeline to the photos_mc layer. I figure maybe if I can show you what I am doing you can understand my dilema. The picture below shows photo_mc (aka gallery). I have the actionscript layer, an images layer for my swf files, and a buttons layer.

photo_mc.jpg

This is the swf file in the first frame in the images layer in photos_mc. I have it playing 1 to 15 where a stop action is placed on frame 15 when they hit the forward button.

img01.jpg

What I like to do is when a user hits the back button it will go back one frame in the photos_mc layer then play from frame 16 to 30 from the movieclip (swf) inside that frame. I will eventually have over 20 swf files in the images layer. So let's say I am on img05. I can hit the back button to go to frame 4 and play img04's frames 16 to 30. Then hit the back button again to go to frame 3 and play img03's 16 to 30 and so forth.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Aug 06, 2013 Aug 06, 2013

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 06, 2013 Aug 06, 2013

Copy link to clipboard

Copied

I think there is a compatibility issue when I opened the file, I am using CS4 not CS5. When I tried to open the file, flash crashed. But yes you are correct in what I am trying to do. I also got it to loop. Here is the current code that I have.

right_btn.addEventListener(MouseEvent.CLICK, forward);

function forward(e:Event):void {

          if(this.currentFrame == this.totalFrames){

                    gotoAndStop(1);

          }else{

                    nextFrame();

          }

}

left_btn.addEventListener(MouseEvent.CLICK, backward);

function backward(e:Event):void {

          if(this.currentFrame == 1){

                    gotoAndStop(this.totalFrames);

          }else{

                    prevFrame();

          }

}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Aug 07, 2013 Aug 07, 2013

Copy link to clipboard

Copied

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 08, 2013 Aug 08, 2013

Copy link to clipboard

Copied

That helped out quite a bit. The issue that I am having now is that when I am on frame 30 and hitting the back button it replays 1 through 15. So now I have to hit the back button twice. I was looking to see about doing "if <30 but not equal to 15". I tried the operators but kept getting syntax errors.

right_btn.addEventListener(MouseEvent.CLICK, forward);

function forward(e:Event):void {

          if (this.currentFrame==this.totalFrames) {

                    gotoAndStop(2);

          } else {

                    nextFrame();

          }

}

left_btn.addEventListener(MouseEvent.CLICK, backward);

function backward(e:Event):void {

          if (this.currentFrame==2) {

                    if (img01_mc.currentFrame<30) {

                              img01_mc.gotoAndPlay(16);

                    } else {

                              prevFrame();

                    }

          }

          if (this.currentFrame==3) {

                    if (img02_mc.currentFrame<30) {

                              img02_mc.gotoAndPlay(16);

                    } else {

                              prevFrame();

                    }

          }

          if (this.currentFrame==1) {

                    gotoAndStop(3);

          }

}

I was trying to see if there was a way to do something like img+currentFrame+_mc so that I wouldn't have over a hundred lines of code.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 08, 2013 Aug 08, 2013

Copy link to clipboard

Copied

Looking at the code (both your's and mine) when we go back one frame it goes to photos_mc.imgxx_mc frame 1 instead of going to frame 16. So that is why I have to hit the back button twice. It is asking are we on frame x (yes) are we less than 30 (no) then plays 16 to 30. Then still being on frame x it says yes we are on frame 30 then goes back 1 and plays 1 to 15.

So in the else statement instead of just sending it back one frame we need to send it back one frame and play 16.

          if (this.currentFrame==2) {

                    if (img02_mc.currentFrame<30) {

                              img02_mc.gotoAndPlay(16);

                    } else {

                              prevFrame();

                    if (img01_mc.currentFrame<30) {

                              img01_mc.gotoAndPlay(16);

                    }

                    }

          }

Or something that does that desired effect.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Aug 09, 2013 Aug 09, 2013

Copy link to clipboard

Copied

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 09, 2013 Aug 09, 2013

Copy link to clipboard

Copied

Thanks I'm a step closer. They aren't video clips, just some images that I animated in After Effects and exported as SWF files. It's now going back and playing from frame 16 but it's not looping. When it's on frame 2 on photos_mc it doesn't go to frame 3 when I hit the back button. It just loops back into frame 2 until I hit the next button. When I hit the back button, it goes back from 3 to 2 but 2 doesn't loop back to three. The code seems to be logical (frame one is just a title screen on startup).

function backward(e:Event):void {

          if (this.currentFrame==2) {

                    gotoAndStop(3);

                    img02_mc.gotoAndPlay(16);

          }

          if (this.currentFrame==3) {

                    gotoAndStop(2);

                    img01_mc.gotoAndPlay(16);

          }

          if (this.currentFrame==1) {

                    gotoAndStop(3);

                    img02_mc.gotoAndPlay(16);

          }

}

Well I'm off to work now. I'll check back when I'm done. Thanks for all your help by the way.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Aug 09, 2013 Aug 09, 2013

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 10, 2013 Aug 10, 2013

Copy link to clipboard

Copied

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

          }

}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Aug 12, 2013 Aug 12, 2013

Copy link to clipboard

Copied

LATEST

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!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines