自機であるPlayerクラスも敵であるEnemyクラスもインスタンスはGameManagerが持っています。
(Enemyは間にEnemyManagerが入ります)
EnemyからPlayerは遠いので、どうやってPlayerの情報を取ってくるか?が設計のポイントです。
まずPlayerに位置情報や当たり判定範囲などの情報を取得できる関数を実装するための
インターフェイスクラス「PlayerInfoGettable」を定義します。
これをPlayerに実装させます。
多重継承はタブーなので、言語仕様的にできないようにしてある言語も多々あります。
しかしJavaのimplementsがC++に無いように、C++にはインターフェイスクラスの実装方法は継承しかありません。
ですので、PlayerはCharactorクラスを継承していますが、インターフェイスクラスを多重継承する分には
全く問題ありません。
多重継承が悪いのはインターフェイスクラス以外のクラスを多重継承する場合です。
さて、PlayerインスタンスはGameManagerが持っているのでEnemyManagerに渡してやることができます。
mPlayer = new Player();
new EnemyManager((PlayerInfoGettable*)mPlayer);
こんな感じで渡せます。
EnemyManagerはEnemyを作るときにこのインターフェイスポインタを渡してやります。
そうしてEnemyクラスが持った
mPlayerInfoGettable;
変数はこれを経由して座標や当たり判定範囲を取得できるようになります。
そこで敵クラスは
void Enemy::updateHit(){
Pos pos = mPlayerInfoGettable->GetPosition();
float range = mPlayerInfoGettable->GetRange();
//posとrangeで敵との当たり判定計算
}
Playerのインスタンス自身を丸ごと渡してやる方法もありますが、
必要以上の権限を多数のクラスに渡すのは危険です。
インターフェイスクラスを実装して必要最小限の権限だけを渡し、
関数の返り値はこのように値のコピーになるようにすることで安全な設計が可能になります。
(オブジェクトがある程度のサイズになるような返り値はオブジェクトコピーに時間がかかるのでconstポインタかconst参照にします)