画像(logo)

HOME/[JAVA言語]ブロックパズルの作り方 目次/五日目 当たり判定「底辺」

[JAVA言語 ブロックパズルの作り方]
五日目 当たり判定「底辺」

広告

↓2017年04月19日発売↓

カラー図解 Javaで始めるプログラミング 知識ゼロからの定番言語「超」入門 (ブルーバックス)

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

目次へ戻る

当たり判定

当たり判定のお時間です!今回は底辺の当たり判定とともにブロックを固定するトコロまでをやっていきたいと思います。

底辺の当たり判定

前回作った左右の当たり判定用の関数を少し変えて底辺の当たり判定用関数を作っていきます。

void my_collision_bottom(){
	collision_flag = 0;

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

底辺の当たり判定になるので「y座標+1」の部分を調べれば大丈夫ですね。

ブロック再生成

今回からブロックが固定された後にブロックが再生成されるのでその処理を加えたいと思います。

void my_make_block(){
	if(make_block_flag == 1){
		for(int y=0;y<BLOCK_HEIGHT;y++){
			for(int x=0;x<BLOCK_WIDTH;x++){
				block[y][x] = blocks[y][x];
			}
		}
		make_block_flag = 0;
	}
}

ブロックを作る「my_make_block()」にブロックを生成するかどうかのフラグ「int make_block_flag」を加えました。

「make_block_flag == 1」の時にブロックを作ります。

今回はまだ四角いブロック一種類のみなので何の意味があるのかと思うトコロですがそのへんはもう少し後半にお話しします。

それではこれらを使ってブロックを固定していきます。

ブロック固定の手順

ブロック固定と言われると何か複雑な事をしそうな気がしますが、

1・底辺の当たり判定を調べる

2・当たり判定があれば現在の「block」の状態を「stage」に保存する

3・ブロックの座標を元に戻す

だけで意外と簡単にブロックは固定されます。

「block」を「stage」に保存する

現在の「block」を「stage」に保存する「my_save_block()」です。

void my_save_block(){
	for(int y=0;y<BLOCK_HEIGHT;y++){
		for(int x=0;x<BLOCK_WIDTH;x++){
			stage[block_y + y][block_x + x] += block[y][x];
		}
	}
}

言葉通りそのまま保存しているだけなので特に説明はいらないですね。

ブロックの座標を元に戻す

続いてブロックの座標を元に戻す「my_init_var2()」になります。

void my_init_var2(){
	block_x = 7;
	block_y = 0;
	block_y_count = 0;
	make_block_flag = 1;
}

ブロックの座標を元の位置に戻してあげます。

さきほどのブロック生成用のフラグも初期化します。

あとはこれらを組み合わせるだけです。

ブロック固定

ブロック固定の「my_fix_block()」です。

void my_fix_block(){
	
	my_collision_bottom();

	if(collision_flag != 0){
		my_save_block();
		my_init_var2();
	}
}

1・底辺の当たり判定を調べる

2・当たり判定があれば現在の「block」の状態を「stage」に保存する

3・ブロックの座標を元に戻す

の手順通りにブロックを固めるだけですね!

画像(jb_5_1)

ブロック固定!

「my_fall_block」を変更

この時点で実行しても特に違和感がないので見落としがちですが、このままではブロックを固定した後にも「block_y++」の処理が一度行われるので一つ落ちた状態からブロックが現れてしまいます。

なので「my_fall_block」に少し手を加えます。

void my_fall_block(){
	if(make_block_flag == 0){
		block_y_count += block_speed;
		block_y = (int)(block_y_count / DRAW_BLOCK_WIDTH);
	}
}

ここでさきほどの「make_block_flag」が意味を成します。

ブロック生成中でなければ「block_y++」みたいな感じですね。

これでブロック固定後にブロックが下がってしまう事を防ぐ事ができます。

広告

降下

さきほどの底辺の当たり判定用関数を使ってブロック降下処理も作ります。

if(key.get_down() % 5 == 1){
	my_collision_bottom();
	if(collision_flag == 0){
		block_y++;
		block_y_count = block_y * DRAW_BLOCK_WIDTH;
	}
}

キー入力の「my_move_block()」内、「DOWN」矢印キー下を押した場合の処理です。

事前にキー入力計算のクラス「Key」に矢印キー下を押した場合も加えておきます。

さきほどの「my_collision_bottom();」を使って当たり判定がなければ「block_y++」、

そして「block_y_count」をそこに合わせてあげるように「block_y_count = block_y * DRAW_BLOCK_WIDTH;」と計算します。

ゲームオーバー

ついでにゲームオーバーも作ってしまいます。

ブロックパズルにおいてのゲームオーバーの条件はブロック再生成時にそこにすでにあるブロックと重なってしまった場合なのでまずは重なった場合の当たり判定用関数を作ります。

void my_collision_center(){
	collision_flag = 0;

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

ブロックと重なってしまった場合なのでその場の判定ですね。

それではゲームオーバー判定用の関数を見てみます。

void my_gameover(){
	my_collision_center();

	if(collision_flag != 0){
		gameover_flag = 1;
	}
}

さきほどの関数を使ってゲームオーバー用に用意したフラグ「int gameover_flag」の切り替えをします。

これでゲームオーバーの判定ができるようになりました。

あとは「ゲームループ」にゲームオーバーの条件を加えるだけです。

ゲームループ

今回から「switch」文を使って初期化→ゲームループ→ゲームオーバーそれぞれを場面分けしていきます。

@Override
public void handle(long time){
	gc.clearRect(0,0,640,480);
	key.calc_key_count();

	switch(game_state){
	case 0:
		game_state = 5;
		break;
	case 5:
		my_make_block();
		my_gameover();
		my_move_block();
		my_draw_back();
		my_draw_variable();
		my_draw_block();
		my_draw_stage();
		my_fix_block();
		my_fall_block();

		if(gameover_flag == 1){
			game_state = 10;
		}
		break;
	case 10:
		my_draw_back();
		my_draw_block();
		my_draw_stage();
		my_ed();
		break;
	default:
		break;
	}
}

「int game_state」という場面を表す変数を用意してそれぞれの場面分けをしております。

今回はゲームが始まってゲームオーバーになるまで一方通行ですが、次のステージに行きたい、ゲームオーバーになった時に最初からやり直させたいなどの処理を入れたい時はこの「switch」で分けた場面をもとにもどして再初期化などして対応します。

画像(jb_5_2)

ゲームオーバー!

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

中間ソース4

それでは次回はブロックの種類を増やすのと横一列が揃ったらブロックを消去してみたいと思います。

次回

六日目 ブロック消去

□ページの先頭へ□

□目次へ戻る□

□HOME□

広告

↓2016年06月25日発売↓

新・明解Java入門 (明解シリーズ)

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

↓2017年04月18日発売↓

Java本格入門 ~モダンスタイルによる基礎からオブジェクト指向・実用ライブラリまで

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

↓2017年05月17日発売↓

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

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

↓2017年04月04日発売↓

Java 第2版 入門編 ゼロからはじめるプログラミング (プログラミング学習シリーズ)

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