c# - 以优雅的方式使用多态性进行碰撞检测

标签 c# .net polymorphism collision-detection

我正在尝试设置一些简单的 2D 形状,可以使用鼠标在窗口中拖动这些形状。当我将一个形状拖到另一个形状时,我希望这些形状记录碰撞。我有一个界面。

interface ICollidable
{
    bool CollidedWith(Shape other);
}

然后我有一个实现上述接口(interface)的抽象类 Shape。

abstract class Shape : ICollidable
{
    protected bool IsPicked { private set; get; }
    protected Form1 Form { private set; get; }

    protected int X { set; get; } // Usually top left X, Y corner point
    protected int Y { set; get; } // Used for drawing using the Graphics object

    protected int CenterX { set; get; } // The center X point of the shape
    protected int CenterY { set; get; } // The center X point of the shape

    public Shape(Form1 f, int x, int y)
    {
        Form = f;
        X = x; Y = y;
        Form.MouseDown += new MouseEventHandler(form_MouseDown);
        Form.MouseMove += new MouseEventHandler(Form_MouseMove);
        Form.MouseUp += new MouseEventHandler(Form_MouseUp);
    }

    void Form_MouseMove(object sender, MouseEventArgs e)
    {
        if(IsPicked)
            Update(e.Location);
    }

    void Form_MouseUp(object sender, MouseEventArgs e)
    {
        IsPicked = false;
    }

    void form_MouseDown(object sender, MouseEventArgs e)
    {
        if (MouseInside(e.Location))
            IsPicked = true;
    }

    protected abstract bool MouseInside(Point point);
    protected abstract void Update(Point point);
    public abstract void Draw(Graphics g);
    public abstract bool CollidedWith(Shape other);
}

然后我有十个具体类 Circle、Square、Rectangle 等,它们扩展了 Shape 类并实现了抽象方法。 我想做的是想出一些 oop 干净和优雅的方法来进行碰撞检测,而不是在 CollidedWith 方法中有一大块 if 语句,例如

public bool CollidedWith(Shape other)
{
    if(other is Square)
    {
        // Code to detect shape against a square
    }
    else if(other is Triangle)
    {
        // Code to detect shape against a triangle
    }
    else if(other is Circle)
    {
        // Code to detect shape against a circle
    }
    ...   // Lots more if statements
}

有没有人有任何想法。这是我以前想过但现在才付诸实践的问题。

最佳答案

碰撞检测是否如此“特定于形状”以致于对

的每个排列都有不同的实现
Circle vs. Other Circle
Circle vs. Other Square
Circle vs. Other Triangle
Square vs. Other Circle
...

听起来您正在尝试创建一个包含所有可能性的矩阵,但如果您提出 10 种新形状,总共 20 种,那么您就有 400 种可能性。

相反,我会尝试在您的抽象类中提出一个通用的 Shape.Overlaps(Shape other) 方法来满足所有这些方法。

如果这只是 2D 几何体,那么确定任何形状的边路径是否相交应该是微不足道的。

关于c# - 以优雅的方式使用多态性进行碰撞检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12304984/

相关文章:

c# - 使用 C# 反序列化来自 Web Api 的 BadRequest 响应的问题

c# - 从 ViewModel 绑定(bind)到反向 ObservableCollection

c# - 根据角色创建类

c# - 泛型 Func<T> 的运行时创建

c# - List<object>.RemoveAll - 如何创建合适的 Predicate

java - 为什么 Java 允许接口(interface)具有静态只读字段而 .NET 接口(interface)不能?

java - 在 Java 中使用三角括号内的 "extends"和类型 "T"

c++ - 在 C 中实现多态性是否需要不兼容的指针分配

c# - 使用接口(interface)组合的异常奇怪的接口(interface)多态性

c# - 使用数据绑定(bind)处理样式