抜き色による透過イメージ(スプライト)

スプライトとは、背景にキャラクタを描く機能です。

ビットマップは長方形なので、そのビットマップをそのまま背景に描くとキャラクタ本体だけでなく、キャラクタ以外の部分まで描かれてしまいますが、スプライトならキャラクタの部分だけを描く事が出来ます。

しかも、スプライトの場合は背景に直接描くのではなく表示の時に背景と「重ねあわせ」処理を行うので、キャラクタを移動した後に元のキャラクタを消す、という処理も不要です。
これはゲーム機などではおなじみの機能で、「キャラクタの部分だけを描く」という点では透過GIF もこれと同様の機能ですね。実際、Javaでは(擬似)スプライト機能の実装に良く透過GIFが使われるようです。

ただし、透過GIFだと単純に背景の上にキャラクタを描くだけなので、 移動したら移動前の部分を復元する必要があります。

・スプライト処理

通常スプライト機能をソフトで実現する(擬似スプライト)には、キャラクタの形に切り抜いた「型紙」(マスク)のビットマップを別に作って実現します。その型紙と背景、キャラクタを描いたビットマップの間で論理演算を行い、型紙の部分だけが描き込まれるようにするのです。

多くのシステムでは、この論理演算をハード的に備えているようで、Windows のGDI でもビットマップの描画モードが各種準備さていますね(スプライト機能がないのは残念ですが)。

ただ、DIBにDIBを描く場合にはこの機能は利用できません(ビットマップといってもDIBの場合は、単なるメモリ配列なのですから)。そこで、キャラクタのビットマップではキャラクタ以外の部分を「抜き色」で描いて描画の時に抜き色を描かないようにしましょう。

例えば、a の色を抜き色にすると、aの部分は描かれないので以下のように表示されます。

ビットマップ  実際に描画されるキャラクタ
 aaaccaaa            cc
 cccccccc         cccccccc
 aaccccaa    →     cccc
 aacaacaa           c  c

これをプログラムにすると、キャラクタ用ビットマップを他のDIB(=メモリ配列)に描く(=コピーする)時、抜き色かどうか調べて抜き色でなければコピーする、という処理をする事になります。

例えば、32×32のキャラクタ(partBMP)を255を抜き色にして256×256のビットマップ(bufBMP)に座標(x, y) から描くプログラムは以下のようになるでしょう(ビットマップはともに1ピクセル8ビット)。

  for (i=0;i<32;i++)
	for (j=0;j<32;j++)
		if (partBMP[j+i*32]!=255) // 抜き色でなければコピー
			bufBMP[x+j+(y+i)*256]=partBMP[j+i*32];

次に、キャラクタを移動した後に元のキャラクタを消す処理です。

単純に、キャラクタを描画する範囲を記憶しておいて復元する、という手もありますが今回は表示用のビットマップを一枚作り、それに背景→キャラクタという順番に描く事にしました。これなら、元のキャラクタは描画のたびに背景でクリアされますから、 後はその上にキャラクタを書き直すだけです。

あるいは、表示用ビットマップをGDIで扱えるビットマップにして、それにマスクと論理演算を使って透過処理を行う、という手もあるかもしれませんね。

・プログラム

実行すると、背景とキャラクタが表示されるので、カーソルキーでキャラクタを移動してください。

プログラムソース表示


プログラミング資料庫 > グラフィック処理研究室