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.
Related
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.
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.
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.
i have a movieClip, which has 3 frames. when i call mc.init(); the mc movieClip should check with the current language and go to the specific frame.
E.g. current lang is 'tw', the trace correctly returns 2. However, the on screen display is the content of frame 1. and i can still trace a movieClip inside frame 1.
Can anyone tell me the reason of the issue??
mc (movieClip)
function changeLanguage(){
if (currentLang =='en'){
gotoAndStop(1);
}else if (currentLang=='tw'){
gotoAndStop(2);
}else if (currentLang=='fr'){
gotoAndStop(3);
}
trace(this.currentFrame);
}
function init(){
changeLanguage();
}
main.as
mc.init();
added 2:23am 21Jun2012
i found that it can gotoAndStop(3) without any problem, only when from frame2 to frame1 has the problem.
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);