Is there any way to have the timeline in a Flash animation jump around? - actionscript-3

Basically, is there any Actionscript 3.0 code similar to gotoAndPlay, except it doesn't require any action from the user?

You don't need user input to call gotoAndPlay. You can call it from any point in code, just like any other API, including in timeline keyframes on from event handlers.
For example, I want to be able to play frames 1-10, then have it jump
to 200-210, and then jump back to 11-20.
You could do this by placing gotoAndPlay calls on timeline frames like this:
gotoAndPlay(1);
// frame 10
gotoAndPlay(200);
// frame 210
gotoAndPlay(11);
// frame 20
stop();
Or you could do it by monitoring the frame playback using the enterFrame event and call gotoAndPlay when certain frames are reached:
gotoAndPlay(1);
addEventListener(Event.ENTER_FRAME, enterFrame);
function enterFrame(e:Event):void {
switch (currentFrame) {
case 10:
gotoAndPlay(200);
break;
case 210:
gotoAndPlay(11);
break;
case 20:
stop();
removeEventListener(Event.ENTER_FRAME, enterFrame);
break;
}
}
The advantage to the second example is that you could work it into a re-usable function that works like gotoAndPlaySequence([0, 10], [200, 210], [11, 20]).
I also strongly recommend that you use frame labels in your actual code, instead of frame numbers. This gets very hard to follow otherwise.

Related

How to play animation and then play reverse on hover, start playing again until end on hover out using in Adobe Animate (Flash)?

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

Play only a certain range of frames

I have a combobox on the stage and changing its value I want to play only a certain range of frames:
stop();
combo01.addEventListener(Event.CHANGE, change);
function change(event:Event):void{
if (combo01.selectedItem.label == "BAL"){
gotoAndPlay(50);
if (currentFrame == 99) {stop();}
}
}
The game is not stopped but returned to frame 1.
You want your current frame check to happen when frame 99 is reached, not when change() is called. One way you can do this is to add a listener to check each frame as it is entered by the timeline until it reaches your desired frame:
addEventListener(Event.ENTER_FRAME, checkFrame);
function checkFrame(e:Event):void {
if(currentFrame == 99){
stop();
removeEventListener(Event.ENTER_FRAME, checkFrame);
}
}
Another way is to use the undocumented (but long supported) addFrameScript(): actionscript3 whats the point of addFrameScript
You could also just put a conditional stop() on frame 99, such as if (stopFrame == 99) stop(), then simply set stopFrame in your change handler.
You get the idea. You need your check to happen at frame 99.

EnterFrame handler to run only while timeline is stopped on a certain frame

I have some code in a frame. It's basically
this.addEventListener(Event.ENTER_FRAME, handleUpdate);
function handleUpdate(e:Event):void
{...}
I want the code to be executed only when on that frame. But the handleUpdate function keeps getting called even when I'm out of that frame.
The timeline is stopped on this frame, and I want the handleUpdate to run continuously until the timeline moves off the frame.
If you're set on having the code for this on the frame in question, then you could do this:
var tmpCurFrame:int = currentFrame; //store the current frame
this.addEventListener(Event.ENTER_FRAME, handleUpdate)
function handleUpdate(e:Event):void {
if (tmpCurFrame != currentFrame) { //if the frame has changed, stop the frame handler
this.removeEventListener(Event.ENTER_FRAME, handleUpdate);
return;
}
//do your code
}
handleUpdate(null);
As an aside, it's much cleaner to have a document class and other class files that manage this sort of thing instead of using frame scripts. But if you all you're looking for is a quick and dirty tweak to your existing code, this should do the trick.
Haven't you heard about addFrameScript ?
It's perfect for your needs.
var desiredFrame = 25; // Timeline frame (starts from 1)
this.addFrameScript(desiredFrame-1, onFrame25); // 1st param is zero-based
function onFrame25():void
{
trace("I'm on frame", desiredFrame);
}
There's a few things you should consider with your approach:
Adding an ENTER_FRAME listener on the frame you care about happens after you enter that frame, so if the movieclip is playing you won't get an ENTER_FRAME event until the next frame (at which time it may have moved off that frame).
Be aware that code on a frame executes every time the playhead enters that frame, and you should be careful to remove listeners when appropriate for memory leak purposes.
So one approach would be to place this code on the frame in question - note that it also nicely removes its listener:
var thisFrame:int = currentFrame;
function handleUpdate(e:Event) {
if (currentFrame==thisFrame) {
// your code here...
} else {
// remove listener if we moved off the frame
removeEventListener(Event.ENTER_FRAME, handleUpdate);
}
}
// call it now because the listener won't fire until next frame
handleUpdate(null);
// add listener in prep for next ENTER_FRAME, though note that
// if we move off this frame, then the listener is removed above
addEventListener(Event.ENTER_FRAME, handleUpdate);
Another approach would be adding the following code on frame 1, so the listener always runs and is never cleaned up, and only performs the code when on frame 12:
addEventListener(Event.ENTER_FRAME, handleUpdate);
function handleUpdate(e:Event):void
{
if (currentFrame==12) {
// your code here...
}
}

