スプライト

スプライトとは8x8~64x64サイズの画像を最大128個まで表示します。シューティングゲームでいう自機や弾、RPGでいう主人公キャラなどに使います。今回登場するメモリ領域は以下のとおりです。なお、図のとおりキャラクタデータはタイルモードとビットマップモードで位置が変わり、格納サイズも変わるという点に注意してください。早速、パレットデータ、キャラクタデータ、属性(Object Attribute Memory)の3つをそれぞれ見ていきましょう。

名前開始アドレス
パレットデータ(256色1パレット or 16色16パレット)0x5000200
キャラクタデータ(タイルモード時)0x6010000
キャラクタデータ(ビットマップモード時)0x6014000
属性(Object Attribute Memory)0x7000000
1.png

パレットデータ

フォーマットはmode3と同じです。構造はそのままに、16色をパレット16個か、256色をパレット1個で指定することも可能です。

キャラクタデータ

キャラクタデータは、パレット番号を指定した集まりです。単位は1キャラクタを8x8ドットとしています。16色の場合、4bitでちょうど16色指定できるので0x0〜0xfピッタリのサイズです。256色も0x0~0xffまでなのでデータを無駄にすることなく使うことができます。

ドット単位の格納方法サイズ
16横2ドット=1byte(下位4bitが左、上位4bitが右)32byte
256横1ドット=1byte64byte

gritの出力

16色のパレットデータとキャラクタデータの出力例を以下に表します。この画像は8x8ドットで上部をシマシマ模様にしています。結果がそのままバイナリに反映されていることを確認してください。

2.png
grit.exe spr2.png -gt -gu8 -gB4 -fts
 spr2Tiles:
	.byte 0x10,0x32,0x54,0x76,0x98,0xBA,0xDC,0xFE,0x10,0x32,0x54,0x76,0x98,0xBA,0xDC,0xFE
	.byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
 
 spr2Pal:
 	.hword 0x0000,0x0010,0x0200,0x0210,0x4000,0x4010,0x4200,0x6318
 	.hword 0x4210,0x001F,0x03E0,0x03FF,0x7C00,0x7C1F,0x7FE0,0x7FFF

キャラクタデータの補足

単位は1キャラクタを8x8ドットと先ほど説明していました。たとえば以下の256x128ドットのキャラクタデータがあったとしましょう。

3.png

このとき、キャラクタ番号は0番「空白」、1番「!」、2番「”」、3番「#」、となります。8x8単位のみを扱うのでしたらこのキャラクタ番号を指定し、表示するだけで話は終わります。ところが8x8単位以上のものを表示したい場合、格納方法に工夫がいります。格納が1次元か2次元か、ということです。例として文字列の下にある球体を32x32ドットで表示したい場合を考えてみます。この球体の番号は96です。1次元で32x32を取り出した場合のキャラクタ番号は96, 97, 98, 99, 100, 101, 102・・・111となります。結果は以下の通り。

4.png

円がきれいに表示されませんでした。では番号を224に変えてみましょう。

5.png

うまく行きました。この方法が1次元的取り出し方法です。データが切れ目なく連続しているため、キャラクタデータを入れ替えるときにとても便利です。個人的には後に教える2次元方法より良いと思っています。シューティングゲームなどでは頻繁にキャラクタデータの変更を行います。ボス戦なら画面いっぱいにキャラクタデータを使うので今のうちに1次元に慣れておくのがいいでしょう。次に2次元的取り出し方ですが、これは番号96にした場合の取り出し番号が96, 97, 98, 99, 128, 129, 130, 131, 160, 161, 162, 163となります。取り出す時の形状には、32x32以外にも以下のようなサイズがあります。

// スプライトの指定サイズ

enum SPRITE_SIZECODE {
	Sprite_8x8,
	Sprite_16x16,
	Sprite_32x32,
	Sprite_64x64,
	Sprite_16x8,
	Sprite_32x8,
	Sprite_32x16,
	Sprite_64x32,
	Sprite_8x16,
	Sprite_8x32,
	Sprite_16x32,
	Sprite_32x64
};

属性(Object Attribute Memory)

スプライトと属性は1:1の関係です。スプライトは最大128個ですので属性も128個あると思ってください。属性1つ分にはattr0, attr1, attr2, dummyという単位で構成されています。いわゆるC言語でいう構造体です。様々なパラメータが存在しており、いきなり覚えようというのは難しいと思います。今は軽く読み流す程度で結構です。

typedef struct {
	u16 attr0;
	u16 attr1;
	u16 attr2;
	u16 dummy;
} OBJATTR;
6.png
7.png

スプライト操作の汎用関数

こちらで用意した関数を通して簡単な(大雑把な)扱いを知ってください。

関数名用途
SpriteInit初期化
SpriteMove移動
SpriteSetSizeサイズの設定
SpriteSetChrキャラクタ番号の設定

すべてのスプライトを画面外に移動させます。非表示にするといった機能はありますが、念のため必ず初期化時に実行します。

スプライトの移動処理です。範囲はGBAの液晶画面サイズ240x160と同じではなく512x256となっています。-3,-3といった中途半端な表示にも対応しているわけです。

スプライトの形状と色数を変更します。引数size, formはgba.hの説明にあるものから選択して使用します。詳細はソースコードを読んでください。

スプライトで使用するキャラクタ番号を指定します。このほかにもいろいろな関数を用意できますが、今回はこれだけを使います。

スプライトの表示例

int main(void)
{
	// モード設定
	SetMode(MODE_0 | OBJ_ENABLE | OBJ_2D_MAP);

	u16* oam = OBJ_BASE_ADR;	// キャラクタデータ
	u16* pal = OBJ_COLORS;		// パレットデータ
	u32 i;

	for(i=0; i<spr1TilesLen/2; i++)
	{
		oam[i] = spr1Tiles[i];
	}

	for(i=0; i<16; i++)
	{
		pal[i] = spr1Pal[i];
	}

	SpriteInit();

	s16 x = 0;
	s16 y = 0;
	u16 s = 0;

	SpriteSetSize(0, OBJ_SIZE(s), OBJ_SQUARE, OBJ_16_COLOR);
	SpriteSetChr (0, 1);
	SpriteMove   (0, x, y);

	for(;;)
	{
		WaitForVsync();

		SpriteMove(0, x, y);

		u16 key = ~(REG_KEYINPUT);

		if(key & KEY_UP)    y--;
		if(key & KEY_DOWN)  y++;
		if(key & KEY_RIGHT) x++;
		if(key & KEY_LEFT)  x--;

		// フレーム単位で形状を変更
		SpriteSetSize(0, OBJ_SIZE(s>>4), OBJ_SQUARE, OBJ_16_COLOR);
		s++;

		if((s>>4) > 3)
		{
			s=0;
		}
	}
}

スプライトを使用するにはSetModeにOBJ_ENABLEを入れます。OBJ_1D_MAPかOBJ_2D_MAPかの2択で、取り出し方が1次元か2次元か指定します。

SetMode(MODE_0 | OBJ_ENABLE | OBJ_1D_MAP);

動作画面とデバッグ画面

8.png
9.png

履歴


添付ファイル: file7.png 29件 [詳細] file9.png 35件 [詳細] file8.png 31件 [詳細] file6.png 29件 [詳細] file5.png 29件 [詳細] file4.png 28件 [詳細] file3.png 30件 [詳細] file2.png 32件 [詳細] file1.png 32件 [詳細]

トップ   差分 履歴 リロード   一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2023-05-30 (火) 10:41:37