OOP初心者がブロック崩しを作ってみる その2
※この記事は「OOP初心者がブロック崩しを作ってみる その1」の続きです
衝突判定を考える
さて、衝突判定のやり方を考えよう。
衝突はボールとReflectorの間で起こる。とりあえず以下のようにクラス分けしてみる。
ReflectorCollectionにReflectorを全て格納しておいて、Ball側から参照、衝突判定を行う。
move関数はBallに速度に従っての移動を指示する関数で、移動するたびに衝突判定を行う。
BallとReflectorのgetRect関数はそれぞれの専有する範囲を返す。(衝突判定に使用)
衝突判定を外に出す
これでも悪くはないが、Ballが「移動する物体」と「衝突する物体」の2つの役割を持っているので、分割したい。
ということで、衝突判定は外に出し、Ballは速度に従って移動することに専念することにする。
CollisionManagerが衝突判定を担当する。
流れとしては、
- Ballのmove関数が呼ばれる
- Ballが速度に従って移動
- BallがexecuteCollisionを呼ぶ
- CollisionManagerが全Reflectorと衝突判定
- CollisionManagerがgiveImpulseを呼び、ボールに力積を与える
という感じ。
Observerパターンを適用する
結合度の面から言えば、BallとCollisionManagerがお互いの関数を直接呼び出しているのであまり良くない。
そもそも、CollisionManagerはボールの移動をトリガーとして衝突判定を行うのである。
したがって、CollisionManagerがボールの移動を監視すれば良い。
つまり、Observerパターンを適用する。
move関数で移動した後、observerに移動を通知する。
これで多少はすっきりした。
Reflectorが衝突を知るには
ブロックのように衝突の有無を情報として必要とするReflectorが存在するので、それを通知する必要がある。
それもCollisionManagerが担当するのが妥当であろう。
以上のことを加味してまとめたクラス図はこうなった。
衝突判定に関しては概ねこのような感じでいいだろう。