AS3で歩行グラフィック

ゲームキャラクターを表示させる歩行グラフィックというものがあるのですが
これをAS3で表示する方法をいろいろ調べた結果をまとめてみました。

こんな感じで、横列(行)には方向パターン、縦列にフレームアニメーション用のパターンをおさめた行列構造の画像を、歩行グラフィック(またはキャラチップ)と呼ぶそうです。

これを表示する方法としては、
行列構成のビットマップ画像から毎フレームごとに表示する箇所を切り出して描画する
という処理が一般的のようです。

歩行グラフィックの描画処理

つまり、右方向にキャラクターが進行しているのならば
右向きの画像が並ぶ行を、順に描画する、という感じです。

Spark project に歩行グラフィックを表示するライブラリがありました。

CharacterWalker
http://www.libspark.org/wiki/tarotarorg/CharacterWalker

Wonderflにもありました。
http://wonderfl.net/c/l7rP

他にもゲーム用フレームワークなどいろいろあるのでしょうけれども
キャラクターをフレームアニメーションさせる仕組みとしては、ほぼ同じだと思います。

描画方法の検証

ぱっと思いついた3つの方法で実装してみます。

キャラクターサイズのBitmapを作成して、BitmapData.copyPixelsで描画
キャラクターサイズのShapeを作成して、Graphics.drawRectで描画
キャラクターサイズにマスクしたSpriteに、Bitmapを配置して表示位置を変える

最初の二つがもっともよく見かけた方法でした。
最後のはJS版を作ったときの方法をそのまま流用したCSSスプライト的な考え方です。

実験としては、キャラクターを3000体描画してそのコストを比較します。

なのですが、大量に表示するのであれば、ステージサイズのビットマップに直接描画するのが効率的だと思います。
まずは基準として、これを実装してます。

ステージサイズのビットマップに描画

CharacterChip Test - wonderfl build flash online

手元の環境(Mac mini / Core 2 Duo 2.26 / 4GB)だと FPS 60 ぐらいです。
単純に速度を出すのであればこれが理想的な方法なのですが、今回は目的が違うので、この数字は参考までに。

次の3つは、3000体のキャラクターを生成して、描画方法の違いを検証してみます。

Spriteに配置したBitmapを移動させる

CharacterSprite Test - wonderfl build flash online

それぞれのFPSが 38、33、20 ぐらいになりました。
※一度にSWFを再生すると、どんどん重くなるのでリロードなどして個別に見てください

描画速度は、BitmapData.copyPixelsと、Graphics.drawRect が比較的速いですね。
数字の違いはあると思いますが、速度差はどの環境でもだいたい同じだと思います。

ただ、この方法だとかなりメモリを食っているように見えますが
まったく最適化していないので、今回の検証ではあまりそこは重要視しません。

例えば、同一の画像であればSWFに画像を埋め込むことでかなり軽減できます。

Flash コンテンツパフォーマンス最適化 (メモリ編 2)

BitmapData の単一参照機能

* Flash Player 10.1 では、埋め込まれたイメージから BitmapData インスタンスを作成すると、常に単一のインスタンスを参照する
* 既存のコンテンツも再コンパイル無しで Flash Player 10.1 上で実行するだけでこの機能が利用できる
* 従来の Flash Player では BitmapData のインスタンスを生成した数だけ、実際にインスタンスがメモリ上に生成されていた

この方法も一応、試してみます。
画像をLoaderで読みこまず、Embedした画像を 2番目の方法(Graphics.drawRect)で描画した場合です。
WonderflだとEmbedが使えないので、あらかじめパブリッシュしたSWFを貼っておきます。

Embedした画像で、Graphics.drawRect