C# 以优雅的方式使用多态性进行碰撞检测
我正在尝试设置一些简单的2D形状,可以使用鼠标在窗口中拖动。当我将一个形状拖动到另一个形状时,我希望形状注册碰撞。我有一个接口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
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语句的方法相冲突并没有什么不同。唯一的区别是框架将为您处理切换逻辑。另一个问题是,这种方法仍然需要修改每个子类,并为创建的每个新类型提供新的实现,这将导致维护负担呈指数级增长。