3

アニメーション(それ自体は x フレームで構成される)を t 回繰り返す次のパターンがあります。

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

x*t がスタックの最大深度よりも大きい場合、明らかにスタック オーバーフローが発生します。

質問: このパターンは、アニメーションを無限回実行するケースに拡張できますか? または、無限ループのケースを実行するためのより正しい方法はありますか?

4

2 に答える 2

2

setTimeoutは呼び出し元のスタックフレームを継承しないため、ここで心配する必要があるだけですがt、スタックサイズが問題にならないように、これを繰り返し簡単に記述できない理由は実際にはありません。

sprite.prototype.loop = function(t, animation_name, frame_delay){
    while (t--){
        this.run(animation_name, frame_delay);
    }
};

ただし、このコードは期待どおりに機能していないように感じます。呼び出しが互いにインターリーブするため、これは文字通りアニメーションt時間を並行して実行しています。延期されたコールバックのそれぞれがここでまったく同じ操作を実行するため、それが意図した効果になるかどうかはわかりません。したがって、認識できる違いはありません。setTimeoutruntblit

于 2013-03-10T10:03:51.907 に答える
2

loop私はあなたの関数を次のように書き直します:

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

それでおしまい。再帰がないため、スタックオーバーフローは発生しません。

編集: just2nが述べたように、コードには別の問題があります。実際setTimeoutにはすべての同じフレームを同時に呼び出しているため、2つの同じフレーム間に遅延は発生しません。したがって、アニメーションは、の値に関係なく1回だけ発生しますt

于 2013-03-10T10:05:02.263 に答える