BitmapAnimationに渡すanimations設定で、frequencyの値を1(指定なしの場合は1になる)にした場合、gotoAndPlayするとなぜか開始フレームの次のフレームから再生される。
色々と調べて一応解決したのでメモ。
//animationsの設定
animations : {
"start": [2, 7, false, 1]
}
//再生
movieClip.gotoAndPlay('start')
上記の場合、
2フレームから再生されるはずが3フレームから再生される。
簡単な解決方法としてはfrequencyの値を2(上記の場合"start"の第4引数=1)にすれば開始フレームから再生されるけど、stageの画面更新タイミングが2回のうち1回の描画になるので、動きが遅くなる。
FPSを調整すれば速さを変えられるので、シビアな環境でなければこれで良いと思う。
スマートフォン環境ではFPSを10程度に押さえたいのでfrequencyの値は1のままなんとかしたい。
Easel.jsのソースを読むと、なぜか開始フレームを1プラスしてから再生するように書かれている。
しかも複数のBitmapAnimationを使用していると、ちゃんと開始フレームから再生されるのと、開始フレーム+1から再生されるのがある。。
解決方法
良い解決方法ではないけど、BitmapAnimationを継承して無理やり開始フレームから再生されるようにした。
元のソースを読んだ感じだとdraw → _tickの順番で実行されれば問題ないぽいけど、実際には_tick → drawの順番で実行される(複数BitmapAnimationの場合だとたまにdraw → _tickがある)。
実行順を変えるのは大変そうなので、他の方法で。
簡潔に言うとは開始画像の描画前にthis.advance()が実行されているのが問題なので、
フラグを立てて、最初の画像を描画するまでthis.advance()を実行しないようにした。
上書き部分のみ書き出し。
gotoAndPlay: function(a) {
this.paused = false;
this._goto(a);
//再生スタート時にfalseにする
this.isFirstPlay = false;
},
draw : function(a, b) {
//先にdrawから実行された場合 _tickを実行
if(!this.isFirstPlay) this._tick();
if(this.DisplayObject_draw(a, b)) return true;
this._normalizeFrame();
var c = this.spriteSheet.getFrame(this.currentFrame);
if(c != null) {
var d = c.rect;
a.drawImage(c.image, d.x, d.y, d.width, d.height, -c.regX, -c.regY, d.width, d.height);
return true
}
},
_tick : function(params) {
var f = this._animation ? this._animation.frequency : 1;
if (this.isFirstPlay && !this.paused && ((++this._advanceCount)+this.offset)%f == 0) {
//これが実行されると開始フレームが+1されてしまう
this.advance();
}
this.DisplayObject__tick(params);
//1回でも_tickが実行されたらtrueにする
this.isFirstPlay = true;
}