典型的な解決策は、次のように 2 つのレベルのディスパッチを行うことです。
class Thing
{
public abstract void Collide(Thing other);
public abstract void CollideWithSpaceship(Spaceship spaceship);
public abstract void CollideWithAsteroid(Asteroid asteroid);
};
class Spaceship : Thing
{
public override void Collide(Thing other) {
other.CollideWithSpaceship(this);
}
public abstract void CollideWithSpaceship(Spaceship spaceship)
{
// Handle Spaceship -> Spaceship collision...
}
public abstract void CollideWithAsteroid(Asteroid asteroid)
{
// Handle Spaceship -> Asteroid collision...
}
}
class Asteroid : Thing
{
public override void Collide(Thing other) {
other.CollideWithAsteroid(this);
}
public abstract void CollideWithSpaceship(Spaceship spaceship)
{
// Handle Asteroid -> Spaceship collision...
}
public abstract void CollideWithAsteroid(Asteroid asteroid)
{
// Handle Asteroid -> Asteroid collision...
}
}
異なるクラスの数が増えると少し面倒になりますが、それにはいくつかの利点があります。
- これは速い。これは、言語に組み込まれた動的ディスパッチに依存しており、これはかなり最適化されています。
- タイプセーフです。キャストが行われていないことに気付くでしょう。
欠点は次のとおりです。
- 拡張に制限はありません。新しいクラスを追加するには、他のすべてのクラスに触れる必要があります。
より拡張可能なソリューションは、各セルが衝突するクラスのペアを識別する 2D ディスパッチ テーブルを構築することです。各セルには、これら 2 つのクラス タイプ間の衝突を処理する関数を配置します。これもうまく機能しますが、型システムを少しごまかしています。いくつかのキャストを行うことになり、クラスを識別するための適切な方法を考え出す必要があります。
C# のサポートは使用しません。dynamic
私の強い予感は、物理エンジンには遅すぎるということです。
また、このような質問への回答に優れたGame Development Stack Exchangeがあることも指摘しておきます。それではお会いしましょう!