movie clip within parent flash move stops entire movie - actionscript-3

I'm a bit new to Flash. As I was developing my movie, I introduced 3 layers of sequential animation that I decided I wanted to loop X times. So I copied the frames, created a new Movie Clip symbol, pasted the frames into it, then deleted the original on the stage and dragged this new clip as an instance (my_animation) in its place. All good so far.
However, when I play the entire movie, my_animation looped indefinitely, so I added a stop() action into that movie clip. That worked - plays once. I then added the following as an action on the very last keyframe of the main scene to try and get my_animation to loop X times:
var i = 1;
for (i = 1;i < 5;i++)
{
my_animation.play();
}
stop();
However, my_animation still only plays once. It does not appear to loop as I expect. I also tried replacing my_anmiation.play() with gotoAndPlay(117) where 117 is the frame containing the movie clip, but still the same.
Any help appreciated.
Thanks
UPDATE: I added a trace(i); statement within the loop. In the Output tab, I see:
1
2
3
4
…etc. SO - my_animation is not firing within the loop.

if you call my_animation.play(); with in "for loop" like that, it just calls 5 time consecutively and it just starts animation .
if you call my_animation.play(); during animation of my_animation nothing
happens. it works if it has stopped...
. so you need to listen add callback for to understand that animation finished and you can start that animation again..
var animatedCount:int = 0;
my_animation.addFrameScript(my_animation.totalFrames-1, onMyAnimationEnds);
my_Animation.play();
function onMyAnimationEnds():void{
animatedCount++;
if(animatedCount < 5)
{
my_Animation.play();
}
}
this will animate my_animation for 5 time...

Related

Jumping back and forth inside a Movieclip with a button?

So, I'm very much a beginner in AS3. I've been reading and figuring out things as I go, though I can't wrap my head around this.
So, I have 4 frames. Each frame has a different movie clip, MC1,MC2,MC3,MC4
Inside those four movie clips, there is another movie clip with the same instance name for each: BC, and inside that movie clip there are two frames. Frame 1 has a dot, and frame 2 does not.
MC1>BC>(2 frames)
MC2>BC>(2 frames)
and so on....
What I'm trying to do: I wanted to see if there was any way to control the frame navigation of BC inside all four MC clips at the same time with one button.
I want to switch back and fourth between the two frames inside the BC movie clip.
I'm at a loss, I've tried quite a few things.
You should be able to do so by giving them all the same instance name (so long as there is only ever one of them on screen at once).
So lets say you have a button that spans all 4 frames with an instance name of navBtn and you gave each of the MC1-4 clips the same instance name of MC. You could do the following on frame 1:
navBtn.addEventListener(MouseEvent.CLICK, navBtnClick);
function navBtnClick(e:Event):void {
if(MC.BC.currentFrame == 2){
MC.BC.gotoAndStop(1);
}else{
MC.BC.gotoAndStop(2);
}
}
Reading your question again, perhaps what are looking for is to have each clip automatically go to the same frame for their BC child when they load? If that is the case, then follow the example in the comment on your question by #Organis. Here is one way you could accomplish this:
Create two variable on frame one of your main timeline:
var BC_NAV_CHANGE:String = "BC_NAV_CHANGE";
var BC_CurFrame:int = 1;
Then, when you need to change the frame of the BC objects, do the following:
//create a function that you call when you want to change the BC frame
function toggleBCFrame(e:Event = null){
MovieClip(root).BC_CurFrame = MovieClip(root).BC_CurFrame == 1 ? 2 : 1;
//the line above is a if/else shorthand, that is setting a new value to the `BC_CurFrame` var,
//if the current value is `1`, it will set it to `2`, otherwise it will set it to `1`
MovieClip(root).dispatchEvent(new Event(MovieClip(root).BC_NAV_CHANGE));
//this line (above) dispatches a event telling anything that's listening that the variable has changed
}
If the code above is on the main timeline, you can forgo all the MovieClip(root). parts of the code.
Now, on the timeline of your BC MovieClip(s), put the following code:
//create a function that goes to and stops at the frame stored in the global variable
function updateFrame(e:Event = null){
gotoAndStop(MovieClip(root).BC_CurFrame);
}
//next listen for the BC_NAV_CHANGE event, and call the above update function above any time that event happens
MovieClip(root).addEventListener(MovieClip(root).BC_NAV_CHANGE, updateFrame);
//lastly, call the update function right away so when the BC clips loads it immediately goes to the correct frame
updateFrame();

Button Click Counter not incrementing

