私は認めます、私は相続財産を濫用し、さらには虐待の罪を犯しました。OOPコースを受講するときに作成した最初の(テキスト)ゲームプロジェクトは、「ドア」と「1つのドアがある部屋」、「2つのドアがある部屋」から「ロックされたドア」と「ロック解除されたドア」 「部屋」から。
私が最近取り組んだ(グラフィカルな)ゲームでは、自分のレッスンを学び、継承の使用に制限をかけたと思いました。しかし、問題がすぐに現れ始めたことに気付きました。私のルートクラスはどんどん肥大化し始め、リーフクラスは重複したコードでいっぱいになりました。
私はまだ間違ったことをしていると思っていたので、オンラインで調べたところ、この問題を抱えているのは自分だけではないことがわかりました。いくつかの徹底的な調査の後、エンティティシステムを発見することになりました(読む:googlefu)
読み始めたとき、コンポーネントを使用した従来のOOP階層で発生していた問題をどれだけ明確に解決できるかを知ることができました。ただし、これらは最初の測定値でした。もっとつまずいたとき… T-machineのような「ラジカルな」ESアプローチ。
私は彼らが使っていた方法に反対し始めました。純粋なコンポーネントシステムは過剰であるか、直感的ではなく、おそらくOOPの強さのように見えました。著者は、ESシステムはOOPの反対であると言っており、OOPに沿って使用できるかもしれませんが、実際には使用すべきではありません。私はそれが間違っていると言っているわけではありませんが、実装したい解決策のような気がしませんでした。
ですから、私にとって、そして私の直感に反することなく、投稿の冒頭で抱えていた問題を解決するには、まだ階層を使用することですが、以前に使用したようなモノリシックな階層ではなく、ポリリシックなもの(モノリシックの反対語が見つかりませんでした)は、いくつかの小さな木で構成されています。
次の例は、私が何を意味するかを示しています(これは、Game Engine Architectureの第14章で見つけた例から着想を得ています)。
車両用の小さなツリーがあります。ルート車両クラスには、レンダリングコンポーネント、衝突コンポーネント、位置コンポーネントなどが含まれます。
そして、車両のサブクラスであるタンクは、そこからこれらのコンポーネントを継承し、独自の「キャノン」コンポーネントが与えられます。
キャラクターについても同じことが言えます。キャラクターは独自のコンポーネントを持ち、プレイヤークラスはそれを継承し、入力コントローラーを与えられますが、他の敵クラスはキャラクタークラスを継承し、AIコントローラーを与えられます。
この設計には問題はありません。純粋なEntity Controller Systemを使用していないにもかかわらず、バブリングアップ効果と大きなルートクラスの問題はマルチツリー階層を使用することで解決され、葉が重複しないため、葉を複製する重いコードの問題はなくなりました開始するコードは、コンポーネントだけです。リーフレベルに変更を加える必要がある場合、コードをどこにでもコピーペーストするのではなく、単一のコンポーネントを変更するのと同じくらい簡単です。
もちろん、私と同じように経験が浅いので、最初に単一階層の継承の重いモデルを使用し始めたときに問題は見られなかったため、現在実装を考えているモデルに問題がある場合は、それを見ることができます。
あなたの意見は?
PS:私はJavaを使用しているため、通常のコンポーネントを使用する代わりに、多重継承を使用してこれを実装することはできません。
PPS:コンポーネント間の通信は、依存コンポーネントを相互にリンクすることにより行われます。これは結合につながりますが、私はそれが良いトレードオフだと思います。