I have a 20 frame bouncing ball movieclip “ballAnim” on frame 1 of the stage, and I simply want to count each time “ballAnim” loops playback. I am inexperienced with actionscript, and I’ve searched and tried a few things to no avail.
Here’s the code from my latest attempt:
import flash.events.Event;
var loopCounter:int;
ballAnim.addEventListener(Event.ENTER_FRAME, addOneLoop);
function addOneLoop(e:Event){
if(ballAnim.currentFrame == 20)
{loopCounter 1}
}
trace(loopCounter);\`
All I get is a single instance of 0. I’ve searched around and I think the problem is that loopCounter is resetting to 0 on every frame because of ENTER_FRAME? I tried addressing this by adding a 2nd keyframe on my actions timeline layer with stop(); (with the movieclip layer spanning both frames underneath) but it doesn’t help. I’ve read that I might need to use a class, but I’m not sure what that is, and I thought this would be a fairly straightforward thing.
CodePudding user response:
Ok, let's have a class.
Your problem is not understanding the flow of things. If we put it simply, Flash Player executes the movie/application in the infinite loop of recurring phases:
- Playheads of playing MovieClips (also, the main timeline) move to the next frame.
- Frame scripts are executed.
- The whole movie is rendered and the picture is updated on the screen.
- Pause till the next frame.
- Events are handled.
Ok, the exact order just MIGHT be different (it is possible to figure it out but not important now). The important part is to understand that:
- Flash Player is (normally) not a multi-thread environment, the phases follow each other, they never overlap, only one thing at a time happens ever and we are pretty much able to follow, which one.
- The script you provided is executed at the "frame scripts" phase and that the ENTER_FRAME event handler doesn't execute until the "event handling" phase kicks in.
So, let's check it:
import flash.events.Event;
// This one returns time (in milliseconds) passed from the start.
import flash.utils.getTimer;
trace("A", getTimer());
ballAnim.addEventListener(Event.ENTER_FRAME, addOneLoop);
// Let's not be lazy and initialize our variables.
var loopCounter:int = 0;
function addOneLoop(e:Event):void
{
trace("BB", getTimer());
// Check the last frame like that because you can
// change the animation and forget to fix the numbers.
if (ballAnim.currentFrame >= ballAnim.totalFrames)
{
trace("CCC", getTimer());
// Increment operation is =, not just .
loopCounter = 1;
}
}
trace("DDDD", getTimer());
trace(loopCounter);
Now once you run it, you will get something like this:
A (small number)
DDDD (small number)
0
BB ...
BB ...
(20 times total of BB)
BB ...
CCC ...
BB ...
BB ...
Thus, in order to trace the number of loops happened, you need to output it inside the handler rather than in the frame script:
import flash.events.Event;
import flash.utils.getTimer;
ballAnim.addEventListener(Event.ENTER_FRAME, addOneLoop);
var loopCounter:int = 0;
function addOneLoop(e:Event):void
{
if (ballAnim.currentFrame >= ballAnim.totalFrames)
{
loopCounter = 1;
// This is the very place to track this counter.
trace("The ball did", loopCounter, "loops in", getTimer(), "milliseconds!");
}
}