#author("2023-05-24T00:46:21+09:00","","")
#author("2023-05-30T00:33:45+09:00","","")
* 固定小数点 [#q2e864fe]
アクション系ゲームのキャラクタ移動など、1ドット単位よりも細かな座標指定を擬似的に扱うにはどうすればよいのでしょうか。ストレートに考えれば、小数点を変数に持たせることが必要になると思います。そこでfloat型を使用して・・・となりますが、ちょっと待ってください。浮動小数点の取扱いはCPUの処理に時間が掛かり、整数計算の数十倍は時間が掛かるといわれています。実は整数型を使った良い方法があるのです。~
アクション系ゲームのキャラクタ移動など、1ドット単位よりも細かな座標指定を扱うにはどうすればよいのでしょうか。ストレートに考えれば、小数点を変数に持たせることが必要になると思います。そこでfloat型を使用して・・・となりますが、ちょっと待ってください。浮動小数点の取扱いはCPUの処理に時間が掛かり、整数計算の数十倍は時間が掛かるといわれています。実は整数型を使った良い方法があるのです。~

方法は単純で''16を1ドット分とみなす''ようにするだけです。この決まり事を事前にプログラム上の約束にすることで「座標 % 16」という結果の「0~15までの値」を小数として利用できます。16進数でいう4bit分、つまりs16だと下位4ビット=小数点、上位12ビット=実際の表示ピクセル座標という扱いになります。

|RIGHT:|RIGHT:|RIGHT:|RIGHT:|RIGHT:|RIGHT:|RIGHT:|RIGHT:|RIGHT:|RIGHT:|RIGHT:|RIGHT:|RIGHT:|RIGHT:|RIGHT:|RIGHT:|RIGHT:|RIGHT:|RIGHT:|RIGHT:|RIGHT:|c
|10進数|0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|COLOR(red):16|17|18|省略・・・|
|16進数|0x0|0x1|0x2|0x3|0x4|0x5|0x6|0x7|0x8|0x9|0xA|0xB|0xC|0xD|0xE|0xF|COLOR(red):0x10|0x11|0x12||
| 2進数|0|1|10|11|100|101|110|111|1000|1001|1010|1011|1100|1101|1110|1111|COLOR(red):10000|10001|10010||

 s16 x, y;
 
 // 座標の代入
 x = ((GBAの横サイズ240 / 2) - (キャラサイズ / 2)) << 4;
 y = ((GBAの縦サイズ160 / 2) - (キャラサイズ / 2)) << 4;
 
 // 座標の加算
 x = x + 1;
 
 // 座標の表示
 SpriteDraw(x >> 4, y >> 4);


%は動作が重いため、シフト演算を使います。

** サンプルプログラム [#t5219b78]
 int main(void)
 {
 	REG_WSCNT = 0x4317;
 
 	BgInit();
 	IrqInit();
 	KeyInit();
 
 	SprInit();
 	SpriteSetAlpha();
 
 
 	char strX[32], strY[32], strM[32];
 	u16 cnt;
 
 	s16 x = ((240 / 2) - (8 / 2)) << 4;
 	s16 y = ((160 / 2) - (8 / 2)) << 4;
 	s16 m = 25;
 
 	for(;;)
 	{
 	    VBlankIntrWait();
 
 		KeyExec();
 		cnt = KeyGetCnt();
 
 		if(cnt & KEY_UP   ) y-=m;
 		if(cnt & KEY_DOWN ) y+=m;
 		if(cnt & KEY_LEFT ) x-=m;
 		if(cnt & KEY_RIGHT) x+=m;
 		if(cnt & KEY_R    ) m+=1;
 		if(cnt & KEY_L    ) m-=1;
 
 		if((x>>4) <      0) x = 0;
 		if((x>>4) >= 240-8) x = (240-8) << 4;
 		if((y>>4) <      0) y = 0;
 		if((y>>4) >= 160-8) y = (160-8) << 4;
 
 		if(m <=  0) m =  1;
 		if(m >= 50) m = 50;
 
 		SpriteMoveAlpha(x>>4, y>>4);
 
 		_Sprintf(strX, "x:%3d %4d 0x%04x", x>>4, x, x);
 		_Sprintf(strY, "y:%3d %4d 0x%04x", y>>4, y, y);
 		_Sprintf(strM, "m:%3d", m);
 
 		BgAsciiDrawStr(0, 17, strX);
 		BgAsciiDrawStr(0, 18, strY);
 		BgAsciiDrawStr(0, 19, strM);
 	}
 }

** 動作画面 [#t9a62457]
#ref(1.png,nolink)

** 出典元 [#pb4ac969]
- M-KAIさんの「Witchシューティングゲーム制作記帳」

** 履歴 [#j0abcb62]
- 2023/04/18
- 2008/06/30

トップ   差分 履歴 リロード   一覧 検索 最終更新   ヘルプ   最終更新のRSS