オブジェクト指向でボールの衝突を実現する方法

このQ&Aのポイント
  • オブジェクト指向でボールの衝突を実現するためには、衝突時点で全てのボールオブジェクトを持っている必要があります。
  • しかし、この方法では処理が遅くなる可能性があるため、他の案を模索する必要があります。
  • クリックごとにボールオブジェクトをリストに追加し、衝突判定の際にそのリストを渡すという方法も考えられます。
回答を見る
  • ベストアンサー

オブジェクト指向 ボールの衝突

こんにちは。javaをはじめて3ヶ月くらいなのですが、オブジェクト指向でうまくプログラムを書くことができません。オブジェクト指向の理解のために、簡単なプログラムを作っていて疑問がわきました。 JPanel上をクリックすると、ボールが発生して動くプログラムをつくっています。クラスBallをつくり、クリック時にインスタンス化されます。そのときボールの発生位置や、初速度が乱数で決まるようにしました。 ここで、ボールとボールが接したときに跳ね返るようにしたいのですが、各Ballオブジェクトは衝突時点における全てのBallオブジェクトを持っていなければならないのでしょうか?(クリックするごとにArrayListなどにBallオブジェクトをいれて、各ボールの衝突判定のときにそのArrayListを渡す) でもこれだと、処理が遅くなってしまいそうで、心配なのですが、他にいい案はないでしょうか?

  • koun
  • お礼率37% (81/216)
  • Java
  • 回答数4
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
  • mpro-gram
  • ベストアンサー率74% (170/228)
回答No.4

No2で回答した者です。 「仮想空間」について、既にNo3回答者様のご回答が付いていますが、view と 内部ロジックの分離(独立部品化)目的です。 いまのところ、2次元平面空間でJPanelに全空間表示している状態と思うので、分離のイメージが湧かないのかもしれませんが、ボール空間の一部のみ切り取ってスクリーン(JPanel)に投影というように考えるとより具体的イメージになるかとおもいます。ボール位置情報をintで保持するかdoubleにするかは、仮想空間側で決める事項となります。 全体を表示するのか、ズームしてどこか一部を表示するのかといったロジックを、座標変換ロジックとして、仮想空間クラス側のメソッドに組み込んでやれば、JPanel側は、どの領域を表示したいかのデータを引数で渡してメソッドを呼び出し、またはsetterメソッドで環境データ設定のようなことをしてから、投影後画像作成メソッドを呼び出して、投影後画像を取り出すといったことができます。 2次元から3次元への拡張時も、呼び出し用メソッド名や引数が同じになるように作っておけば、仮想空間クラスを変更してすげ替えるだけで、JPanel側の変更はごくわずかとなります。 この仮想空間クラス拡張をも考えると、インターフェースで、表示画像取り出しメソッド名を宣言して、統一するといったことをしておくとよりよいでしょう。 しかし、いっぺんにやろうとしても、すぐには動くものにならないので、とりあえずJPanelに全部組み込んで、まずは動くものを作ってみてもよいでしょう。 いろいろな部品の動作原理が解ってきたら、上記のことをもう一度思い出してクラスを分解していくと、こういう作りをすると拡張(変更)が楽なのかといったことが解ってくると思います。ここまでくれば、デザインパターンを勉強するとより洗練されたプログラムになっていくでしょう。 私も、レイトレーシングプログラムを作ったときに、3-4回ほどクラス構成全部作り換えてようやくMVCの基本を理解できたかなと思っています。

その他の回答 (3)

  • s-gate
  • ベストアンサー率12% (1/8)
回答No.3

こんにちは。 オブジェクト指向プログラミングの目的の一つは、プログラムをオブジェクトというパーツに分け、それぞれを独立性の高い部品として設計して変更やメンテナンスを容易にすることだと私は理解しています。 今回のケースで既に前の回答者様が仰っているように、ボールクラスと当たり判定を行うクラスを分けた方が良いというアドバイスは、まさにこの目的のためです。 ボールクラス自体をいじらなくても当たり判定の処理を独立して変更することができますし、仮にボール以外のものを同じようにパネル上で動かしたい場合も、その物体のクラスのみを設計するだけで当たり判定クラスは流用できるかもしれません。 さらに補足でご質問になっている、表示系座標と仮想座標の分離についてもこの目的のためと言えます。 JPanelの座標を直接使用している場合は、他の環境に移植する場合には何らかの変更をボールクラス自体に施す必要があるかもしれません。 しかし、ボールクラスが仮想空間座標を前提に設計されていれば、JPanel以外に表示させたい場合にもボールクラスそのものを変更する必要はなくなり、部品としての独立性を保てます。