I have a similar animation in Flash with a replay button at the bottom. Once the animation completes, it does not loop. Instead if you click replay, the animation starts again.
I want a textbox which will display the amount of times the button was pressed.
My existing code is currently replaying the animation. It's incrementing the count to 1 (from 0) in trace but not getting set within the textbox. Additionally, if I click the button again, trace displays 1 again -- no increment occurred (1 to 2, 2 to 3, etc).
If I comment out gotoAndPlay(1), the incrementing works just fine and is displayed in the textbox -- but the animation does not play again.
What am I doing wrong?
import flash.events.MouseEvent;
var hitcount:Number = 0;
textCounter.text = String(hitcount);
function incCounter(event:MouseEvent):void
{
hitcount++;
textCounter.text = String(hitcount);
trace(hitcount);
gotoAndPlay(1);
}
replay_btn.addEventListener(MouseEvent.CLICK, incCounter);
The problem in your code is that you are creating and initializing every time your counter, so sure you will get every replay the value 1.
So to avoid that, you can just verify if you have already created the hitcount var otherwise create it :
if(!hitcount){ // hitcount is null, so create it
var hitcount:Number = 0;
}
As a good practice, you can also remove the MouseEvent.CLICK on your button if you don't need it. So you get something like this :
if(!hitcount){
var hitcount:Number = 0;
}
count.text = hitcount.toString();
function incCounter(event:MouseEvent):void
{
event.target.removeEventListener(MouseEvent.CLICK, incCounter);
hitcount++;
count.text = hitcount.toString();
gotoAndPlay(1);
}
replay_btn.addEventListener(MouseEvent.CLICK, incCounter);
Hope that can help.
If your flash movie is longer than one frame then the layer which you are placing your actions on the stage needs to extend that amount of frames as well. Otherwise the code is no longer there after frame 1. Also when you come back to frame 1 you are attaching yet another mouse event each time. Start your code with yourButton.removeEventListener to ensure you are only ever attaching one event to it. And every time the movie ends and goes back to frame 1 your counter is reset to 1.

Trigger a function when specific frame number is reached - AS3

I wanted friends, do the following when my MC get a determanido internal quandro, it triggers a function to another MC. for example when the ball hit the wall, a person goes to search - la, I have tried using :
("root") {root.MC.play ()}
Translation from comments:
Friends, I have an MC_1 with 10 frames, when it reaches frame 5, I want another movieClip MC_2 to respond (eg: to move or fade etc)
creating a ENTER_FRAME listener for your MC_1 is the easiest way to achieve this
MC_1.addEventListener(Event.ENTER_FRAME,respond);
function respond(e:Event):void{
if(MC_1.currentFrame>=5)
MC_2.gotoAndPlay(2);
//or any other respose you want from MC_2
}
addFrameScript can be used in AS3 to specify a function to execute on reaching a MovieClip frame.
MovieClip.addFrameScript(index:int, func:Function);
A sample implementation of this:
// addFrameScript's index is zero Based, hence 4 means frame 5
MC_1.addFrameScript(4, funcToExecute);
function funcToExecute():void{
// this will get called when MC_1 reaches frame 5
// do stuff here, like manipulating MC_2, etc...
}

Timer flash to show something at the right time

