こんにちは。javaをはじめて3ヶ月くらいなのですが、オブジェクト指向でうまくプログラムを書くことができません。オブジェクト指向の理解のために、簡単なプログラムを作っていて疑問がわきました。
JPanel上をクリックすると、ボールが発生して動くプログラムをつくっています。クラスBallをつくり、クリック時にインスタンス化されます。そのときボールの発生位置や、初速度が乱数で決まるようにしました。
ここで、ボールとボールが接したときに跳ね返るようにしたいのですが、各Ballオブジェクトは衝突時点における全てのBallオブジェクトを持っていなければならないのでしょうか?(クリックするごとにArrayListなどにBallオブジェクトをいれて、各ボールの衝突判定のときにそのArrayListを渡す)
でもこれだと、処理が遅くなってしまいそうで、心配なのですが、他にいい案はないでしょうか?
No.4ベストアンサー
- 回答日時:
No2で回答した者です。
「仮想空間」について、既にNo3回答者様のご回答が付いていますが、view と 内部ロジックの分離(独立部品化)目的です。
いまのところ、2次元平面空間でJPanelに全空間表示している状態と思うので、分離のイメージが湧かないのかもしれませんが、ボール空間の一部のみ切り取ってスクリーン(JPanel)に投影というように考えるとより具体的イメージになるかとおもいます。ボール位置情報をintで保持するかdoubleにするかは、仮想空間側で決める事項となります。
全体を表示するのか、ズームしてどこか一部を表示するのかといったロジックを、座標変換ロジックとして、仮想空間クラス側のメソッドに組み込んでやれば、JPanel側は、どの領域を表示したいかのデータを引数で渡してメソッドを呼び出し、またはsetterメソッドで環境データ設定のようなことをしてから、投影後画像作成メソッドを呼び出して、投影後画像を取り出すといったことができます。
2次元から3次元への拡張時も、呼び出し用メソッド名や引数が同じになるように作っておけば、仮想空間クラスを変更してすげ替えるだけで、JPanel側の変更はごくわずかとなります。
この仮想空間クラス拡張をも考えると、インターフェースで、表示画像取り出しメソッド名を宣言して、統一するといったことをしておくとよりよいでしょう。
しかし、いっぺんにやろうとしても、すぐには動くものにならないので、とりあえずJPanelに全部組み込んで、まずは動くものを作ってみてもよいでしょう。
いろいろな部品の動作原理が解ってきたら、上記のことをもう一度思い出してクラスを分解していくと、こういう作りをすると拡張(変更)が楽なのかといったことが解ってくると思います。ここまでくれば、デザインパターンを勉強するとより洗練されたプログラムになっていくでしょう。
私も、レイトレーシングプログラムを作ったときに、3-4回ほどクラス構成全部作り換えてようやくMVCの基本を理解できたかなと思っています。
No.3
- 回答日時:
こんにちは。
オブジェクト指向プログラミングの目的の一つは、プログラムをオブジェクトというパーツに分け、それぞれを独立性の高い部品として設計して変更やメンテナンスを容易にすることだと私は理解しています。
今回のケースで既に前の回答者様が仰っているように、ボールクラスと当たり判定を行うクラスを分けた方が良いというアドバイスは、まさにこの目的のためです。
ボールクラス自体をいじらなくても当たり判定の処理を独立して変更することができますし、仮にボール以外のものを同じようにパネル上で動かしたい場合も、その物体のクラスのみを設計するだけで当たり判定クラスは流用できるかもしれません。
さらに補足でご質問になっている、表示系座標と仮想座標の分離についてもこの目的のためと言えます。
JPanelの座標を直接使用している場合は、他の環境に移植する場合には何らかの変更をボールクラス自体に施す必要があるかもしれません。
しかし、ボールクラスが仮想空間座標を前提に設計されていれば、JPanel以外に表示させたい場合にもボールクラスそのものを変更する必要はなくなり、部品としての独立性を保てます。
回答ありがとうございます。なんとなく理解してきました。
ボール以外のものもパネル上で動かすことを前もって考える場合には、描画物クラスという抽象クラスをボールクラスが継承して、判定クラスが描画物クラスを扱うようにすれば、判定クラスを変更しなくても、新しい描画物の種類を増やしていけますね。
また、仮想座標は、他の環境に移植する場合に、仮想座標とその環境のインターフェースだけを考えればいいようにするためのものなんですね。
つまりクラスとクラスのインターフェースを簡潔にして、クラスごとの独立性を高めるというのがオブジェクト指向の目的なんでしょうか。
No.2
- 回答日時:
各ボール用クラスは、それぞれに固有のデータを持たせるだけで、他のことまで関知させない方が、よいでしょう。
ボール間の衝突判定は、ボール全部とボールの存在環境についての情報を握るクラスが行うようにします。
つまり、ArryListのインスタンスを保持するクラスに、各ボール間の衝突判定メソッドを組み込んで、ボールの移動方向や位置変更などを行わせます、画面の端へ行ったときの処理もここで組み込めます。
衝突判定は、各ボールから他のボールを全部リストすると2重計算になるので、既に計算した組は計算しないように組みます。2つの衝突だけ考えればいいなら、2重ループで、内部ループは、自分の番号より後方をみるだけでいいはず。3重衝突を考えると面倒になるのでとりあえず、2個組での衝突だけで考えた方がよいでしょう。
ボール全部についての情報を握るクラスは、JPanelではなく、仮想空間オブジェクトとして、別にクラスを作成すると、表示用JPanelとボール仮想空間での移動ロジックとの分離ができます。
クリックのたびに、呼び出すのは、仮想空間インスタンスが持つメソッドで、新規ボール登録メソッドと衝突判定メソッドを呼び出し、さらに表示用メソッド呼び出し。
移動での表示変更はThreadかTimer制御かな?このインスタンスを、仮想空間インスタンスと別に持つか、仮想空間インスタンス内に保持させるかどうかは、全体構成とのかねあいで決めてください。表示制御メソッド呼び出しのしやすさでは、表示用クラスの内部クラスで定義してもいいかも?
移動時の表示変更については、TimerTask().run()などから、仮想空間クラスの衝突判定メソッドを呼び出して、現在のボール情報を元に移動計算と内部データ更新を行う。その後、表示用メソッド呼び出しの手順。
概略こんな感じで、Object指向&MVC&UML的構成になると思いますけど解りますでしょうか?
この回答への補足
回答ありがとうございます。独学なので、いろいろと勉強になります。
ArrayListを保持するクラスが衝突判定するということと、衝突判定時のループのさせ方は理解できました。
>表示用JPanelとボール仮想空間での移動ロジックとの分離ができます。
という部分についてなのですが、これは、どういうことなのでしょうか?
仮想空間というのは、例えば、ボールが位置座標をintではなくdoubleで持つことができるようにするためのものですか?表示用クラスの表示メソッドで仮想空間の座標系から表示用クラスの座標系に座標変換するということでしょうか?
No.1
- 回答日時:
n個のボールがあれば n(n-1)/2回の衝突判定は必要なので (状況によって減ることはあるが最悪これを覚悟しなきゃならない) それについてはあきらめるしかない.
でなんだけど, 「各Ballオブジェクトは衝突時点における全てのBallオブジェクトを持っていなければならないのでしょうか」がどういうことなのか, よくわかんない. そもそも「すべてのボールの情報を記憶する」クラスは存在するはずなので, そいつが衝突判定をすればいいだけではないんだろうか. カッコ内の「クリックするごとにArrayListなどにBallオブジェクトをいれて、各ボールの衝突判定のときにそのArrayListを渡す」というのも, 「誰が ArrayList などを持っているのか」「誰が誰にその ArrayList などを渡すのか」が明確じゃないので, 何とも言えない.
回答ありがとうございます。ボールクラスのメソッドで衝突判定しちゃってました。衝突判定するクラスをつくって、そのクラスがボール全体の情報を持ち、衝突判定するようにすればいいんですね。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 物理学 英語表現についてどうもわからないので教えて貰えないでしょうか? 具体的には以下の文の中でreflec 1 2023/04/29 20:59
- Java オブジェクト指向プログラミングの実践本を紹介してください 3 2022/09/19 04:56
- PowerPoint(パワーポイント) パワーポイントのアニメーションについて 4 2023/06/14 16:25
- Java 複数TBLのオブジェクトを1つの変数(オブジェクト)でまとめて管理したい 1 2022/12/17 00:12
- JavaScript オブジェクト配列の各メンバを任意の式で評価して、その評価値が最大のオブジェクトを返す関数はありますか 2 2023/05/20 15:02
- その他(プログラミング・Web制作) ボールの動きがスムーズに動いてかつ目盛り線描画を維持するためには 4 2023/05/31 10:01
- 物理学 光時計の光の進み方について 8 2022/06/22 19:52
- その他(プログラミング・Web制作) Pythonによる物理の斜方投射の位置座標表示について 2 2023/06/05 12:46
- その他(プログラミング・Web制作) Pythonにおける物理のシミュレーションでの単位変換について 2 2023/06/02 17:11
- 物理学 高校生 物理 1 2023/07/26 06:37
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
(vba)他のアプリケーションの右...
-
「ラッパークラス」の存在意義...
-
ASP.NETでの共通コードの書き方...
-
【継承】親のメソッドの実行
-
抽象クラスをJUNITでテストする...
-
【設計思想の質問】staticメソ...
-
interface,extend,implementの...
-
vb.net 自作プロパティの削除に...
-
c++でのヘッダーファイルの循環...
-
C++で参照カウンタを実装したい...
-
「継承されたメソッドの可視性...
-
Javaでは多重継承ができない、...
-
VB DLLプロジェクトについて
-
C# 「データが失なわれる可能性...
-
メソッドの引数にクラス名を渡す
-
c# この高速化の方法あり?
-
「IOException は対応する try ...
-
JTextFieldの入力制限
-
Java StringBuilderクラスについて
-
C#からDLLを呼びたいのですが・...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
interface,extend,implementの...
-
抽象クラスをJUNITでテストする...
-
「ラッパークラス」の存在意義...
-
(vba)他のアプリケーションの右...
-
ASP.NETでの共通コードの書き方...
-
VB DLLプロジェクトについて
-
C#からDLLを呼びたいのですが・...
-
c++でのヘッダーファイルの循環...
-
委譲って何ですか?
-
「継承されたメソッドの可視性...
-
【C#】クラスのコンストラクタ...
-
Javaでのジェネリクス型パラメ...
-
C# 「データが失なわれる可能性...
-
Excel vbaのプログラムでガンマ...
-
ファイルパスが取得出来ない(P...
-
オーバーライドとラッパーの違い
-
compareToにおける「自然順序付...
-
メソッドの引数にクラス名を渡す
-
vb.net 自作プロパティの削除に...
-
VBがオブジェクト指向言語でな...
おすすめ情報