検索
連載

スプライトアニメーションはゲーム開発の超基本BREWアプリケーション開発入門(5)

BREWの基礎から開発環境の構築・アプリケーション開発までを順を追って紹介。2Dラスタ/ベクタ描画を解説した前回のグラフィックス基礎編に続き、今回も2Dラスタデータの利用を詳しく見ていく。

PC用表示 関連情報
Share
Tweet
LINE
Hatena


 前回「ラスタ/ベクタ、2Dグラフィックスの基礎のキソ」は、2Dグラフィックスの基礎として「2Dベクタデータ」「2Dラスタデータ」の描画を行いました。今回はその続きとして、2Dラスタデータの利用をもう少し詳しく見ていきたいと思います。

 2Dラスタデータを使った処理は、ゲームなどでよく利用されており、単にデータをロードして描画する以外にも便利な機能が提供されています。

 今回はその利用を含め、さらに“アニメーションさせる”という部分にも触れたいと思います。

スプライトを利用する

 ゲームなどで多用される画像処理の1つに「スプライト」処理があります。ゲームでは画像をロードして、表示させるだけではなく、キャラクターがユーザーの操作によって動いたり、敵や背景がアニメーションするなど、描画フレームごとにグラフィックスが異なります。

 さらに、ユーザーがコントロールするキャラクターや敵キャラクターの動作は、状況によって変化するため、決まった画像を単に表示するのでなく、効率よくインタラクティブに描画する必要があります。

photo
図1 単純なアニメーションとゲームとの違い

 このように描画内容の一部を変更したり、画像を部品化したりして、データを効率よく用いる際に使用される技術がスプライトです。

 スプライトは、1画面の絵を構成する要素を複数の細かい部品(画像)にし、それらを画面上の任意の位置で合成して、表示する技術です。1枚の画像で1画面を作らないので、ゲームのようなインタラクティブな描画をするのに適した画像処理方法といえます。

photo
図2 1枚の絵とスプライトとの違い

ISpriteの利用

 BREWでは、専用のスプライト機能(スプライトエンジン)が提供されており、それを利用することで、スプライトを簡単に実現できます。

 スプライト機能を利用するためには「ISprite」を使います。「ISprite」には、大きく以下の機能が提供されています。

1. オブジェクト表示機能……画面上をアニメーションするキャラクターやオブジェクトを扱う機能

2. タイルマップ機能……背景を動的に作り出す機能

 この2つの機能を利用することによって、インタラクティブな2Dグラフィックス描画が可能になります。

コンパチブルビットマップの利用

 前回、ビットマップデータを描画したときには、単純に画像データをロードして、そのデータを画面転送しただけでした。ディスプレイは、「ピクセル」という単位で構成されたVRAMなどのメモリ上に「ピクセルバッファ」を持っており、これを「デバイスビットマップ」と呼びます。通常、プログラムから描画処理を行う場合、このデバイスビットマップへの処理が必要となります。

 一方、スプライトの場合は、ロードした画像を合成する必要があるため、合成用の領域を確保する必要があります。この領域は、デバイスビットマップとの互換性を有し、「コンパチブルビットマップ」と呼ばれます。

 コンパチブルビットマップを作成するには、「IBITMAP_CreateCompatibleBitmap()」を使います。

*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***

 第1引数に、元のデバイスビットマップを指定して、第3、4引数で指定した大きさで作成したコンパチブルビットマップを第2引数に格納します。ここで作成したコンパチブルビットマップをスプライト用の画像合成領域として利用します。

 以下は、スプライト用のビットマップデータをロードして、コンパチブルビットマップを作成するサンプルです(ソース1)。

*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***

 「ISprite」を利用する場合には、以下のヘッダをインクルードする必要があります。

*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***

 「ISprite」は別の関数でも利用するので、「Applet」構造体の下位にメンバを追加しておきます。

*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***

 多少分かりにくい部分もあるかと思いますので、以下に処理の流れをまとめます(図3)

photo
図3 スプライト用のビットマップデータをロードして、コンパチブルビットマップを作成する流れ

 ここでのポイントは、読み込んだスプライト用BMPデータを、「IBITMAP_BltIn()」で作成したコンパチブルビットマップに転送し、それを「ISPRITE_SetSpriteBuffer()」で「ISprite」に設定している部分です。

 単に、BMPデータを描画するだけであれば前回紹介した「IDISPLAY_BitBlt()」を利用すればよいのですが、ここでは任意のコンパチブルビットマップに対しての転送になるので、「IBITMAP_BltIn()」を利用しています。そして、スプライト処理はBREWのスプライトエンジン側のバッファで行われるため、スプライトエンジンのバッファに処理対象を設定する必要があります。

 最後に、「ISPRITE_SetDestination()」で最終的な描画ターゲットを指定しています。これにより、コンパチブルビットマップで行われた合成結果を、デバイスビットマップに対して転送することになります。実際の転送は、スプライト処理後に行います(詳しくは後述)。

 また、コンパチブルビットマップなどの変数を「IBITMAP_Release()」ですぐに開放していますが、特に問題はありません。BREWのAPIリファレンスを見てみると以下のように解説があります。

*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***

 まず、前提としてBREWでは、あるインスタンスが内部的に異なる複数のインスタンスから参照されている可能性があるため、参照カウントという形で参照インスタンスの数を管理しています。そのため、開放処理には参照カウントのデクリメントが必要で、参照カウントが0になると、インスタンスが実際に開放されます。つまり、「Release()」は参照カウントをデクリメントする関数で、ここではプログラム側からの参照とスプライトエンジン側からの参照があるため、プログラム側から「Release()」を呼んでも、スプライトエンジン側の参照が有効なため、ビットマップの開放は実際には行われていないことになります。

 スプライト処理は、読み込んだ画像をスプライトエンジン側でいろいろと操作するため、画像の読み込みから処理、開放に至るプロセスが長くなりがちです。このため、プログラム側のインスタンス参照を任意のタイミングで開放できれば、面倒な開放のタイミングを気にすることなく、スプライトエンジンに任せることができるという配慮がなされていると考えることができます。

*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***

>>スプライトの詳細については次ページ(MONOistサイトに移ります)で解説します


Copyright © ITmedia, Inc. All Rights Reserved.

ページトップに戻る