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

C# 以优雅的方式使用多态性进行碰撞检测,c#,.net,polymorphism,collision-detection,C#,.net,Polymorphism,Collision Detection,我正在尝试设置一些简单的2D形状,可以使用鼠标在窗口中拖动。当我将一个形状拖动到另一个形状时,我希望形状注册碰撞。我有一个接口 interface ICollidable { bool CollidedWith(Shape other); } abstract class Shape : ICollidable { protected bool IsPicked { private set; get; } protected Form1 Form { private s

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

interface ICollidable
{
    bool CollidedWith(Shape other);
}
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);
}
然后,我有一个实现上述接口的抽象类形状

interface ICollidable
{
    bool CollidedWith(Shape other);
}
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);
}
然后,我有10个具体的类,Circle、Square、Rectangle等,它们扩展了Shape类并实现了抽象方法。 我想做的是想出一些面向对象的简洁优雅的方法来进行讨论检测,而不是在CollidedWith方法中使用一大块if语句,比如is

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
}

有人有什么想法吗。这是一个我以前考虑过的问题,但我现在才付诸实践。

它们都是或,而不是特定的形状

正方形就是一个有4个点的多边形,正好成直角。然后只需编写一个
Path.collizeswith(Path)
方法,就可以上路了


查看一些。

碰撞检测是不是“特定于形状”,因此每个碰撞排列都有不同的实现

Circle vs. Other Circle
Circle vs. Other Square
Circle vs. Other Triangle
Square vs. Other Circle
...
听起来你在尝试创建一个包含所有可能性的矩阵,但如果你想出10个新形状,总共20个,你就有400个可能性

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


如果这仅仅是二维几何体,那么确定任何形状的边路径是否相交应该很简单。

通常用于这种情况。

如果您能够解释如何定义碰撞,以及碰撞在子类之间可能如何变化,这将很有帮助。
Shape
是否也将包含实例坐标的任何信息?@Mick C。我已经更改了代码,为Shape classis插入了整个代码。如果您仔细想想,这与OP的
与带有大型if语句的
方法相冲突并没有什么不同。唯一的区别是框架将为您处理切换逻辑。另一个问题是,这种方法仍然需要修改每个子类,并为创建的每个新类型提供新的实现,这将导致维护负担呈指数级增长。