サンプルコードのダウンロード

では、まずサンプルコードをダウンロードし、解凍してください。
私はVisual C++6.0でコンパイルしているので、お持ちの方はVisual C++でプロジェクトファイルを開いてください(「game_08.dsw」をダブルクリックすれば開けます)。
圧縮ファイルに含まれる「game_08.exe」をダブルクリックし、実行してみてください。
どうでしょう?画面が切り替わり、フルスクリーン化すると思います。
そして、何かキーを押すと、そのキーコードが画面に表示されると思います。
というわけで今回は、キー入力について解説したいと思います。

二次元座標同士の当たり判定


右の図のように、座標上に2つの長方形が存在したとします。
ここで、この2つの物体(長方形)が重なっているか(当たっているか)を調べるときに、次のような式をよく使います。

if(ax2<bx1 || ax1>bx2 || ay1<by2 || ay2>by1)
	当たっていない
else
	当たっている

ただ、例によって(?)数学上の座標とパソコンのディスプレイの座標ではY軸の向きが逆なので、

if(ax2<bx1 || ax1>bx2 || ay1>by2 || ay2<by1)
	当たっていない
else
	当たっている

これが正しい式となります。まぁ、当たった時の判定だけしたいのならば、「!」を使えば直ぐに出来ますね。

if(!(ax2<bx1 || ax1>bx2 || ay1>by2 || ay2<by1))
	当たっている

実際にゲームに使用する場合は、キャラクターの全体もしくは、その一部を当たり判定とし、その部分を長方形として扱い、上の式へ代入します。
ただ、この方法はシューティングゲーム等のような、「あまり精度にはこだわらないから速度の速い方法がいい」という場合に使用してください。

レッツプログラミング

ではサンプルコードを見ていきます。

今回は、「第3回 キー入力によって複数のキャラクタを動かす」の最後の方へちょこっと加え、2匹のスライムが重なった(当たった)時にそのメッセージを表示するようにします。

//----------[ メイン関数 ]----------------------------------------------------------------------
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow){
	
	<略>

	//座標
	int cx[2]={160-16,480-16},cy[2]={240-16,240-16};
	
	//キーテーブル
	unsigned char key_up[2]={38,104},key_down[2]={40,98},
		key_left[2]={37,100},key_right[2]={39,102};
	
	//その他の変数
	int i,mv=3;

	//メインループ
	while(1){
		WaitSet();			//現在の時間(単位:ミリ秒)取得
		ClearScreen(lpBack);		//バックバッファ初期化
		DdTextOut(lpBack,0,0,"カーソルキー、テンキー(4,6,8,2)で移動 pauseキーで終了",255);

		for(i=0;i<2;i++){
			//キャラクター移動
			if(keyg[key_up[i]])	//↑
				cy[i]-=mv;
			else
			if(keyg[key_down[i]])	//↓
				cy[i]+=mv;
			else
			if(keyg[key_left[i]])	//←
				cx[i]-=mv;
			else
			if(keyg[key_right[i]])	//→
				cx[i]+=mv;
			
			//キャラクタ表示
			BltClip(lpBack,cx[i],cy[i],32,32,lpWork,32*i,0,1);
		}

		//当たり判定
		if(!(cx[0]>cx[1]+31 || cx[0]+31<cx[1] || cy[0]+31<cy[1] || cy[0]>cy[1]+31))
			DdTextOut(lpBack,0,16,"当たっている",255);
		
		
		Flip();					//フィリップ
		Wait(1000/60);				//メッセージループへ
	}

解説するまでも無いですね。

記事検索

アーカイブ