サンプルコードのダウンロード
では、まずサンプルコードをダウンロードし、解凍してください。
私はVisual C++6.0でコンパイルしているので、をお持ちの方はVisual C++でプロジェクトファイルを開いてください(「game_07.dsw」をダブルクリックすれば開けます)。
圧縮ファイルに含まれる「game_07.exe」をダブルクリックし、実行してみてください。
どうでしょう?画面が切り替わり、フルスクリーン化すると思います。
そして、何かキーを押すと、そのキーコードが画面に表示されると思います。
というわけで今回は、キー入力について解説したいと思います。
よくわからない解説
ではサンプルコードを見ていきます。
//----------[ メイン関数 ]---------------------------------------------------------------------- int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow){ <略> #define CMAX 81 //記憶しておく座標の数 #define OSTEP 20 //オプションを配置する間隔 // cx:座標 cy:座標 mv:移動量 float cx[CMAX],cy[CMAX],mv=3.0f; //座標初期化 int i; for(i=0;i<CMAX;i++){ cx[i]=float(320-16); cy[i]=float(240-16); } int angle=0; //サイン、コサインテーブル作成 float fsin[360],fcos[360]; for(i=0;i<360;i++){ fsin[i]=(float)sin(i*3.1415926535/180); fcos[i]=(float)cos(i*3.1415926535/180); } //メインループ while(1){ WaitSet(); //現在の時間(単位:ミリ秒)取得 ClearScreen(lpBack); //バックバッファ初期化 DdTextOut(lpBack,0,0,"↑、↓、→、←で移動 pauseキーで終了",255); angle=-1; //とりあえず角度を-1にしておく //[38]↑ [40]↓ [37]← [39]→ if(keyg[38] && keyg[39]) //右上 angle=45; else ・ ・ ・ <キー入力省略> //angleの値が変わっていたらキャラクタの座標を変更する if(angle!=-1){ //座標を記憶しておく(バックアップ for(i=CMAX-2;i>=0;i--){ cx[i+1]=cx[i]; cy[i+1]=cy[i]; } cx[0]+=fcos[angle]*mv; cy[0]-=fsin[angle]*mv; } //キャラクタ表示 //オプション //後ろ(古い座標)から表示 for(i=CMAX-1;i>0;i-=OSTEP) BltClip(lpBack,(int)cx[i],(int)cy[i],32,32,lpWork,32,0,1); //本体 BltClip(lpBack,(int)cx[0],(int)cy[0],32,32,lpWork,0,0,1); Flip(); //フィリップ Wait(1000/60); //メッセージループへ }
グラディウスのオプションは、本体(自機)の通った跡を遅れて通りますよね?
ですから、こういった処理は、自機の座標をいくつか記憶しておき、古い座標の所へオプションを配置してやればいいのです。
まず、キャラクタ(自機)の座標を配列でいくつか確保してやります。
#define CMAX 81 //記憶しておく座標の数 float cx[CMAX],cy[CMAX];
このとき、一番新しい座標をcx[0],cy[0]とし、一番古い座標をcx[CMAX-1],cy[CMAX-1]とします。
ゲーム中、キー入力があり、自機の座標が変更されようとしたら、cx[0],cy[0]~cx[CMAX-2],cy[CMAX-2]の中身を
cx[1],cy[1]~cx[CMAX-1],cy[CMAX-1]へコピーします(つまり1つ後ろへずらす)。
それで、cx[0],cy[0]の値を変更してやればいいのです。
if(angle!=-1){ //座標を記憶しておく(バックアップ for(i=CMAX-2;i>=0;i--){ cx[i+1]=cx[i]; cy[i+1]=cy[i]; } cx[0]+=fcos[angle]*mv; cy[0]-=fsin[angle]*mv; }
座標を一つ後ろへずらす時、
for(i=0;i<CMAX-1;i++){ cx[i+1]=cx[i]; cy[i+1]=cy[i]; }
こんなふうに前からコピーしてしまうと、cx[0]の値がcx[1]へ、cx[1]の値がcx[2]へ・・・というように
全て同じ値になってしまうので、やめましょう(爆。ちゃんと後ろからコピーしていきましょう。
で、自機の座標跡を作っていったら、次は表示ですね。
#define OSTEP 20 //オプションを配置する間隔 <略> //後ろ(古い座標)から表示 for(i=CMAX-1;i>0;i-=OSTEP) BltClip(lpBack,(int)cx[i],(int)cy[i],32,32,lpWork,32,0,1); //本体 BltClip(lpBack,(int)cx[0],(int)cy[0],32,32,lpWork,0,0,1);
オプション用の画像は自機の座標跡の古い所から表示してやります。
優先度の問題なのですが、先に描いた方が画面の後ろに表示されますよね?
なので、新しい座標の所程、後で描いてやります(自機は一番最後)
上のようなプログラムだと、
80,60,40,20番目の座標へ順番にオプションを配置し0番の座標へ自機を配置しています。