スプライトシートを使った描画
さて、実際の制作現場ではパフォーマンスを考慮し、複数の画像をまとめてスプライトシートと呼ばれる1枚の大きな画像を用いることがあります。
ここではImageMagickを利用して簡単にスプライトシートを生成する方法と、スプライトシートから任意のフレームをクリップして描画する方法を紹介します。
先ほど用いた9枚のピコピコハンマーの画像を1つのスプライトシートにまとめてみましょう。LIST4のコマンドで9枚の画像が縦横3×3で並んだ大きな1枚のスプライトシートができ上がります。
montage -background none -geometry +0+0 -tile 3x3 hammer00*.png hammer.png
でき上がる画像は図8のとおりです。
さて、この大きな画像ファイルから任意のフレームをクリップするためにはFrameコンストラクタの第5引数にUV座標と呼ばれる情報を指定します。UV座標は以下の形式で指定します。
[クリップ開始のx座標,クリップ開始のy座標,クリップ領域の幅,クリップ領域の高さ]
またUV座標は0から1の範囲で指定する必要がありますので、先ほど作った3x3のスプライトシートから1フレーム目をクリップする場合は以下のようになります。
[0, 0, 1/3, 1/3]
次に2フレーム目ですが、(1/3, 0)から同じく1/3ずつクリッピングするので以下のようになります。
[1/3, 0, 1/3, 1/3]
もう書くまでもありませんが、最後の9フレーム目は(2/3,2/3)から1/3ずつクリップするのでこのようになります。
[2/3, 2/3, 1/3, 1/3]
最後にコードを示しておきます。LIST5のようになります。
function main() { var glView = new UI.GLView({ frame: [0, 0, 80, 80], onLoad: onLoad }); glView.setActive(true); } function onLoad() { var path = "Content/gl/hammer.png"; var animation = new GL2.Animation(); animation.pushFrame(new GL2.Animation.Frame(path, 1000/9, [80, 80], [0, 0],[0/3,0/3,1/3,1/3])); animation.pushFrame(new GL2.Animation.Frame(path, 1000/9, [80, 80], [0, 0],[1/3,0/3,1/3,1/3])); animation.pushFrame(new GL2.Animation.Frame(path, 1000/9, [80, 80], [0, 0],[2/3,0/3,1/3,1/3])); animation.pushFrame(new GL2.Animation.Frame(path, 1000/9, [80, 80], [0, 0],[0/3,1/3,1/3,1/3])); animation.pushFrame(new GL2.Animation.Frame(path, 1000/9, [80, 80], [0, 0],[1/3,1/3,1/3,1/3])); animation.pushFrame(new GL2.Animation.Frame(path, 1000/9, [80, 80], [0, 0],[2/3,1/3,1/3,1/3])); animation.pushFrame(new GL2.Animation.Frame(path, 1000/9, [80, 80], [0, 0],[0/3,2/3,1/3,1/3])); animation.pushFrame(new GL2.Animation.Frame(path, 1000/9, [80, 80], [0, 0],[1/3,2/3,1/3,1/3])); animation.pushFrame(new GL2.Animation.Frame(path, 1000/9, [80, 80], [0, 0],[2/3,2/3,1/3,1/3])); var sprite = new GL2.Sprite(); sprite.setAnimation(animation); GL2.Root.addChild(sprite); }
GL2レイヤーとUIレイヤー
ここまでで、UIパッケージとGL2パッケージを使った描画方法を説明しました。GL2パッケージを使って描画する世界と、UIパッケージを使って描画する世界は独立したレイヤーのようになっていて、常にGL2の上にUIが表示されるようになっているので注意してください。
OpenGLの制約上、画像のサイズは縦横ともに2のn乗であることが求められています。ngCoreではその点も考慮して画像サイズの変換なども行ってくれますので、ここで作った画像も実行後生成される、build/の中を覗くと512x512のサイズに変換されていることが確認できます。