ブロック崩しの当たり判定・反射について

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

ブロック崩しの当たり判定・反射について

#1

投稿記事 by Butler » 13年前

現在ブロック崩しを作っているのですが、
ボールとブロックの衝突で少し問題が出て…

ブロックとの当たり判定とその後の反射についてです。

いくつかのブロックが並び、壁となっているところにボールが当たった時
壁にぶつかっただけで、x方向にもy方向にも跳ね返ってしまうんです。

当たり判定はx、yそれぞれで行っていて、
動いた後のボールで判定を行っています。

両方の判定が行われているのはわかるのですが

壁になっているブロックの並びに当たった時、正しい片方のみの判定を行わせるにはどうすればいいのでしょうか。


|↖




|↘

当たり判定そのものが間違っていたら指摘してくださると助かります><

最後に・・・
初めての投稿なので
何か足りない情報があったらそちらの指摘もお願いします!

jay
記事: 314
登録日時: 15年前
住所: 大阪市
連絡を取る:

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

#2

投稿記事 by jay » 13年前

「横から当たった場合には横方向にだけ反射させる」
「縦に当たった場合には縦方向にだけ反射させる」

理屈はこう言うことですね
単に「当たったかどうか」だけでなく「どの方向から当たったのか」を考えるといいと思います



より具体的なアドバイスを求める場合は、ソースコードをペタッと張り付けて下さいな
♪僕たちは まだ森の中 抜け出そう 陽のあたる場所へ

Butler

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

#3

投稿記事 by Butler » 13年前

反射の部分のコードです。
すでに当たり判定は行って、その中に入ってます。

blockx[] blocky[] ブロックのx、y座標
blocksizex[] blocksizey[] ブロックのx、yサイズ
ballx bally ボールのx、y座標
ballpx ballpy ボールのx、y座標への移動量
ballsize ボールのサイズ(直径)
ballspd ボールのスピード(ballpx*ballspdで実際のx移動量)

setiはfor文で使っているカウンターです。

コード:

				 if (blocky[seti]				  >bally+ballsize) ballpy*=-1,bally+= blocky[seti]				    -(bally+ballsize+(ballpy*ballspd));
			else if (blocky[seti]+blocksizey[seti]<bally		 ) ballpy*=-1,bally+=(blocky[seti]+blocksizey[seti])-(bally+		 (ballpy*ballspd));
				 if (blockx[seti]				  >ballx+ballsize) ballpx*=-1,ballx+= blockx[seti]				    -(ballx+ballsize+(ballpx*ballspd));
			else if (blockx[seti]+blocksizex[seti]<ballx		 ) ballpx*=-1,ballx+=(blockx[seti]+blocksizex[seti])-(ballx+		 (ballpx*ballspd));
これと組み合わせて、当たる前のボールの位置も合わせて
判断させればいいということでしょうか?

jay
記事: 314
登録日時: 15年前
住所: 大阪市
連絡を取る:

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

#4

投稿記事 by jay » 13年前

ちょっぴり違いますね
当たる前ではなく、当たった瞬間で考えましょう

以下は参考になりそうなもの、見るかどうかは貴方次第…
http://dixq.net/forum/viewtopic.php?f=3&t=8951
http://hakuhin.jp/as/block.html#BLOCK_05


で、ここからが僕の考えたやり方ですが(上のリンクよく見てないのでもしかしたら被ってるかもですが)
当たった瞬間のボールとブロックの中心点の差を比べてやるやり方はどうでしょう?
例えば当たった瞬間のボールの中心点がブロックの中心点からX方向にマイナス2、Y方向にプラス6だったとします
これだとほぼブロックの中央に下から当たったということになりますよね
だから下方向に反射させる訳です

Butlerさんのコードを元に書くとこんな感じに
下方向の判定だけですが

コード:

//まずは単純に当たったかどうかだけ判定する
if(blocky[seti] > bally+ballsize && blocky[seti]+blocksizey[seti]<bally &&
   blockx[seti] > ballx+ballsize && blockx[seti]+blocksizex[seti]<ballx)
{
	//当たった場合は
	int tx = ballx + (ballsize/2);	//ボールの中心点
	int ty = bally + (ballsize/2);
	int blx = blockx[seti] + (blocksizey[seti]/2);	//ブロックの中心点
	int bly = blocky[seti] + (blocksizey[seti]/2);

	int sx = blx - tx;	//ブロックの中心点から見たボールの座標の差(相対座標)
	int sy = biy - ty;

	//下方向の判定
	//ボールがある程度以上下にあり、且つXの差よりYの差の方が大きい
	if( (sy < (-blocksizey[seti]/4) ) && (abs(sy) > abs(sx)) )
	{
		ballpy*=-1;	//反射させる
		bally+=(blocky[seti]+blocksizey[seti])-(bally+(ballpy*ballspd);	//位置調整
	}
}
絶対値を求めるのにabs関数を使っていますが、もし座標を実数型で管理しているのなら
fabs関数に変えてあげてくださいね

ただこのやり方は結構誤魔化してる感じが強いので
角付近に当たるとちょっと動作が怪しくなるかも…(sxとsyがイコールになる状況を考えるかどうかって事ですね)

あとブロックが正方形であることを前提に書いているので
長方形のブロックを使うならば単純に差だけではなく、差の比率も思慮に入れる必要が出てくると思います
最後に編集したユーザー jay on 2012年8月02日(木) 08:01 [ 編集 1 回目 ]
♪僕たちは まだ森の中 抜け出そう 陽のあたる場所へ

Butler

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

#5

投稿記事 by Butler » 13年前

jayさんありがとうございます!

中心からの差を求めて、その差が小さい方を先に判定させればいい、という方法を使わせてもらいますね!
わかりやすいコードも書いてくださってありがとうございます><

まだまだ未熟でまた聞きにくるかもですが・・・
その時はまたよろしくお願いします!

閉鎖

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