画像(logo)

HOME/[C言語コンソール]ブロックパズルの作り方 目次/四日目 当たり判定「壁」

広告

[C言語 コンソール ブロックパズルの作り方]
四日目 当たり判定「壁」

広告

↓2016年02月29日発売↓

12歳からはじめる ゼロからのC言語 ゲームプログラミング教室

目次へ戻る

当たり判定

当たり判定のお時間です!今回は横に移動するのと壁の当たり判定を確認する所までやっていきたいと思います。

キー入力

まずは横に動かすためのキー入力の簡単なプログラムを作ってみます。

実行すると入力待ちの無限ループになりますので矢印キーの左か右を押してください!

#include <stdio.h>
#include <conio.h>

int main(){
	int key;
	int flag = 1;

	while(flag){
		if(_kbhit()){
			key = _getch();
			if(key == 0 || key == 224)key = _getch();
			flag = 0;
		}
	}
	
	switch(key){
	case 0x4b:
		printf("左が押されました!\n");
		break;
	case 0x4d:
		printf("右が押されました!\n");
		break;
	default:
		printf("左右以外が押されました\n");
		break;
	}
	
	return 0;
}

■実行結果■

画像(cb_4_1)

キー入力を確認するためのプログラムです。

矢印キーの「左←」か「右→」を押すと反応するようになってます。

リアルタイム(いつでも)入力

カタチで覚えましょう!

if(_kbhit())key = _getch();

ここでリアルタイムに入力を受け取っております。

キーボードが押されると「if」文の中の関数「_kbhit()」が反応してその後の命令を実行します!キーボードが押されないとそのまま命令を素通りしてしまうので無限ループにしてます。

そして関数「_getch()」でキー入力を受け取って変数「key」に保存します。

ここで普通のキー(アルファベットとか)が押された場合は、「A」→「65」とすぐにキーの文字コードを受け取るのですが、矢印キーは少しちがう受け取り方をします。

矢印キーはまず最初に数字の「0」または「224」を受け取ってからその後に文字コードを受け取ります。(環境によって少し違うかもです。)

なので「key == 0 || key == 224」の時、変数「key」が「0」または「224」の時はもう一度「_getch()」でキーコードを受け取る必要があります。

まとめると

if(_kbhit()){
	key = _getch();
	if(key == 0 || key == 224)key = _getch();
}

こんな感じになりますね!

あとは「switch」文で振り分けてるだけです。

ちなみに矢印キーの16進数コードは「0x4b・左」「0x4d・右」「0x48・上」「0x50・下」になります。

当たり判定

キー入力のやり方がわかったので次は当たり判定です。このままだと壁を突き抜けて、どこまででも行ってしまいます。

広告

固まったブロックや壁を保存「stage」

固まったブロックや壁の状態を保存しているのは「stage[23][18]」でした。

なのでこの「stage[23][18]」と現在のブロック「block[4][4]」を調べれば良さそうです。

void my_collision_left(){
	int x,y;
	
	collision_flag = 0;

	for(y=0;y<BLOCK_HEIGHT;y++){
		for(x=0;x<BLOCK_WIDTH;x++){
			if(block[y][x] != 0){
				if(stage[block_y + y][block_x + (x - 1)] != 0){
					collision_flag = 1;
				}
			}
		}
	}
}

ブロックの左側の当たり判定を調べる「my_collision_left()」です。

当たり判定用のフラグとしてグローバル変数「int collision_flag」を用意してそこに当たり判定の結果を格納します。

そして当たり判定の方法ですが、まずは現在の「block[4][4]」の状態を調べます。

for(y=0;y<BLOCK_HEIGHT;y++){
	for(x=0;x<BLOCK_WIDTH;x++){
		if(block[y][x] != 0){
		}
	}
}

「block[4][4]」が「0」でなければ、つまりそこがブロックならば今度は「stage[23][18]」上の現在のブロックの座標周りを調べれば必要な情報が得られます。

if(stage[block_y + y][block_x + (x - 1)] != 0){
	collision_flag = 1;
}

今回は左側の当たり判定なので「x座標 - 1」の部分を調べれば大丈夫ですね!

同じように右側の当たり判定用関数も作ります。

キー入力に当たり判定を組み込む

あとはキー入力時に当たり判定用関数を組み込むだけですね!

void my_get_key(){
	int key = 0;

	if(_kbhit()){
			
		key = _getch();
		if(key == 0 || key == 224)key = _getch();

		switch(key){
		case 0x4b:
			my_collision_left();
			if(collision_flag == 0){
				block_x--;
			}
			break;
		case 0x4d:
			my_collision_right();
			if(collision_flag == 0){
				block_x++;
			}
			break;
		default:
			break;
		}

	}
}

それぞれのキー入力に合わせて当たり判定用関数を呼び出し「collision_flag」を確認して移動させます。

これで左右の当たり判定ができました。

時間稼ぎ

今回から動かしながら確認していきますので、今までの「stop = _getch()」を外して時間かせぎ用の関数「my_timer()」を加えます。

void my_timer(){
	int x,y;
	for(y=0;y<10000;y++){
		for(x=0;x<10000;x++){
		}
	}
}

これは大量の「for」ループで時間をかせいでいるだけです。コンピューターによって速さがバラバラだと思いますので適当に合わせてください。

あと今はC言語のお遊びプログラムなので時間を稼ぐのにこのようなやり方を使いますが、これはコンピューターにだいぶ悪いやり方なのでほどほどにしておきましょう!

ちなみに他のコンピューター言語はだいたい時間稼ぎ用の関数がありますのでそちらをお使いください!

メイン

メインになります。

int main(){

	my_init_var();

	while(1){
		my_clear_field();
		my_make_block();
		my_get_key();
		my_make_field();
		my_draw_field();
		my_timer();
		my_fall_block();

		if(block_y > 17)break;
	}
		
	return 0;
}

「stop = _getch()」を外して「my_timer()」を加えました。

画像(cb_4_2)

左右の壁を確認しながら落下します!

ここまでの中間ソースになります。

中間ソース3

それでは次回は底辺の当たり判定をつけたいと思います。

次回

五日目 当たり判定「底辺」

□ページの先頭へ□

□目次へ戻る□

□HOME□

広告

↓2017年06月16日発売↓

やさしいC 第5版 (「やさしい」シリーズ)

新品価格
¥2,700から
(2017/5/1 13:05時点)

↓2014年08月09日発売↓

新・明解C言語 入門編 (明解シリーズ)

新品価格
¥2,484から
(2017/5/1 13:08時点)

↓2016年02月20日発売↓

新・解きながら学ぶC言語

新品価格
¥2,160から
(2017/5/1 13:10時点)

↓2017年02月11日発売↓

C言語プログラミング基本例題88 88

新品価格
¥3,024から
(2017/5/1 13:12時点)

↓2016年12月15日発売↓

Cの絵本 第2版 C言語が好きになる新しい9つの扉

新品価格
¥1,490から
(2017/5/1 13:13時点)

↓2017年02月08日発売↓

新・明解C言語で学ぶアルゴリズムとデータ構造 (明解シリーズ)

新品価格
¥2,700から
(2017/5/1 13:15時点)