C言語ゲームプログラミング 第7回講座
 

Study C Ver2販売開始のお知らせ

 C言語の勉強や教育用に最適です。
 2004/8/23よりStudy C Ver2の販売を開始しました。
 Study C Ver2の新しい機能については
 こちらをご参照ください。
C言語でゲームプログラマーを目指す方へ
 ■C言語プログラミング講座
 C言語の勉強は、当サイトで一番人気の
 C言語学習塾をご利用ください。


1.キー入力
これまで、C言語学習塾ユーザ専用ページのケーススタディではgetch()とkbhit()関数を使ってキーボードからの入力を行うように説明していました。

ちょっと復習してみると、kbhit()関数は何かキー入力されたかどうかを検知しTRUE(真の値)を返してきます。 kbhit()関数がTRUEを返したとき、getch()関数を使用して何のキーが押されたかを取得します。 getch()関数は、カーソル左キーの場合7、右キーの場合8を返します。

次のプログラムはカーソルの左右キーで画面上のボールを左右に動かすプログラムです。 getch()関数の返す値によってボールのX座標(b_xx)を変化させ新たな位置にボールを描いています。 ボールを描いた位置はbold_xx変数に保持しておき次回別の位置にボールを描く直前に、その位置をfillrect()関数で消去しています。

                                                                               
#include <graph.h>

main()
{
	HBITMAP	hbmp_ball;
	int	b_xx,		//ボールの位置
		bold_xx;	//ボールの旧位置
	unsigned long
		tick;

	gl_openwin(-1, -1, 640, 480, 0);

	hbmp_ball = gl_loadbitmap("ball.bmp");
	if(hbmp_ball == NULL){
		printf("ビットマップファイルが見つかりません.\n");
		exit(0);
	}

	bold_xx = -1;
	b_xx = 320;
	tick = GetTickCount();

	for(;;){
		if(GetTickCount() >= tick && GetTickCount() < tick + 50)
			continue;
		tick = GetTickCount();

		if(kbhit()){
			switch(getch()){
			case 7: //キー入力は左カーソル
				b_xx -= 10;
				//ボールが画面からはみ出さないようにする処理
				if(b_xx < 0)
					b_xx = 0;
				break;
			case 8: //キー入力は右カーソル
				b_xx += 10;
				//ボールが画面からはみ出さないようにする処理
				if(b_xx > 640 - 16)
					b_xx = 640 - 16;
				break;
			}
		}

		if(bold_xx != b_xx){	//ボールの旧位置から移動していれば再描画
			//旧位置(bold_xx)のボールを消去、bold_xxが-1の時(起動直後)は何もしない
			if(bold_xx != -1){
				gl_fillrect(bold_xx, 240, bold_xx + 16, 240 + 16, RGB(0, 0, 0));
			}
			//新しい位置にボールを描く
			gl_drawbitmap(hbmp_ball, b_xx, 240, 16, 16, 0, 0);
			//旧位置(bold_xx)を新しいボールの位置に置き換える
			bold_xx = b_xx;
		}
		gl_refresh();
	}
}

このプログラムを実行してカーソル左右キーを押してみてください。 一件この関数で問題ないように思えますが、下記のようなゲームには不向きな点がいくつかあります。
(1)カーソルキーを押し続けると、一瞬動きが止まった後ボールが動き出します。 これはキーボードのオートリピート機能による動きです。
(2)カーソルキーで何かを動かしながら別のキーでビームを出すような使い方ができません。 (3)ShiftやCtrlキーの検出ができません。




2.キー状態の取得
ゲームに最適な関数としてgl_getkeystate()関数を用意しました。 この関数は、指定したキーが現在押されているかをチェックすることができます。
                                                                               
gl_getkeystate(kc);
kc : チェックしたいキーコードを指定します。
キーコードは'A'〜'Z'(大文字で指定します)、'0'〜'9'やgraph.hインクルードファイルに定義された定数で指定します。
カーソルキーならVK_LEFT、VK_UP、VK_RIGHT、VK_DOWNを使用します。
その他
	スペースキー:VK_SPACE
	Shift:VK_SHIFT
	Ctrl:VK_CONTROL
	ESC:VK_ESCAPE

返り値が負の値の場合、キーが押されているということになります。

例)
gl_getkeystate('A');
Aキーが押されている場合負の値を返します。

gl_getkeystate(VK_LEFT);
左カーソルキーが押されている場合負の値を返します。

gl_getkeystate(VK_SHIFT);
Shiftキーが押されている場合負の値を返します。

gl_getkeystate(VK_ESCAPE);
ESCAキーが押されている場合負の値を返します。

gl_getkeystate()関数を使用して前のプログラムを書き換えます。

                                                                               
#include <graph.h>

main()
{
	HBITMAP	hbmp_ball;
	int	b_xx, bold_xx;
	unsigned long
		tick;

	gl_openwin(-1, -1, 640, 480, 0);

	hbmp_ball = gl_loadbitmap("ball.bmp");
	if(hbmp_ball == NULL){
		printf("ビットマップファイルが見つかりません.\n");
		exit(0);
	}

	bold_xx = -1;
	b_xx = 320;
	tick = GetTickCount();

	for(;;){
		if(GetTickCount() >= tick && GetTickCount() < tick + 50)
			continue;
		tick = GetTickCount();

		//左カーソルキーが押されていれば移動処理を行います。
		if(gl_getkeystate(VK_LEFT) < 0){
			b_xx = b_xx - 10;
			if(b_xx < 0)
				b_xx = 0;
		}
		//右カーソルキーが押されていれば移動処理を行います。
		if(gl_getkeystate(VK_RIGHT) < 0){
			b_xx = b_xx + 10;
			if(b_xx > 640 - 16)
				b_xx = 640 - 16;
		}

		if(bold_xx != b_xx){
			if(bold_xx != -1){
				gl_fillrect(bold_xx, 240, bold_xx + 16, 240 + 16, RGB(0, 0, 0));
			}
			bold_xx = b_xx;
			gl_drawbitmap(hbmp_ball, b_xx, 240, 16, 16, 0, 0);
		}
		gl_refresh();
	}
}

今度のプログラムは、キーを遅続けたとき一瞬とまるといった問題が解消されます。

お問い合わせ先 C言語ゲームプログラミングのトップページに戻る Copyright(C) 2003 潟Iーキッド