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

How do I loop back from the first frame to the last frame?

New Here ,
Feb 16, 2013 Feb 16, 2013

Hi there,

I'm currently working on the framework for a product viewer.

I have:

a movie clip called 'viewer_mc' which contains the images take from different angles of the product. The actionscript generates a script on the last frame of this that returns it to frame 1.

a button instance called 'autoplay_btn' which plays through the movie clip from whatever the current frame is, and stops on frame 1.

a left and right button which serve to move the movie clip frame, to give the appearance that the product is rotating.

I have succeeded in getting it to:

have the movie clip play through once, return to frame 1 and stop.

have the buttons return functions when held down, that move the frame in the movie clip using nextFrame and prevFrame commands. The right button successfully loops round to frame 1 and continues functioning to give the appearance of continual rotation.

The last problem I am experiencing is getting the left button to act in the corresponding manner, going from the first frame to the last and continuing to function.

Here is my actionscript so far:

import flash.events.MouseEvent;

var lastFrame:Number = viewer_mc.totalFrames;

var thisFrame:Number = viewer_mc.currentFrame;

var backFrame:Number = viewer_mc.currentFrame-1;

1. This is the part that gets it to play through once before returning to the first frame. I think perhaps the problem I am experiencing is because of the 'viewer_mc.addFrameScript(lastFrame-1, toStart)' part i.e. although I'm holding the left button, its returning to this script and therefor getting bounced back immediately to the first frame. However, there is no flicker on the screen which you might expect if this were the case

Note - as this is a generic product viewer which I can use as a template I am using lastFrame etc. as opposed to typing the value in

function toStart (){

          viewer_mc.gotoAndStop(1);

}

viewer_mc.addFrameScript(lastFrame-1, toStart);

2. This is the functionality for the autoplay_btn that will play through a rotation / return the viewer to the initial (frontal) view of the product (frame 1).

autoplay_btn.addEventListener(MouseEvent.MOUSE_DOWN, autoplay);

function autoplay (ev:MouseEvent):void{

          var startFrame:Number = viewer_mc.currentFrame;

          viewer_mc.gotoAndPlay(startFrame);

};

3. This is the functionality of the right button, which when held, moves the movie clip to the next frame via the 'rotateRight' function based on the 'nextFrame' command. It loops back round to the first frame due to the 'viewer_mc.addFrameScript(lastFrame-1, toStart)' script generated on the last frame of the movie clip, as is desired.

right_btn.addEventListener(MouseEvent.MOUSE_DOWN, rightDown);

function rightDown(e:Event){

    stage.addEventListener(MouseEvent.MOUSE_UP,stoprightDown); //listen for mouse up on the stage, in case the finger/mouse moved off of the button accidentally when they release.

    addEventListener(Event.ENTER_FRAME,rotateRight); //while the mouse is down, run the tick function once every frame as per the project frame rate

}

function stoprightDown(e:Event):void {

    removeEventListener(Event.ENTER_FRAME,rotateRight);  //stop running the tick function every frame now that the mouse is up

    stage.removeEventListener(MouseEvent.MOUSE_UP,stoprightDown); //remove the listener for mouse up

}

function rotateRight(e:Event):void {

    viewer_mc.nextFrame();

}

4. This is the functionality of the left button, which when held, moves the movie clip to the prev frame via the 'rotateRight' function based on the 'prevFrame' command. And this is where the problem lies, as although it works for getting the movieclip back to frame 1, it does not loop round to the last frame and continue functioning, as is wanted.

left_btn.addEventListener(MouseEvent.MOUSE_DOWN, leftDown);

function leftDown(e:Event){

    stage.addEventListener(MouseEvent.MOUSE_UP,stopleftDown); //listen for mouse up on the stage, in case the finger/mouse moved off of the button accidentally when they release.

    addEventListener(Event.ENTER_FRAME,rotateLeft); //while the mouse is down, run the tick function once every frame as per the project frame rate

}

function stopleftDown(e:Event):void {

    removeEventListener(Event.ENTER_FRAME,rotateLeft);  //stop running the tick function every frame now that the mouse is up

    stage.removeEventListener(MouseEvent.MOUSE_UP,stopleftDown); //remove the listener for mouse up

}

I'd imagine it is probably my logic for this part that is really letting me down - I can do a similar function in actionscript 2, but am trying to learn actionscript 3 just to move with the times as it were, and struggling a bit. Still this is only a few days in!

function rotateLeft(e:Event):void{

          if(thisFrame==1){

                    gotoAndStop(viewer_mc.totalFrames-1);

          } else{

          viewer_mc.prevFrame();

          }

}

Any help you can give me would be gratefully received. For an example of the effect I am trying to achieve with the autoplay button etc. I recommend:

