サンプルコードのダウンロード
では、まずサンプルコードをダウンロードし、解凍してください。
私は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); //メッセージループへ }
解説するまでも無いですね。