典型的解决方案是像这样进行两个级别的调度:
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 调度表,其中每个单元格标识一对冲突类。在每个单元格中,放置一个处理这两种类类型之间冲突的函数。这也很有效,但它有点欺骗类型系统。你最终会做一些铸造,你必须想出一个好的方法来识别一个类。
我不会使用 C# 的dynamic
支持。我强烈的预感是它对于物理引擎来说太慢了。
我还要指出,有一个Game Development Stack Exchange可以更好地回答此类问题。到时候那里见!