I want to make a timer that will show text at my panelText (dynamic text box) at specific time, actually I have a video that I want to have subtitles, and I want to use timer, my video is 3 minutes and 37 second long, and I have script that I want to show at some time, example at 1 minute 0 seconds it will show the text "hello, this is my video to learn about solar system" in my panelText, and at 2 minute I want to show text "There are 8 planets in our solar system", something like that. For information, I'm using flvPlayback to play the video and load the external video.
An example from my code:
var myTimer:Timer = new Timer(217000);
var time = 0;
myTimer.start()
myTimer.addEventListener(TimerEvent.TIMER,timerHandle);
function timerHandle(event:TimerEvent){
if(myTimer == 120000)
{
panelText.text="There's 8 planets in our solar system";
}
and i got error 1176: Comparison between a value with static type flash.utils:Timer and a possibly unrelated type int. can someone help me?, i'm sorry for my bad english
You should use FLVPlayback's addASCuePoint() function to make precise actions when your FLVPlayback fideo is playing. You use this function to set up whatever points you want to display custom subtitles, there can be as many of these as you want, then you listen for MetadataEvent.CUE_POINT event on your FLVPlayback instance, and process the cue point in order to display the associated subtitle. Note though, you will have to separately parse subtitle expiration, or assign a cue point to remove the displayed subtitle several seconds past the displaying cue point. Although it will be better if you will be able to add subtitles directly on the video, so that seeking through your video will not require handling of misaligned subtitles. Still, it's doable with pure AS3 code, if you would also listen to VideoEvent.FAST_FORWARD and VideoEvent.REWIND events to handle user interaction with playback and display corresponding subtitle by calling findNearestCuePoint() to find the closest earlier subtitle-enabled cue point.
An example of adding a cue point:
flv.addASCuePoint(0.1,"1",{text:"Subtitle one"});
flv.addASCuePoint(6.8,"2",{text:"Subtitle two"});
flv.addASCuePoint(11.8,"2 hide",{text:""}); // remove old subtitle
flv.addASCuePoint(120.0,"3",{text:"There are 8 planets in our solar system"});
Note that each call returns an Object, which is also returned whenever a MetadataEvent.CUE_POINT event is dispatched. This has a parameters sub-object that you have passed into addASCuePoint as third parameter, which you then parse and take actions depending on what's in there. Here, I've placed a single field "text" into each of the parameter objects, which should be the text to display as subtitles. So, then you listen to the cue point event and take actions, like this:
flv.addEventListener(MetadataEvent.CUE_POINT,cueHandler);
// do this only once, a listener does not need to be added per cue point
function cueHandler(e:MetadataEvent):void {
var cuepoint:Object=e.info;
if (cuepoint.parameters) {
panelText.text=cuepoint.parameters.text;
} else {
// DEBUG here
}
}
In case of seeking, you listen for FF and rewind events with a function that will call findNearestCuePoint(), retrieve its parameters.text and place that text into your text field.
You misunderstood the usage of the Timer class.
var myTimer:Timer = new Timer(n) means that the Timer will always "tick" at the specified interval n, in your case every 217000 milliseconds (217 seconds).
This might not be the best solution, but it'll show you how you can use the timer class for a scenario such as yours.
var myTimer:Timer = new Timer(1000); //a timer that will tick every second
myTimer.addEventListener(TimerEvent.TIMER, timerHandler);
myTimer.start(); //you should set up your listener before you start the timer
function timerHandler(event:TimerEvent):void{
//myTimer.currentCount will tell you how many times your Timer has ticked
//every tick, in this scenario, represents exactly one second, because we initialized the Timer with 1000 milliseconds
//so, if you want to show some text 86 seconds after the video has started, you could do:
if(myTimer.currentCount == 86){
panelText.text = "We're 86 seconds into the video";
}else if(myTimer.currentCount == 217){
//after reading your code it seems like you intended to let the timer only run 217 seconds, because that's the length of your video
//my proposed solution could also handle this, in this else if clause
myTimer.stop();
myTimer.removeEventListener(TimerEvent.TIMER, timerHandler);
myTimer = null;
}
}
The error is right.you are comparing a timer with a number!!.
fixed part of code:
if(myTimer.currentCount==120000){
panelText.text="There's 8 planets in our solar system";
}
and your timer constructor is wrong!the first argument is delay and next is repeat count.
the fixed code:
var myTimer:Timer = new Timer(100,2170);
var time = 0;
myTimer.start()
myTimer.addEventListener(TimerEvent.TIMER,timerHandle);
function timerHandle(event:TimerEvent){
if(myTimer.currentCount == 1200)
{
panelText.text="There's 8 planets in our solar system";
}
in this code, our timer ticked at every 0.1 second(100 miliseconds) and is ticked 2170 times. so, to set your text, you must put a zero after your desired second.
hope this helps :)

Replay button with counter

I'm having some trouble getting my playCount to work properly with my replay command.
The goal is to have a button pop up at the end, that gives the option to replay the animation. After the 3rd play, the button should no longer appear.
Currently it continues to show the button even after 3 plays.
The command to tell the replay button to appear is supposed to only trigger if the playCount is less than 3. The trace is coming back showing more that 3 plays, but the button still appears.
I'm not sure where the problem is.
Here's the problematic snippet of code (or where I think the problem is):
// replay button
if(playCount < 3)
{
trace(playCount);
tl.from(replayBtn, .5, {alpha:0})
replayBtn.addEventListener(MouseEvent.CLICK, replay);
}
function replay(event:MouseEvent):void{
tl.restart()
// add one to playCount
playCount++;
trace(playCount);
}
Here is a link to my files.
create a new function called removebutton then add an if condition
if(playCount >= 3)
{
trace(playCount);
replayBtn.enabled = false ;
replayBtn.removeEventListener(MouseEvent.CLICK, replay);
}
the reason is that your button is enabled and its still functioning , couldnt check your code though , but this might work ,
Managed to figure it out so I'll just leave this here
function replay(event:MouseEvent):void{
playCount++;
trace(playCount);
if(playCount < 2) {
//replay the function if there are less than 2 plays on the playcount
tl.restart();
} else {
//if there are not less than 2 plays, replay but the button invisible
tl.restart();
replayBtn.visible = false;
}
}
from what I originally had, I changed the function to an if-else clause. Instead of trying to make it not play the last step when the play count was about 2 (since it will replay 1 more time after it hits 2), I set it to restart if there are less than 2 counts and restart with the button invisible if there isn't less than 2 (the button is being hidden using alpha in the rest of the base animation)