当たり判定について

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

当たり判定について

#1

投稿記事 by NEX » 15年前

DXライブラリを使ってアイスホッケーゲームを作っております。

徐々にお互いの陣地にあるバーが閉まっていき
時間経過と共にボールが入りにくくなってしまいます。
タッチした方向(初期ボール位置からみて)にボールが飛ぶようになっております。

バーに当たったら移動量を反転させるという処理にしております。
バーに正面から当たればそれらしく見えるのですが
バーの縦?に当たると強制的に座標が修正され見た目が悪くなってしまいます。
当たり判定の座標を無理やり直している所が悪いのですが改善の仕方がわかりません・・・。
──────┐
      │ ←ここに当たった時がおかしい動作をする
──────┘
   ↑ こうあたればそれらしく見えます
   
この当たり判定さえ出来ればほぼ完成なのですが
意図した通りに動いてくれるプログラムが書けません。
添付しましたソースは画像がなくても動作するようにDXライブラリ搭載の描画関数を使っております。
本当にご迷惑をかけて申し訳ないと思うのですが
どなたか回答を頂けないでしょうか?

実際はもっとソースが長いのですが当たり判定の所だけ抽出しました。
なので不具合があったらすみません。

ISLe

Re:当たり判定について

#2

投稿記事 by ISLe » 15年前

バーを四角形で処理するのではなくて、壁のラインで縦と横に分けて処理すると良いです。

次に問題になるのが角に当たった場合です。

1) そのときのパックの座標から適当に振り分ける
2) パックの移動ベクトルの角度の深さで振り分ける
3) パックの移動ベクトルから交差する壁のラインを判断して振り分ける
4) 接触時の接触点とパックの中心との角度から接触後の移動成分を計算で求める

1)
ブロック崩しのバーは真横で弾いても上に戻ります(戻らないタイトルもある)。
ゲーム性重視の割り切り型。
2)
アクションゲームなら不自然さは感じないレベル。
3)
オブジェクトの大きさが考慮されない動きだけど不自然さは感じないレベル。
4)
物理エンジンレベル。ただし丸いパックと直行する壁のラインは極めて単純なモデル。(編集)

現時点でまるまる実装コードを提示することは難しいです。
そのゲームの個性にもなる部分なので試行錯誤してみてください。
画像

NEX

Re:当たり判定について

#3

投稿記事 by NEX » 15年前

回答ありがとうございます。
物理エンジンレベルの物は求めておりません。
見ていて不自然でなければいいレベルの判定を作りたいです。

どこと当たったかわかるような関数を作ってみたのですが
やはり上手く動作しません・・・。

ISLe

Re:当たり判定について

#4

投稿記事 by ISLe » 15年前

「壁のラインで縦と横に分けて」というのはバーに当たったと判定したあとにどこに当たったか判断するという意味ではなくて、バーを構成する壁ごとに分解して別々に当たり判定するという意味です。
だから角(交点)の場合、縦の壁と横の壁に同時に当たることになります。

ところでパックは丸く描画されているのに(パックが内接する)四角で当たり判定が行われているのですが、その点に関しては無視して良いのでしょうか?

> 物理エンジンレベルの物は求めておりません。
> 見ていて不自然でなければいいレベルの判定を作りたいです。

不自然かどうかは結局主観なので最終的な判断をするのはNEXさんです。
NEXさんはどうなって欲しいと考えているのか具体的に教えてくれませんか?

わたしが十数年前にブロック崩しを作ったときはボールがブロックやバーに当たるパターンをすべて方眼紙に描きました。
#上下左右の対象パターンは省けるので正確には1/4。
理想の動きがコーディングできなくても現状で具体的に何がどう不自然で理想としてはどうなって欲しいかを示すことはできると思います。

--追記
当たり判定をきちんと理解したいのであれば、まずは点をひとつ置いて、パックと点の当たり判定を考えてみてください。 画像

NEX

Re:当たり判定について

#5

投稿記事 by NEX » 15年前

回答ありがとうございます。
頼れる人も周りにいないので本当に助かります。

円での当たり判定を行おうとも思ったのですがそこまで
正確な判定でなくても良い気がしたので箱との判定にしております。
円のほうがいいのでしょうか?