koun
質問者

お礼

回答ありがとうございます。なんとなく理解してきました。 ボール以外のものもパネル上で動かすことを前もって考える場合には、描画物クラスという抽象クラスをボールクラスが継承して、判定クラスが描画物クラスを扱うようにすれば、判定クラスを変更しなくても、新しい描画物の種類を増やしていけますね。 また、仮想座標は、他の環境に移植する場合に、仮想座標とその環境のインターフェースだけを考えればいいようにするためのものなんですね。 つまりクラスとクラスのインターフェースを簡潔にして、クラスごとの独立性を高めるというのがオブジェクト指向の目的なんでしょうか。

  • mpro-gram
  • ベストアンサー率74% (170/228)
回答No.2

各ボール用クラスは、それぞれに固有のデータを持たせるだけで、他のことまで関知させない方が、よいでしょう。 ボール間の衝突判定は、ボール全部とボールの存在環境についての情報を握るクラスが行うようにします。 つまり、ArryListのインスタンスを保持するクラスに、各ボール間の衝突判定メソッドを組み込んで、ボールの移動方向や位置変更などを行わせます、画面の端へ行ったときの処理もここで組み込めます。 衝突判定は、各ボールから他のボールを全部リストすると2重計算になるので、既に計算した組は計算しないように組みます。2つの衝突だけ考えればいいなら、2重ループで、内部ループは、自分の番号より後方をみるだけでいいはず。3重衝突を考えると面倒になるのでとりあえず、2個組での衝突だけで考えた方がよいでしょう。 ボール全部についての情報を握るクラスは、JPanelではなく、仮想空間オブジェクトとして、別にクラスを作成すると、表示用JPanelとボール仮想空間での移動ロジックとの分離ができます。 クリックのたびに、呼び出すのは、仮想空間インスタンスが持つメソッドで、新規ボール登録メソッドと衝突判定メソッドを呼び出し、さらに表示用メソッド呼び出し。 移動での表示変更はThreadかTimer制御かな?このインスタンスを、仮想空間インスタンスと別に持つか、仮想空間インスタンス内に保持させるかどうかは、全体構成とのかねあいで決めてください。表示制御メソッド呼び出しのしやすさでは、表示用クラスの内部クラスで定義してもいいかも? 移動時の表示変更については、TimerTask().run()などから、仮想空間クラスの衝突判定メソッドを呼び出して、現在のボール情報を元に移動計算と内部データ更新を行う。その後、表示用メソッド呼び出しの手順。 概略こんな感じで、Object指向&MVC&UML的構成になると思いますけど解りますでしょうか?

koun
質問者

補足

回答ありがとうございます。独学なので、いろいろと勉強になります。 ArrayListを保持するクラスが衝突判定するということと、衝突判定時のループのさせ方は理解できました。 >表示用JPanelとボール仮想空間での移動ロジックとの分離ができます。 という部分についてなのですが、これは、どういうことなのでしょうか? 仮想空間というのは、例えば、ボールが位置座標をintではなくdoubleで持つことができるようにするためのものですか?表示用クラスの表示メソッドで仮想空間の座標系から表示用クラスの座標系に座標変換するということでしょうか?

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

n個のボールがあれば n(n-1)/2回の衝突判定は必要なので (状況によって減ることはあるが最悪これを覚悟しなきゃならない) それについてはあきらめるしかない. でなんだけど, 「各Ballオブジェクトは衝突時点における全てのBallオブジェクトを持っていなければならないのでしょうか」がどういうことなのか, よくわかんない. そもそも「すべてのボールの情報を記憶する」クラスは存在するはずなので, そいつが衝突判定をすればいいだけではないんだろうか. カッコ内の「クリックするごとにArrayListなどにBallオブジェクトをいれて、各ボールの衝突判定のときにそのArrayListを渡す」というのも, 「誰が ArrayList などを持っているのか」「誰が誰にその ArrayList などを渡すのか」が明確じゃないので, 何とも言えない.