Making platform game, need method to stop running

I am making a platform game in flash.
I have a goal class(the class which contains code for the goal sprite, where when you hit it, it continues to next part of game).
Inside the goal constructor, 2 event listeners are added, they are as follows:
addEventListener(Event.ADDED, beginClass);
addEventListener(Event.ENTER_FRAME, eFrame);
The beginClass function is fine, and only runs once, but eFrame is what checks if the player has hit the goal, so it is constantly running. The problem is, once the player hits the goal, eFrame continues to run, while in a menu describing the next scene to the player. My eFrame function is below.
private function eFrame(event:Event):void{
if(hitTestObject(_root.mcMain)){
var lastScore:int = _root.mainScore;
_root.mainScore = lastScore;
while (_root.lvlHolder.numChildren > 0) {
_root.lvlHolder.removeChildAt(0);
}
_root.mcMain.removeChildAt(0);
_root.isInCut = true;
if (_root.lvlCurrent == 1) {
_root.gotoAndStop(2);
} else if (_root.lvlCurrent == 2) {
_root.gotoAndStop(3);
} else if (_root.lvlCurrent == 3) {
_root.gotoAndStop(4);
}
}
}
Frames 2, 3, 4, are frames with just text and a button that display a message to the player, and then the player hits continue. My problem is that eFrame is still trying to be run, but the class has not been instantiated, and the method is causing extreme amounts of lag once the player continues.
Inside Goal, what's the point of _root?
Anyway here's what I've done:
Change the event ADDED to ADDED_TO_STAGE, that way, when the event is fired we know this Sprite has a stage property.
addEventListener(Event.ADDED_TO_STAGE, beginClass);
Remove the eFrame event from the constructor. Add it to beginClass, with stage, like so:
stage.addEventListener(Event.ENTER_FRAME, eFrame);
Now in eFrame, you can awesomely remove the event with the stage reference. It didn't work earlier because the reference was wrong (whatever it was with the _root variable).
stage.removeEventListener(Event.ENTER_FRAME, eFrame);
BUT - remember to do it before this part of your code:
while (_root.lvlHolder.numChildren > 0) {
_root.lvlHolder.removeChildAt(0);
}
because when the sprite is removed, it won't have the stage property anymore. Just remember to clean up events in all possible scenarios. I'm not entirely sure stage is the right place to place your enter frame event, I just assumed so because of what you earlier called _root.
Inside eFrame() stop the event listener:
removeEventListener(Event.ENTER_FRAME, eFrame);
you're adding eventListener to stage so try this:
stage.removeEventListener(Event.ENTER_FRAME, eFrame);
or
parent.removeEventListener(Event.ENTER_FRAME, eFrame);
or
event.target.removeEventListener(Event.ENTER_FRAME, eFrame);

Reverse timeline code for as3

How would I get to play backwards a timeline from a specific frame to another frame?
I need to be able to play back from frame 62 to 1 and from 101 to 62 depending on what frame I am on. I know I can do 2 if loops with if (currentFrame == 62) etc but what is the code to play the timeline in reverse for AS3?
You can use Greensock's TweenLite class to tween frames of your timeline in either direction.
Tweenlite.to ( mc, 1, {frame:1} );
Something like this:
stop();
var targetFrame:int = 62;
// if we are ahead of the target, start going backwards
if(currentFrame > targetFrame) stage.addEventListener(Event.ENTER_FRAME,goBack);
function goBack(evt:Event):void
{
prevFrame();
// kill the event listener when the target is reached
if(currentFrame <= targetFrame) stage.removeEventListener(Event.ENTER_FRAME,goBack);
}