この記事では、Cocos2d-xにおけるアニメーションのバッファリングについて説明します。
【前回まで】
・第1回 : アニメーションを利用した回復エフェクトの表示方法
・第2回 : 加算合成を利用して、背景が黒い画像をアニメーションで使えるようにする方法
・第3回 : エフェクトアニメーションの終了と同時にエフェクトを消す方法
キーの登録とキーによるアニメーションの取り出し
結論から言うと、キーの登録・キーによるアニメーションの取り出しを行うことで、高速、安定したアニメーション表示が可能となります。
Cocos2d-xではキーの登録という形で、予め作成したアニメーションを登録しておいて、後からキーで取り出してアニメーションを再生するという事ができます。
・キーの登録
/* animationTouroku : 予め生成しておいたアニメーション "keyName" : 任意の文字列 */ AnimationCache::getInstance()->addAnimation(animationTouroku, "keyName");
・キーによるアニメーションの取り出し
/* animationToridashi : 取り出したアニメーション "keyName" : 任意の文字列 */ Animation* animationToridashi = AnimationCache::getInstance()->getAnimation("keyName");
AnimationCacheはシングルトンクラスなので、プログラムのどこからでも呼び出すことができます。
ですので、Cocos2d-xのサンプルクラス中のHelloWorldScene::init()のように、アプリ起動時にアニメーションを生成・登録しておいて、アニメーションを再生したい場面でアニメーションをキーで取り出すといったやり方が可能です。
このように記述しておくことで、キーでアニメーションを取り出す際には、すでにアニメーションは「addAnimation」によりメモリ上に存在しており高速にアニメーションを表示可能というわけです。
アニメーションの生成には、アニメーションの元となる画像を読み込む必要があるため、ディスクI/Oが発生する(後述)のですが、ファイルの読み込みを予め済ませておき(バッファリング)、アニメーション表示時にディスクI/Oを発生させないことで高速、および遅延のない安定したアニメーション表示を実現します。※バッファリングはオンメモリにしておく、などとも言います。
ファイルの読み込みを予め済ませておく(バッファリング)
アニメーションを生成する際には、下記のプログラムのようにアニメの元となる画像を読み込みます。通常、そのようなファイル名を指定するようなプログラムではディスクI/Oが発生します。
SpriteFrame* sprite0 = SpriteFrameCache::getInstance()->getSpriteFrameByName("スプライトフレーム画像名");
一般的に、ディスクI/Oはメモリアクセスに比べて1,000,000倍程度遅いと言われています。(激遅! メモリアクセスがnsに比べて、ディスクI/Oはmsオーダー程度)
つまり、アニメーションをしたい瞬間にいちいちアニメーションを生成していてはディスクI/Oを大量に発生させることになり、アプリの処理状況によってはアニメーション処理が激重になって表示が遅れる可能性があるということです。
そのような状況を回避するため、ディスクI/Oを発生させるような処理はアプリ起動時や画面遷移時に予め行っておき、アプリ実行中にディスクI/Oによる負荷を避けることが重要です。
作法としてのバッファリングを意識したプログラムの実装
さて、ここまでバッファリングについて説明してきましたが、昨今のOSは進化していて、プログラムの先読みによるバッファリングなどの研究も進んでいるようです。
もしからしたら、ファイルを読み込むという1行のプログラムを実行する前に、既にOSによるプログラム先読みにより画像ファイルはメモリ上に存在しているかも知れません。
しかしながら、OSがどこまでバッファリングを意識しているかは、オープンソースでも無い限り通常は知り得ることのないことであり、その振る舞いをOSの分だけ調査することは現実的ではありません。
それならば、OSに依存したプログラムをギャンブル的に書く前に、作法としてディスクI/Oを意識したプログラムを行うほうが、より高速・安定したアプリに仕上がるのでは無いでしょうか。
結論
・アニメーションは予め生成しておいてキーを登録しておき、キーで取り出して使う!
・アニメーションに限らず、ディスクI/Oはなるべく最初に行っておく!
以上です。
ここまでご覧頂き、ありがとうございました。