koun
質問者

お礼

回答ありがとうございます。ボールクラスのメソッドで衝突判定しちゃってました。衝突判定するクラスをつくって、そのクラスがボール全体の情報を持ち、衝突判定するようにすればいいんですね。

関連するQ&A

  • オブジェクト指向

    Javaプログラミングを少し勉強し始めました。 そこで、オブジェクト指向という言葉が出てきました。 オブジェクトを作る利点というか意味はどのようなところにあるのでしょうか? 比較的簡単なプログラムなら、変数とメソッドで表示できると思うのですが・・。 ・コードが読みやすくなる ・実行速度が速くなる などの利点があるのでしょうか? なるべく分かりやすく解説してもらえればと思います。

    • ベストアンサー
    • Java
  • Javaにおけるオブジェクト指向とは?

    現在Javaを勉強しております。 以前はC言語を勉強しておたのですが、 JavaとCの違いにおいてJavaの特徴としてオブジェクト指向と習いました。 しかしいまいちこのオブジェクト指向を理解できません。 プログラムを一つのまとまりとして考えるというのはどういうことなのでしょうか? 確かにJavaはC言語とは違いいくつかのプログラムからできている (はず?見当違いだったらすみません) C言語が一つの大きなプログラムでできているとすると、 Javaは細かいプログラムの集合体であると私は考えていました。 この細かいプログラムの集合体というのがオブジェクト指向なのでしょうか? 全くの見当違いだったらすみません。 よろしくお願いします。 

    • ベストアンサー
    • Java
  • オブジェクト指向の特徴

    プログラミングにおいて Java言語などのオブジェクト指向とは 「クラス(設計図)からインスタンス(実体)を量産できる。」がオブジェクト指向ではないプログラミング言語との決定的な違いなのでしょうか? またオブジェクト指向とオブジェクト指向ではない言語の決定的な違いや 実際に実務において経験した感覚的な違いなどがあれば教えてください。 インターネットに乗っていない些細なことでも構いません。

    • ベストアンサー
    • Java
  • オブジェクト指向が理解できません 教えてください

    現在Javaを勉強しているのですが、 Javaに限らず最近のプログラムの特徴であるオブジェクト指向がよくわかりません。 C言語も学んでいたので少しは知識はあります。 以下は私の解釈です。 C言語は関数の集まったものがいわゆる私たちが作るプログラムで、 作ったプログラムはそれ単体で機能する。 それに比べてオブジェクト指向を用いたプログラムでは、 オブジェクトからクラスが生成、このクラスが一つのプログラムとなる。 クラスのプログラムをいくつも集めたものが最終的なソフトとなる。 Cだとミスを一か所直すと他のところを直す羽目になるかもしれませんが、 オブジェクト指向においてはミスをオブジェクト単位で修正するので、 他のオブジェクトへの影響度は少ない。 よってオブジェクト指向の方が拡張・修正などでも優れている。 こんな感じに解釈したのですがどうでしょうか? オブジェクト指向では最終的なプログラムソフトはオブジェクトの集合体によって構成されているため、オブジェクト指向=オブジェクト中心の考えと言えるのでしょうか。

  • オブジェクト指向に関して。

    Javaの解説本を読んでオブジェクト指向プログラミングという物があることをしりました。その本には「オブジェクトはデータとそのデータを扱うための機能を持っている。この機能はメソッドと呼ぶ。クラスは設計図のような物で変数とメソッドから構成されている。設計図を実際に形にした物がインスタンスである。」と書いてありました。私はオブジェクト=クラスのような感じがしたのですが、実際のところオブジェクト=クラスでいいのでしょうか?  また、友人に話したところ、オブジェクト指向はサブルーチンに似ているといっていました。私はプログラミングの知識が全くないのでサブルーチンという物が何なのかわからないのですが、サブルーチンとオブジェクト指向の考え方は違うような気がするのです。友人に説明して納得させるにはどうしたら良いのでしょうか? ぜひ、力を課してください。

  • オブジェクト指向、理解しやすい?

     最近、Javaの解説書や解説サイトを見ていて、しばしば、「Javaは完全なオブジェクト指向だから理解しやすい」といった記述を見かけます。(「プログラムが見やすくなる」とかではなく)  Javaに限った話ではないのですが、個人的に、オブジェクト指向の概念は、プログラミング初心者の最大の関門ではないかと勝手に思っています。僕はPHPから入ったのですが、ある程度基本事項をマスターした後も、オブジェクト指向だけは長い間苦手としてきました。(最近やっと慣れてきたところです。)  そこで伺いたいのですが、最初にやったプログラミング言語がオブジェクト指向だったという方、オブジェクト指向の概念は、 1.わかりやすかった 2.そこでつまずいた 3.特に意識せずに通り過ぎた 4.その他 いずれでしょうか? ※最初にJavaについて書きましたが、これはただの例なので、オブジェクト指向言語全般についての質問であるととらえてください。

  • オブジェクト指向の教え方

    新入社員にJavaを教えているところなのですが、オブジェクト指向プログラミングをどのように教えていいか困っています。 全員がC言語研修を受講済みで、さらにJava言語も、継承やオーバーロード、例外まで一通り教えて、一応理解しています。 そこで、次のレベルとして、C言語風のプログラミング(「プログラム=関数の集まり」の考え方)から、オブジェクト指向(「プログラム=オブジェクトの集まり」の考え方)に意識改革させたいところです。 問題領域をオブジェクトの集まりとしてとらえ、そこからクラスを抽出していく、という説明がよくありますが、 「何をオブジェクトにするのか」「どのようにクラスを抽出したらいいのか」の部分を詳しく教えたいのですが、どのように説明したらいいでしょうか。また、参考になるWebサイトなどありませんでしょうか? 自分が普段作るときは、ほぼ「勘」でクラス設計していますので、それでは教えられなくて困っています。よろしくお願いします。

    • ベストアンサー
    • Java
  • オブジェクト指向でないプログラムってどんなのですか

    オブジェクト指向はそれぞれのインスタンスに属性とオペレーションがあるのがわかりましたが、そうでないプログラムの仕組みなんてありえるんですか? Aを動かす為にBを押したらCがAを動かしてくれたって物を作ろうとしたときにそれぞれをオブジェクトとする以外に方法は無いような気がしますが。 ものを作るときって部品を組み立てたり作用させたりすると思うので、それ以外の組み立て方法ってどうやるのでしょうか?

  • ボールの衝突 (VB.net)

    プログラム初心者です。 VB.netでの質問です。 例えば,100個のボール(の絵をしたPictureBox)を たくさん配置して適当な規則で動かせます。 (ここまではできます) 次にいずれかの2つ(少なくとも2つ)のボールが 衝突した(距離がある値より小さくなった)ときに,互いに跳ね返る様にしたいとき, どのようなコードを書けばよいのでしょうか? 例えば配列を使って, 0.1秒に一回(timerつかって) for i=1 to 100 for j=1 to 100-i if (i)番目のボールが(i+j)番目のボールと衝突 している then 跳ね返る    end if next next なんてことやったら無駄が多すぎますよね? なんか全てのボールに同一の名前をつけて, 1つの判定で全判定したことにするようには できないでしょうか? 無理でしたら,せめてもう少し無駄のない方法 を教えてください。お願いします。

  • イベントドリブンとオブジェクト指向

    現役S.E.です。イベントドリブンとオブジェクト指向のことを説明する必要に迫られています。しかし、私自身知識が混乱してしまい、説明に自信がないので教えてください。 オブジェクト指向は、構造化プログラミングに変わって登場してきた考え方ですよね。クラスを設計してイベントやプロパティ、メソッドを実装してインスタンスを派生していくプログラミング方法であると認識しています。 それから、イベントドリブンはマウスでのクリックとかキーの押下などのイベントに応じて、様々なアクションを起こすという考え方だと認識しています。 それで、ちょっと考えるとイベントドリブンを実現するためには、アクションやメソッドがないと動かせないと思うので、オブジェクト指向でないと実現できないと思うのですが、構造化プログラミングなのにイベントドリブンで動かすみたいなケースってあるのでしょうか? イベントドリブンという考え方を、オブジェクト指向と組み合わせて開設してしまっていいのかどうかがよく分からなくなってしまいました。 どんな風に解説したらいいか、アドバイス頂ければ幸いです。