http://www.fender.com/basses/precision-bass/american-standard-precision-bass

TOPICS
ActionScript
5.0K
Translate
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

LEGEND , Feb 17, 2013 Feb 17, 2013

Here's a link to the file I made using your code with the change I indicated for the reverse playing.  See if it works as you expect.  If so, try to see what's different in yours.  If not, tell me what it should do that it fails to.

http://www.nedwebs.com/Flash/AS3_loop_play.fla

Translate
LEGEND ,
Feb 16, 2013 Feb 16, 2013

There's a bit too much wording to see much code in what you wrote.  For what I can see, I recommend you just use currentFrame instead of thisFrame, mainly because I can't see where you keep it updated...

function rotateLeft(e:Event):void{

          if(currentFrame==1){

                    gotoAndStop(viewer_mc.totalFrames-1);

          } else{

                    viewer_mc.prevFrame();

          }

}

One thing I am not sure of is whether you intend to go to the last frame (viewer_mc.totalFrames) or the second last frame (viewer_mc.totalFrames-1)

Translate
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
New Here ,
Feb 17, 2013 Feb 17, 2013

Thanks for getting back to me.

Here's the code without my comments / explanations:

import flash.events.MouseEvent;

import flash.events.Event;

var lastFrame:Number = viewer_mc.totalFrames;

var thisFrame:Number = viewer_mc.currentFrame;

var backFrame:Number = viewer_mc.currentFrame-1;

function toStart (){

          viewer_mc.gotoAndStop(1);

}

viewer_mc.addFrameScript(lastFrame-1, toStart);

//last image of viewer_mc = first image of viewer_mc

autoplay_btn.addEventListener(MouseEvent.MOUSE_DOWN, autoplay);

function autoplay (ev:MouseEvent):void{

          var startFrame:Number = viewer_mc.currentFrame;

          viewer_mc.gotoAndPlay(startFrame);

};

right_btn.addEventListener(MouseEvent.MOUSE_DOWN, rightDown);

function rightDown(e:Event){

    stage.addEventListener(MouseEvent.MOUSE_UP,stoprightDown); //listen for mouse up on the stage, in case the finger/mouse moved off of the button accidentally when they release.

    addEventListener(Event.ENTER_FRAME,rotateRight); //while the mouse is down, run the tick function once every frame as per the project frame rate

}

function stoprightDown(e:Event):void {

    removeEventListener(Event.ENTER_FRAME,rotateRight);  //stop running the tick function every frame now that the mouse is up

    stage.removeEventListener(MouseEvent.MOUSE_UP,stoprightDown); //remove the listener for mouse up

}

function rotateRight(e:Event):void {

    viewer_mc.nextFrame();

}

left_btn.addEventListener(MouseEvent.MOUSE_DOWN, leftDown);

function leftDown(e:Event){

    stage.addEventListener(MouseEvent.MOUSE_UP,stopleftDown); //listen for mouse up on the stage, in case the finger/mouse moved off of the button accidentally when they release.

    addEventListener(Event.ENTER_FRAME,rotateLeft);//while the mouse is down, run the tick function once every frame as per the project frame rate

}

function stopleftDown(e:Event):void {

    removeEventListener(Event.ENTER_FRAME,rotateLeft);  //stop running the tick function every frame now that the mouse is up

    stage.removeEventListener(MouseEvent.MOUSE_UP,stopleftDown); //remove the listener for mouse up

}

function rotateLeft(e:Event):void{

          viewer_mc.prevFrame();

}

The definition of the rotateLeft function is where the problem lies I think - I've taken out my poor attempts at doing the logic from the previous post. If I were to write it out long-hand the statement I want to write is: 'If you get to frame 1 and function rotateLeft is called go to the end of the movie clip'.

The reason I have to use the viewer_mc.totalFrames-1 definition in the addFrameScript call is the addFrameScript function is 0 based i.e. if you want to call frame 1 of the movieclip you have to return a value of 0 in the addFrameScript (or such is my understanding of it anyway). As such, the last image in the movie clip will need to be the view obtained at 360 degree rotation, which is of course the same view as at 0 degree rotation. As a consequence, the last frame in the movie clip is superfluous for the user, but necessary for the overall effect to be achieved. And, in addition, to keep up the effect of a 360 degree view when the rotateLeft function is called it needs to skip that last frame to go to the lastFrame-1 (or totalframes-1), or in other words, the view of the image prior to completing the full 360 rotation.

the variables thisFrame and lastFrame are defined at the very top of the script. Like you said they might need to be defined or called on again elsewhere.

Translate
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 ,
Feb 17, 2013 Feb 17, 2013

Did you try the change I indicated?

When you define the values of those variables at the top, only those that do not change will retain the correct value.  The value of thisFrame (and backFrame) will be the value it was when the file started and will not automatically update as the currentFrame value changes.  That's why I say to just use the currentFrame property instead.

