I'm trying to make a reversed play module in Action Script 3. I have a video, 200 frames long that I imported to Flash as a movie clip. I name the movie clip and inserted some key frames to make the video stop at specific frames, making it a 3 stage animation.
Whenever I swipe/pan to the right (detecting a positive x offset) it gives the command play();, the movie clip will play til it finds a stop.
What I want to achieve is to play it backwards from the current frame til the previous stop when I swipe to the left (detecting a negative offset).
I sorted out the swipe/touch programming and what I'm missing is the backwards bit. I've managed to make it work, going backwards 1 single frame, not the whole bunch that exist prior to hit the previous stop frame. My code for the swipe and play forward is this, with the single prev frame included, which gives me just one frame back instead of the whole set before the previous stop.
Multitouch.inputMode = MultitouchInputMode.GESTURE;
mymovieclip.stop();
mymovieclip.addEventListener(TransformGestureEvent.GESTURE_SWIPE , onSwipe);
function onSwipe (e:TransformGestureEvent):void{
if (e.offsetX == 1) {
//User swiped right
mymovieclip.play();
}
if (e.offsetX == -1) {
//User swiped left
mymovieclip.prevFrame();
}
}
You could try this:
import flash.events.Event;
import flash.display.MovieClip;
//note that this is not hoisted, it must appear before the call
MovieClip.prototype.playBackward = function():void {
if(this.currentFrame > 1) {
this.prevFrame();
this.addEventListener(Event.ENTER_FRAME, playBackwardHandler);
}
}
function playBackwardHandler(e:Event):void {
var mc:MovieClip = e.currentTarget as MovieClip;
if(mc.currentFrame > 1 && (!mc.currentFrameLabel || mc.currentFrameLabel.indexOf("stopFrame") == -1)) { //check whether the clip reached its beginning or the playhead is at a frame with a label that contains the string 'stopFrame'
mc.prevFrame();
}
else {
mc.removeEventListener(Event.ENTER_FRAME, playBackwardHandler);
}
}
var clip:MovieClip = backMc; //some clip on the stage
clip.gotoAndStop(100); //send it to frame 100
clip.playBackward(); //play it backwards
Now you can put 'stopFrame' label to the clip's timeline (stopFrame1, stopFrame2... stopFrameWhatever) and the clip should stop there until playBackward is called again. Note that you should remove the enter frame event listener if the clip hasn't reached a stopFrame or its beginning and you want to call play/stop from the MovieClip API, otherwise it may cause problems.
Related
Sorry this is so specific but I have combed through so many pages and videos and tutorials and can't figure this out.
I have all of my animations within a MovieClip. In the movie clip is also a stage sized white square button with the instance name "btn". Back on the main stage I have a second layer called "actions" with the following code applied to the first (and only) frame. It's not working. At all. (HUGE) tia
stop(); // this will stop the movie from playing at the start
btn.addEventListener((MouseEvent.ROLL_OVER, playMovie);
btn.addEventListener((MouseEvent.ROLL_OUT, stopMovie);
function playMovie(evt:MouseEvent):void {
play();
}
function stopMovie(evt:MouseEvent):void {
stop();
}
The problem is when you say play(); or stop(); which object are you really commanding? Your playMovie function could be in theory used to control many MovieClips at once, in different ways, so be specific with your commands...
btn.play(); //start the playback of "btn" MC
btn.stop(); //stop the playback of "btn" MC
Also consider using MOUSE_OVER/OUT instead ROLL_OVER/OUT etc but whatever works for you.
For reversing you will use btn.prevFrame(); together with an ENTER_FRAME event function. This function reads your Document settings for the FPS. For example, if you set 30 frames-per-sec then whatever instructions you put inside the event function will be processed 30 times per second.
See this other Answer for advice about reversing the playback of a MovieClip.
#VC.One is correct in how you should implement a solve to your issue, however in response to your comment on their answer, I thought I would demonstrate how to implement this fully for you - incase they don't.
var removeUpdate = false;
btn.addEventListener(MouseEvent.MOUSE_OVER, playMovie);
btn.addEventListener(MouseEvent.MOUSE_OUT, stopMovie);
function playMovie(evt:MouseEvent):void {
// Stop rewinding the movie clip and play it
if(removeUpdate){
stage.removeEventListener(Event.ENTER_FRAME, update);
removeUpdate = false;
}
// play our button
btn.play();
}
function stopMovie(evt:MouseEvent):void {
// stop our button
btn.stop();
// ... and rewind it
stage.addEventListener(Event.ENTER_FRAME, update);
removeUpdate = true;
}
function update(evt: Event){
// moves the button movie clip backwards one frame.
btn.prevFrame();
// If we have finished rewinding the movie clip, then stop
if(btn.currentFrame == 1){
stage.removeEventListener(Event.ENTER_FRAME, update);
removeUpdate = false;
}
}
It is important that you remove the update event because if you don't, the movie will never play again, because it will go one frame forward and then back again every frame due to; btn.play(); btn.prevFrame();
Hey i a have create a movie clip scene in the Second frame now what i want to do is that when it goes to the second frame and start play the clip and the clip finishes it will stop at the third frame i have done the Action script code but it doesn't work
function endDrag(event:MouseEvent):void
{
event.target.stopDrag();
event.target.x = startPoint.x;
event.target.y = startPoint.y;
if (jug.dropTarget != null && jug.dropTarget.parent == DropTarget && currentFrame == 1)
{
this.gotoAndStop(2);
nextFrame();
}
}
You are in frame 1. The user drags a Movie Clip named jug to a target named droptarget. So your function endDrag asks its parent (the Main Timeline) to gotoAndStop(2):
event.target.parent.gotoAndStop(2); // or this
In frame 2 another Movie Clip plays, and when it finishes to play, its parent (the Main Timeline) gotoAndStop(3). In the last frame of your movie clip:
MovieClip(parent).gotoAndStop(3);
I have an animation that I want to loop three times and then finish the final frames and then stop. I have tried this code to start with:
var stopNum = 0;
function looper(loopLimit) {
if (stopNum>=loopLimit) {
stop();
} else {
gotoAndPlay(2);
}
this.stopNum++;
}
And this code to stop:
if (!loopCount) {
var loopCount:Number = 0;
}
loopCount++;
if (loopCount >= 3) {
this.stop();
}
I have remaining frames to play from this point and then the entire animation stops. The problem is the frames loop three times but include all the frames including the closing frames.
Try using some events available from Flash 10 like so:
Event.FRAME_CONSTRUCTED
and
Event.EXIT_FRAME
Throwing some idea though, e.g. If your animation ends, then use Event.EXIT_FRAME and keep counter which will tell you that how many times animation is played.
Off the top of my head, I'd use an event listener to check for when the playhead advances for the moiveclip (as mentioned by Rajneesh). Within the event listener, I'd check for what frame it is at, and if it is at the end of my 'end loop frame' and then I'd check if I need to loop it. If so, then I increment a counter to keep track of how many times I've looped, and tell the movieclip to go to the start frame and play again.
Once it's looped enough times, I'd just let it run until the last frame then, on which I'd stop the animation.
I'll take a guess and assume your movieclip has 100 frames, and you only want frame 1 to 90 to loop 2 times, then have it play 1 more time, but from frame 1 to 100. Plays a total of three times from 1 to 90, then once 91 to 100, before stopping.
import flash.display.MovieClip;
import flash.events.Event;
var clip:MovieClip = this.aCircle;
var timesPlayed:int = 0;
var timesToLoop:int = 3;
var frameToStartLoop:int = 1;
var frameToStopLoop:int = 90;
function enterFrameListener(inputEvent:Event):void {
if(clip.currentFrame == frameToStopLoop){
timesPlayed++;
if(timesPlayed < timesToLoop){
clip.gotoAndPlay(frameToStartLoop);
}
// if the currentFrame made it past the above condition, then
// it means there is no more looping needed so just play till the end and stop.
} else if(clip.currentFrame == clip.totalFrames){
clip.stop();
// can remove this listener now, as it is no longer needed
clip.removeEventListener(Event.ENTER_FRAME, enterFrameListener, false);
}
}
// use an event listener to listen for the ENTER_FRAME event, which is triggered everytime the movieclip advances a frame
// (as a side note, you'll also find that this event is triggerd even if there is only 1 frame, or even if the playhead is not actually moving, check the doc for details)
clip.addEventListener(Event.ENTER_FRAME, enterFrameListener, false, 0, true);
So I have two movieclips, sRP_mc and dP_mc, on the first frame. Now, when either of the movieclips are clicked on, then I want the movieclip to be removed from the stage and then I want the frame to change (I want the movie to go to frame 5). On frame 5, there is a close button, which, if clicked, takes you back to frame 1 (but when it takes you back to frame 1, I want the movieclip which was clicked on to not be there anymore). Here is my code for my first frame (frame 1).
import flash.events.MouseEvent;
stop();
if (sRP_mc.visible == true) {
sRP_mc.addEventListener(MouseEvent.CLICK, sRPClicked);
function sRPClicked(event:MouseEvent):void {
sRP_mc.removeEventListener(MouseEvent.CLICK, sRPClicked);
removeChild(sRP_mc);
gotoAndPlay(5);
}
}
if (dP_mc.visible == true) {
dP_mc.addEventListener(MouseEvent.CLICK, dPClicked);
function dPClicked(event:MouseEvent):void {
dP_mc.removeEventListener(MouseEvent.CLICK, dPClicked);
removeChild(dP_mc);
gotoAndPlay(10);
}
}
and on frame 5, there is a close button and the code is this.
import flash.events.MouseEvent;
stop();
close_btn.addEventListener(MouseEvent.CLICK, closeScreen);
function closeScreen(event:MouseEvent):void {
gotoAndStop(1);
}
and on frame 10 there is also a close button the code is this.
import flash.events.MouseEvent;
stop();
close_btn.addEventListener(MouseEvent.CLICK, closeScreen2);
function closeScreen2(event:MouseEvent):void {
gotoAndStop(1);
}
As you can see, if sRP_mc or dP_mc are removed using the removeChild method, then sRP_mc and dP_mc should not be visible (.visible != true) but when I play this, it says that sRP_mc and dP_mc are always visible and the child does not get removed completely from the stage (or I think the isntance keeps coming back whenever I go back to frame 1). Why is it doing this and how would I fix it?
When the object is removed from the stage the visible property isn't changed to false unless you do so manually. Here's a better to way to check if an item isn't on the stage (I also cleaned up your inline function):
if (sRP_mc.stage != null) {
sRP_mc.addEventListener(MouseEvent.CLICK, sRPClicked);
}
function sRPClicked(event:MouseEvent):void {
sRP_mc.removeEventListener(MouseEvent.CLICK, sRPClicked);
removeChild(sRP_mc);
gotoAndPlay(5);
}
If an object is removed from the stage its stage property is set to null. Hopefully this helps!
I want to ask about this problem. I have a movieclip (instance name : char). Inside it I have 2 frames. The first frame contains a movieclip (it does nothing I forgot why I even bother to make it into movieclip). This first frame has frame label "still".
The second frame also contains a movieclip, inside it contains 12 frame. This second first frame has frame label "run"
This is my code
char.gotoAndStop(char.still);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keysDown);
stage.addEventListener(KeyboardEvent.KEY_UP,keysUp);
function keysDown(e:KeyboardEvent):void{
if(e.keyCode == Keyboard.RIGHT)
{
char.gotoAndStop("run");
this. char.scaleX = 1;
}
}
function keysUp(e:KeyboardEvent):void{
if(e.keyCode == Keyboard.RIGHT)
{
char.gotoAndStop("still");
}
}
The problem is, when I press RIGHT ARROW button, It moves, but the movieclip (with frame name "run") can't loop or even play complete from frame 1-12, it only plays from frame 1-9 then stop (not go to frame 10 or even loop)
is there something wrong with my code?
Have a look at how often the KEY_DOWN-Event is actually fired. For example by just tracing.
function keysDown(e:KeyboardEvent):void{
if(e.keyCode == Keyboard.RIGHT)
{
trace("pressed");
char.gotoAndStop("run");
this. char.scaleX = 1;
}
}
You will realize that the event is thrown WHILE the Key is pressed, not only once. You actually call the gotoAndStop("run") repeatedly, which makes your animation mc restart all the time.