ビットでフラグを管理する

アバター
せんちゃ
記事: 50
登録日時: 15年前
住所: 江別市東野幌町
連絡を取る:

ビットでフラグを管理する

投稿記事 by せんちゃ » 12年前

当たり判定などを取る場合、
複数のプレイヤーを個別にとる場合を考える。
プレイヤーとマップモデルが衝突したときに、アニメーションを再生させる場合などは
初回ヒット(trigger)と毎回のヒット判定(hold)で判定を分ける必要がある。
初回ヒット時のみ、ヒットしたモーションを再生させる、といった感じです。


クラスメンバにhitMaskというint型を定義
hitMaskには毎回のヒットフラグを記憶させます。

CODE:

for( int i = 0 ; i = 0 && i < max_player );

	//	衝突した!!
	if( isCollision() ){
		//	&演算した結果0の場合、
		//	前回の判定ではヒットしていなかったということなので
		//	初回ヒットとして扱う
		if( ( hitMask & player_mask ) == 0 ){
			model.playAnimation( ヒットしたときのアニメ );
		}
		//	初回でなかったときの処理
		else{
		}
		
		//	ヒットしたキャラのフラグを立てる
		hitMask |= player_mask;
	}
	else{
		//	ヒットしていないのであればフラグを落とす
		//	&演算とビット反転を組み合わせることで、
		//	指定のビットを確実に0にすることができる
		hitMask &= ~player_mask;
	}
}
このようにビットで判定することのメリットとしては、
配列で管理するよりエラー処理を減らせるという点。
配列だとオーバーフローとアンダーフローが発生しないように
アクセスするたびにチェックする必要がありますが、このような方法だと
初回の一回、不正な値がないかのチェックだけで済むので非常にお得


hitMask変数をあちらこちらで参照すると危険ですが、
そこはプログラマー側が注意して管理するべき部分なのでいろんなところで
不必要に値をいじったりはしないように注意するという感じです。



ということを会社で教わったので、とりあえずメモ。
ある種の定型文らしい

ISLe
記事: 2650
登録日時: 15年前

Re: ビットでフラグを管理する

投稿記事 by ISLe » 12年前

わたしはplayer_maskを1で初期化して、ループ最後にシフトするほうが好みですね。

このコードだと配列を使わないメリットが少ない気がしますけど。
配列よりメリットがあるのは、排他的論理和を使ってトリガーを抽出するときだと思います。

アバター
せんちゃ
記事: 50
登録日時: 15年前
住所: 江別市東野幌町
連絡を取る:

Re: ビットでフラグを管理する

投稿記事 by せんちゃ » 12年前

ISLeさん
今回はまさにトリガーがほしかった処理だったので、
こんなやり方があるよ!
と教えてもらった感じです。

配列で持つのもビットでやるも、
好みの問題などもありそうですね

ISLe
記事: 2650
登録日時: 15年前

Re: ビットでフラグを管理する

投稿記事 by ISLe » 12年前

例えばゲームパッドのボタンの押下状態(押されているとき1)が各ビットに格納されているとき
btnstat_lastが前回の値で
btnstatが今回の値だとすると
btnstat ^ btnstat_last & btnstat
で押されたボタンのビット(プレストリガー)を取り出せます。
これを配列でやるメリットはないでしょう。

ちなみに
btnstat ^ btnstat_last & btnstat_last
だと離されたボタンのビット(リリーストリガー)を取り出せます。
最後に編集したユーザー ISLe on 2013年1月16日(水) 22:23 [ 編集 1 回目 ]