質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

Q&A

解決済

1回答

540閲覧

物質判定方法ゲーム理論

rsetuhbcln

総合スコア13

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

0グッド

0クリップ

投稿2017/12/07 05:11

編集2018/02/06 03:01

いつもありがとうございます。
当たり判定についてなのですが、現在、ボールをカゴに入れるゲームを作成しています。
そこで、ボールがカゴの上辺以外に当たり判定をつけ、反射させたいと思っているのですが、なかなかうまくいかず、カゴに当たると反射してしまいます。
なにか良い方法はありませんか?よろしくお願いします。

namespace _1108_ボール_斜

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Bongo

2017/12/07 06:45

当たり判定はカゴのピクチャーボックスの形(単なる長方形)でいいのでしょうか?それともカゴに合った形(たとえば半球状)の方がいいでしょうか。後者の場合、カゴの画像もご提示いただけると方法を検討しやすいかと思います。また、ボールがカゴに入った後(カゴ上辺を通過した後)のボールの動きをどうしたいかも要検討でしょうね。場合によっては、カゴ内壁との当たり判定をどうするか考えなくてはならないかもしれません。
rsetuhbcln

2017/12/07 08:05

返信ありがとうございます 当たり判定は単なる長方形で大丈夫です。またボールがカゴに入ったらボールを初期位置に戻すように考えています。
Bongo

2017/12/07 10:33

なるほど、それならだいぶシンプルになりそうですね。もう一つ確認事項として、ボールの大きさは考慮するべきでしょうか?今のご質問者さんのコードですと、ボールのふちではなく、中心点がカゴ領域に入った時に「当たった」と判定されているものと想像します。現状通り、ボールの大きさを考慮しなくてよいならさらにシンプルに作れそうですが...
rsetuhbcln

2017/12/07 11:00

ボールの大きさを考慮していなかったので、ボールの半径を条件に加えました。
guest

回答1

0

ベストアンサー

こんな方針でどうでしょう。なお、この方法でやる場合、ご質問者さんの現在のコードballPos_x += vx * Math.Cos(deg * (Math.PI / 180));ballPos_y += vy * Math.Sin(deg * (Math.PI / 180)) + g * t;のような「毎回初速度と経過時間から現在の速度を求め、ボールの位置に加算する」方式はちょっと相性が悪いかと思います(跳ね返り後のボールの動きをご想像いただくとお分かりかと思いますが、跳ね返った後は軌道が変わるので、発射時の式のままではおかしな動きになってしまうはずです...あえてやるとしたら、「跳ね返り地点から跳ね返り方向へ跳ね返り速度でボールを再発射する」イメージで実装することになるでしょうか)。それよりも、

  • ボールの位置のほかに、「ボールの現在速度」を保持する変数を追加する(仮にballVel_xballVel_yとする)
  • ボール発射時に現在速度に初速度を代入する...ballVel_x = vx * Math.Cos(deg * (Math.PI / 180));ballVel_y = vy * Math.Sin(deg * (Math.PI / 180));
  • Update内では「現在速度に加速度を加算」してから「現在位置に現在速度を加算」する...ballVel_y += g;ballPos_x += ballVel_x;ballPos_y += ballVel_y;

といった方式の方が跳ね返りを実装しやすいように思います。

当たり判定ですが、まず、ボールの中心が下図1~9のどのエリアにいるか特定し、エリアに応じて判定方法を分けることにします。どのエリアにいるかはボール座標とピクチャーボックスの4辺の位置L、T、R、Bを比較すればいいでしょう。

イメージ説明

そして、ボールのエリアに応じてピクチャーボックスとの衝突判定を行い、併せてボールを跳ね返らせるのに使う、衝突面の法線ベクトルを求めます。各エリアごとに見てみると...

  1. 衝突する可能性があるのはa点。ボール中心とa点の距離を求め、ボール半径以下なら衝突とする。法線は(ボール中心座標 - a点座標) / ボール中心とa点の距離。
  2. 衝突する可能性があるのは辺ab。T - ボール座標Yがボール半径以下なら衝突とする。法線は(0、-1)。
  3. 衝突する可能性があるのはb点。ボール中心とb点の距離を求め、ボール半径以下なら衝突とする。法線は(ボール中心座標 - b点座標) / ボール中心とb点の距離。
  4. 衝突する可能性があるのは辺bd。ボール座標X - Rがボール半径以下なら衝突とする。法線は(1、0)。
  5. 衝突する可能性があるのはd点。ボール中心とd点の距離を求め、ボール半径以下なら衝突とする。法線は(ボール中心座標 - d点座標) / ボール中心とd点の距離。
  6. 衝突する可能性があるのは辺cd。ボール座標Y - Bがボール半径以下なら衝突とする。法線は(0、1)。
  7. 衝突する可能性があるのはc点。ボール中心とc点の距離を求め、ボール半径以下なら衝突とする。法線は(ボール中心座標 - c点座標) / ボール中心とc点の距離。
  8. 衝突する可能性があるのは辺ac。L - ボール座標Xがボール半径以下なら衝突とする。法線は(-1、0)。
  9. ボールが速すぎると、ボールの縁で衝突判定されることなくこのエリアに来てしまうと予想される。このケースに対処する方法の一例としては、このエリアに来た場合はボールを1フレーム前の位置に戻し、短い間隔で少しずつ移動させてみて当たり判定を行うという手が考えられる。

ここまででボールがピクチャーボックスのどの辺、あるいはどの角に当たったか、そして衝突面の法線が分かるので、後は...

  • 辺abに当たったケースでは「ボールがカゴに入った」と判定する
  • それ以外では跳ね返り処理を行う...C# - 当たり判定 反射するようにするには(103369)|teratailでozwkさんのおっしゃった方法が有効でしょう。「ボールの現在速度ベクトルと法線ベクトルの内積を求める」→「現在速度ベクトル - (2 * 内積 * 法線ベクトル)を新たな現在速度ベクトルとする」でいけるはずです。

こんな感じでいかがでしょうか...?どの方向から当たったかの場合分けがややこしいかもしれませんが、紙に図を描いたりして動きをイメージしてみるのもいいんじゃないかと思います。

投稿2017/12/07 15:14

Bongo

総合スコア10807

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rsetuhbcln

2017/12/08 02:14

詳しく説明していただきありがとうございます! ちょっと難しそうですが、やってみたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問