HTML5ゲームのできるまで ~描画の高速化 (2)~

image1.jpg

こんにちは。システム本部プラットフォーム部の坊野です。

 

今回は前回に引き続きHTML5ゲームのリリースまでの過程で私たちが行ってきたことをお話します。

 

 

 

 

前回の振り返り

前回のBlogで「移動した画像の部分のみを再描画する」という手法について説明しましたが、残念ながらこの手法ではゲーム開発者が必要とする描画速度を達成できませんでした。また、この手法では背景スクロールなどの場合に描画速度が改善しないという問題もありました。

これらの問題を解決するため、私たちは新たな試作を行うことにしたのですが、その前になぜ前回の手法のどの部分に時間がかかっているのが調査することにしました。その調査結果の概要を円グラフで表すと表1のようになります。

表1 描画時間の解析結果

表1 描画時間の解析結果

この円グラフから、前回の手法のうち「消去された部分と重なっている画像の再描画」に多くの時間がかかっていることがわかります。また、この部分を細かく分解すると表2のように「消去された部分と重なっている背景の再描画」に非常に多くの時間がかかっていることがわかります。

表2 異なる画像の再描画時間の解析結果

表2 異なる画像の再描画時間の解析結果

これらの解析結果から、私たちはこの背景描画部分の最適化を行うことにしました。

 

背景描画の最適化

これから背景描画の最適化処理について説明するのですが、その前に「Blood Brothers」における画像位置の指定方法について説明します。

「Blood Brothers」では個々の画像の位置はその親画像からの相対位置 (相対座標系) をもちいて指定されています。たとえば、主人公の画像の位置から(0,100)の位置にそのHPバーを描画するという感じで指定されています。この画像位置の指定方法 (座標系) を用いて画像の分類を行うと個々のフレームは表3のようなツリー構造で表現されます。

表3 「Blood Brothers」における画像の分類

表3 「Blood Brothers」における画像の分類

ここで表3を見てみますとこのツリーにおいて背景画像とキャラクタ画像は親子関係にないことが分かります。このことから、私たちはこの構造を用いて個々のフレームを複数の子画像 (レイヤー) に分解すれば背景画像の再描画を防止することができると考えました。

この手法を用いたフレームの更新方法は以下のようになります。

1.フレーム内の画像をその座標系を用いてレイヤーに分解します。 (この場合は6個のレイヤーに分解されます。)

image4.png

2.個々のレイヤーに対して前回の手法を用いてその画像を更新します。 (この場合は赤く表示されたレイヤーのみ更新されます。)

image5.png

3.更新されたレイヤーを合成して更新フレームを作成します。

image6.png

この手法によって私たちの試作品は背景画像を再描画する必要がなくなったため描画速度は iPhone 4sで約50fpsと非常に高速になり、ついにスマートフォンゲームと同等の描画性能を達成することができました。

 

スクロールの高速化

今回の手法は背景スクロールのような場合にも非常に有効です。

 

たとえば「Blood Brothers」では「Go」ボタンを押すと背景画像のをスクロールが行われます。この場合、前回の手法ではキャラクターやステータス画面などの再描画を行う必要がありましたが、今回の手法を用いることにより、これらの再描画を行う必要がなくなりました。


また、背景画像が多くの画像で構成されている場合は背景レイヤーの画像を流用することによってさらなる高速化が可能になります。つまり、スクロール時には以下のような方法で描画をおこなうことにより再描画する画像の個数を減少させることができます。

1.新しいレイヤーを作成します。

image7.png

2.元レイヤーの画像をスクロール後の位置にコピーします。

image8.png

3.(赤色で示されている) 新しいレイヤーの未描画部分の描画を行います。


まとめ

前回から2回にわたりご説明したようにゲームに特化した手法を実装することによってHTML5ゲームでスマートフォンゲームと同等の描画速度を達成することができました。一方、描画以外の部分をみてみますと、私たちの試作品は画像やBGMのキャッシュが実装されておらず、起動が非常に遅いという問題が存在していました。


次回は起動高速化に必須となる画像や音声のキャッシュ方法について説明させていただきます。お楽しみに。