I have the following pattern to repeat an animation (itself consisting of x frames), t times:
sprite.prototype.loop = function(t,animation_name,frame_delay) {
if(t > 0) {
function next_run() {
this.loop(t-1,animation_name,frame_delay);
}
this.run(animation_name,frame_delay,next_run);
}
};
sprite.prototype.run = function(animation_name,frame_delay,frame_count,callback) {
frame_count ||= 0;
var s = this;
if(frame_count < this.paths[animation_name].length) { // x frames
setTimeout( function () {
s.blit(s.paths[animation_name][frame_count]);
s.run(animation_name,frame_delay,frame_count+1);
}, frame_delay );
}
} else {
if(!!callback) callback();
}
super_mario.loop(10000,'mushroom_death',40);
Clearly if x*t is larger than the maximum stack depth, a stack overflow will occur.
Question: Can this pattern be extended to the case of running an animation an infinite number of times, or is there a more correct way to do the infinite loop case?
I would rewrite your loop function as follows:
sprite.prototype.loop = function (t, animation_name, frame_delay) {
var s = this;
var frames = s.paths[animation_name];
var x = frames.length;
for (var i = 0; i < t; i++) {
for (var frame_count = 0; frame_count < x; frame_count++) {
setTimeout(function (frame_count) {
s.blit(frames[frame_count]);
}, (i * x + frame_count) * frame_delay, frame_count);
}
}
};
That's it. There won't be any stack overflow because there's no recursion.
Edit: As just2n mentioned there's another problem with your code. There won't be any delay between two same frames as you're in effect calling setTimeout for all the same frames at the same time. Hence the animation will only occur once no matter what the value of t.
setTimeout doesn't inherit the caller's stack frame, so you'd only have to worry about t here, though there's really no reason this can't be trivially written iteratively so that stack size isn't a concern:
sprite.prototype.loop = function(t, animation_name, frame_delay){
while (t--){
this.run(animation_name, frame_delay);
}
};
However, it feels like this code isn't doing what you expect it to do. This is literally running the animation t times in parallel, since the setTimeout calls in run will interleave one another. I'm not sure I can understand how that would be an intended effect, since each one of the t deferred callbacks would each perform the exact same blit operation here, so there would be no discernible difference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With