箱と直線の当たり判定用の関数を作ってみて
実装してみたのですがジグザグ動いてしまいます。

>>不自然かどうかは結局主観なので最終的な判断をするのはNEXさんです。
>>NEXさんはどうなって欲しいと考えているのか具体的に教えてくれませんか?
お手数おかけします。

具体的に不自然なジグザグにならなければ問題ないです。
不自然さがどのレベルか説明するのが難しいのですが

・当たったら移動量が反転(入射角等を無視して)する。
・当たり判定を貫通して無限に閉じ込められない(同じ場所で判定が続く)
 ※物体が同じ位置周辺で迷う?感じにならない

どうしても明日までに完成させたいのですが難しいでしょうか?

ISLe

Re:当たり判定について

#6

投稿記事 by ISLe » 15年前

なるほどハマって戻ってこなくなるのを防ぎたいのですね。

> ・当たったら移動量が反転(入射角等を無視して)する。

1)バーの四角形を構成するラインをそれぞれ別々に当たり判定します。
2)外側の壁には当たらないので内側の壁2つだけで良いです。
3a)縦に長い壁に当たったらX移動量を反転します。
3b)横に長い壁に当たったらY移動量を反転します。

> ・当たり判定を貫通して無限に閉じ込められない(同じ場所で判定が続く)
>  ※物体が同じ位置周辺で迷う?感じにならない

面が上向きの壁はパックのY移動量が+のときだけ判定する。同様に
面が下向きの壁はパックのY移動量が-のときだけ判定する。
面が左向きの壁はパックのX移動量が+のときだけ判定する。
面が右向きの壁はパックのX移動量が-のときだけ判定する。
↑の条件を加えると閉じ込められることが無くなります。

めり込みはパックの進入角度から適当に補正してください。
重くならなければ気にならないくらい内部的に細かく動かして無視するのが楽です。

NEX

Re:当たり判定について

#7

投稿記事 by NEX » 15年前

回答ありがとうございます。
上のバーだけ移動量の向きごとに判定してみたのですが
当たってなくても当たった判定になっている気がします。
現在のバーの速度だとゴールさせるのが難しいです。

本当に申し訳ないのですが上のバーだけでいいので
私のソースを修正して頂けないでしょうか?
勝手なことを言っているのはわかります・・・。
ただ本当にもうわかりません・・・。

ISLe

Re:当たり判定について

#8

投稿記事 by ISLe » 15年前

//左バーの下
    sx = Gate[0].x1 - (Gate[0].length/2);
    ex = Gate[0].x1 + (Gate[0].length/2);
    sy = (float)Gate[0].y1 + 8;
    ey = (float)Gate[0].y1 + 8;
    if(Medal.Vy < 0 && HitJudgeBoxLine( Medal.Px-20, Medal.Py-20, Medal.Px+20, Medal.Py+20, sx, sy, ex, ey )) Medal.Vy = -Medal.Vy;
    
    //左バーの右
    sx = Gate[0].x1 + (Gate[0].length/2);
    ex = Gate[0].x1 + (Gate[0].length/2);
    sy = (float)Gate[0].y1 - 7;
    ey = (float)Gate[0].y1 + 8;
    if(Medal.Vx < 0 && HitJudgeBoxLine( Medal.Px-20, Medal.Py-20, Medal.Px+20, Medal.Py+20, sx, sy, ex, ey )) Medal.Vx = -Medal.Vx;
という具合いに壁ごとに当たり判定して移動成分を変化させれば良いと思ったんですが…
実際に手を入れてみたら余分な処理がたくさんあって上手く機能しないですね。


パック(メダル)の移動量を毎ループ計算し直しているのが全体の処理を複雑にしています。
最初に打ち出す角度は最初に移動成分を求めた時点で不要です。
反転フラグも必要ありません。
スピードの減衰は移動成分に比率を掛けていくようにしましょう。

あとゲートの座標の基準が中途半端な位置にあって分かりにくく描画位置もずれています。

ISLe

Re:当たり判定について

#9

投稿記事 by ISLe » 15年前

コードを整理して単純なサンプルを作ってみました。
ウインドウ内でマウスの左クリックするとメダルに対してクリックした位置と反対方向にメダルが移動します。

出っ張った角に当たったときの不自然さ対策はしてません。

閉鎖

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