Translate
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
New Here ,
Feb 17, 2013 Feb 17, 2013

That change didn't work unfortunately - and it also seems to have stopped the prevFrame part of it working at all.

Strangely, if I put currentFrame<1 the prevFrame bit works, but it still doesn't have the missing functionality of looping back around.

I am thinking it might be to do with the addFrameScript added earlier on, because in terms of logic the statement added to the totalFrames-1 frame sends it back to frame 1, where if you press the button, it sends you back to that frame which sends you back again etc. so its stuck. Would there need to be a condition added to this addFrameScript i.e. 'if the left button is held down don't add this in'?

Translate
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 ,
Feb 17, 2013 Feb 17, 2013

I missed something in my previous code offering... add the red bit

function rotateLeft(e:Event):void{

          if(viewer_mc.currentFrame==1){

                    gotoAndStop(viewer_mc.totalFrames-1);

          } else{

                    viewer_mc.prevFrame();

          }

}

If I build things up to agree with your code, the two controls work correctly.  THe auto needs work, but you should be able to work that out using similar logic.

Translate
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
New Here ,
Feb 17, 2013 Feb 17, 2013

I've put in the correction above and progress! - it now calls the prevFrame part of the function, but the gotoAndStop(viewer_mc.totalFrames-1) part, frustratingly, won't happen.

Here is what I currently have (I'm probably being stupid and missed something)

import flash.events.MouseEvent;

import flash.events.Event;

function toStart (){

          viewer_mc.gotoAndStop(1);

}

viewer_mc.addFrameScript(viewer_mc.totalFrames-1, toStart);

//last image of viewer_mc = first image of viewer_mc

autoplay_btn.addEventListener(MouseEvent.MOUSE_DOWN, autoplay);

function autoplay (ev:MouseEvent):void{

          var startFrame:Number = viewer_mc.currentFrame;

          viewer_mc.gotoAndPlay(startFrame);

};

right_btn.addEventListener(MouseEvent.MOUSE_DOWN, rightDown);

function rightDown(e:Event){

    stage.addEventListener(MouseEvent.MOUSE_UP,stoprightDown); //listen for mouse up on the stage, in case the finger/mouse moved off of the button accidentally when they release.

    addEventListener(Event.ENTER_FRAME,rotateRight); //while the mouse is down, run the tick function once every frame as per the project frame rate

}

function stoprightDown(e:Event):void {

    removeEventListener(Event.ENTER_FRAME,rotateRight);  //stop running the tick function every frame now that the mouse is up

    stage.removeEventListener(MouseEvent.MOUSE_UP,stoprightDown); //remove the listener for mouse up

}

function rotateRight(e:Event):void {

    viewer_mc.nextFrame();

}

left_btn.addEventListener(MouseEvent.MOUSE_DOWN, leftDown);

function leftDown(e:Event){

    stage.addEventListener(MouseEvent.MOUSE_UP,stopleftDown); //listen for mouse up on the stage, in case the finger/mouse moved off of the button accidentally when they release.

    addEventListener(Event.ENTER_FRAME,rotateLeft);//while the mouse is down, run the tick function once every frame as per the project frame rate

}

function stopleftDown(e:Event):void {

    removeEventListener(Event.ENTER_FRAME,rotateLeft);  //stop running the tick function every frame now that the mouse is up

    stage.removeEventListener(MouseEvent.MOUSE_UP,stopleftDown); //remove the listener for mouse up

}

function rotateLeft(e:Event):void{

                    if(viewer_mc.currentFrame==1){

                    gotoAndStop(viewer_mc.totalFrames-1);

          }else{

                    viewer_mc.prevFrame();

          }

}

Translate
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 ,
Feb 17, 2013 Feb 17, 2013

Here's a link to the file I made using your code with the change I indicated for the reverse playing.  See if it works as you expect.  If so, try to see what's different in yours.  If not, tell me what it should do that it fails to.

http://www.nedwebs.com/Flash/AS3_loop_play.fla

Translate
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
New Here ,
Feb 17, 2013 Feb 17, 2013

Found it! Line47 of your document I was missing the 'viewer_mc' from the viewer_mc.gotoAndStop....etc.

Thanks for all your help - its always something infuriatingly minute that goes wrong isn't it?

Incidentally, could you recommend any books for brushing up on actionscript 3?

Translate
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 ,
Feb 17, 2013 Feb 17, 2013
LATEST

You're welcome. 

Unfortunately I'm not a book guy... I have probably written enough to create a few of them myself but hate reading them.  The Sunday comics are my speed.

So while there might be some reasonably good reading material out there, I have no experience with any of it to offer advice.

Translate
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