ブロック崩しの当り判定について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
スライム

ブロック崩しの当り判定について

#1

投稿記事 by スライム » 14年前

初めまして。
今初心者ながらブロック崩しを作っているのですが、うまくいかない部分があります。
それは、バーとボールの当り判定についてです。

ボールがバーの上に来たとき、真ん中付近はちゃんと跳ね返ってくれるのですが、
ボールがバーの角の付近(角ではない)にくると跳ね返る場所と跳ね返らずにすり抜ける場所が出てくるのです。
これを角以外はとりあえず全て跳ね返るようにしたいのですが、どうしたらいいのでしょうか。
バーとボールの制御のコードです。

コード:

void Ber(){
	//動きを計算
		if(ber_x < 635-160 && Keyboard_Get(KEY_INPUT_RIGHT) >= 1 ){
			ber_x+=5;
		}
		if(ber_x > 5 && Keyboard_Get(KEY_INPUT_LEFT) >= 1){
			ber_x-=5;
		}
	//描画
	DrawGraph(ber_x,ber_y,ber_image,true);
	DrawFormatString(10,10,GetColor(255,255,255),"(%d.%d)",ber_x,ber_y);
}

void Ball(){
	if(Keyboard_Get(KEY_INPUT_SPACE) == 1) shoot_flag = 1;	//スペースが押されたら発射

	if(shoot_flag == 1){
		ball_x += ball_x_move;
		ball_y += ball_y_move;

		if(ball_x + ball_x_size >= width || ball_x <= 0) ball_x_move *= -1;	//左右の壁に当たった時

		if(ball_y <= 0) ball_y_move *= -1;	//上の壁に当たった時

		if(ball_y + ball_y_size == ber_y){	//ボールのバーの横の線上に来たとき
			for(int i = 0; i<=ball_x_size; i++){
				for(int j = 0; j<=ber_x_size; j++){
					if(ball_x + i == ber_x + j){	//かつバーの上にあるとき
						ball_y_move *= -1;
						test_x = ball_x;
						test_y = ball_y;
						break;
					}
				}
			}
		}
		if(ball_x == ber_x + ber_x_size){	//ボールがバーの縦の線上に来たとき
			for(int i = 0;i<=ball_y_size; i++){
				for(int j = 0; j<=ber_y_size; j++){
					if(ball_y + i == ber_y + j){	//かつバーの横にあるとき
						ball_x_move *= -1;
						break;
					}
				}
			}
		}
		if(ball_y + ball_y_size >= height + 100){	//下に落ちた時
			//ボールを初期位置に戻す
			shoot_flag = 0;
			ball_x = 320-20/2;
			ball_y = 450-20;
			ball_x_move = 5;
			ball_y_move = -5;
		}
	}
	DrawGraph(ball_x,ball_y,ball_image,true);
	DrawFormatString(10,25,GetColor(255,255,255),"(%d.%d)",ball_x,ball_y);
	DrawFormatString(10,40,GetColor(255,255,255),"(%d.%d)",test_x,test_y);
}
なおテスト用にバーとボールの座標、バーにボールが当たった時のボールの座標を上から順に画面に表示させています。

C言語はまだ基本の基本くらいしか分かっていません。
どうかよろしくお願いします!

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: ブロック崩しの当り判定について

#2

投稿記事 by softya(ソフト屋) » 14年前

この条件を満たさずに下にすり抜けるのでは?必ず等しくなりますか?
if(ball_y + ball_y_size == ber_y){ //ボールのバーの横の線上に来たとき
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

non
記事: 1097
登録日時: 15年前

Re: ブロック崩しの当り判定について

#3

投稿記事 by non » 14年前

範囲で考えないと、ものすごく無駄なループになっている。
non

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: ブロック崩しの当り判定について

#4

投稿記事 by softya(ソフト屋) » 14年前

ボールをボールより少し小さな四角と仮定して、矩形を用いた当たり判定で処理するとある程度すり抜け防止は出来ます。
「当たり判定 - ゲームプログラミングWiki」
http://www.c3.club.kyutech.ac.jp/gamewi ... ontent_1_4
ただ、これでもボールのスピードが上がり過ぎると通り抜けます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

スライム

Re: ブロック崩しの当り判定について

#5

投稿記事 by スライム » 14年前

softya(ソフト屋) さんが書きました:この条件を満たさずに下にすり抜けるのでは?必ず等しくなりますか?
if(ball_y + ball_y_size == ber_y){ //ボールのバーの横の線上に来たとき
ボールがどの位置に来ても、落ちてきているのでバーのX軸とは必ず一致すると考えたのですが・・・
softya(ソフト屋) さんが書きました:ボールをボールより少し小さな四角と仮定して、矩形を用いた当たり判定で処理するとある程度すり抜け防止は出来ます。
「当たり判定 - ゲームプログラミングWiki」
http://www.c3.club.kyutech.ac.jp/gamewi ... ontent_1_4
ただ、これでもボールのスピードが上がり過ぎると通り抜けます。
なるほど、そういう方法もあるんですね。
サイトもありがとうございます。参考にします!
non さんが書きました:範囲で考えないと、ものすごく無駄なループになっている。
そうですね。範囲にすると簡単に書けますね・・・
ありがとうございます。

non
記事: 1097
登録日時: 15年前

Re: ブロック崩しの当り判定について

#6

投稿記事 by non » 14年前

スライム さんが書きました:ボールがどの位置に来ても、落ちてきているのでバーのX軸とは必ず一致すると考えたのですが・・・
ball_y += ball_y_move;
なので、ball_y_moveが1なら大丈夫かもしれない。
non

スライム

Re: ブロック崩しの当り判定について

#7

投稿記事 by スライム » 14年前

non さんが書きました: ball_y += ball_y_move;
なので、ball_y_moveが1なら大丈夫かもしれない。
速度はいろいろ変えてもだめでしたが、ループをやめて

コード:

if(ball_y + ball_y_size == ber_y){	//ボールのバーの横の線上に来たとき
	if((ball_x > ber_x) && (ball_x < ber_x + ber_x_size)) ball_y_move *= -1;
	else if((ball_x + ball_x_size > ber_x) && (ball_x + ball_x_size < ber_x + ber_x_size)) ball_y_move *= -1;
}
と直したところ、無事自然な反射をするようになりました!
たくさんのアドバイスありがとうございました!

閉鎖

“C言語何でも質問掲示板” へ戻る