6

I am trying to set up some simple 2D shapes which can be dragged about the window using the mouse. I want the shapes to register a collision when I drag one into another. I have an interface.

interface ICollidable
{
    bool CollidedWith(Shape other);
}

I then have an abstract class Shape that implements the above interface.

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);
}

I then have ten concrete classes Circle, Square, Rectangle etc that extend the Shape class and implement the abstract methods. What I would like to do is come up with some oop clean and elegant way to do the collosion detection instead having a large block of if statements in the CollidedWith method such 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
}

Has anyone any ideas. It's a problem I've thought about before but am only putting into practice now.

4

3 回答 3

4

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

Circle vs. Other Circle
Circle vs. Other Square
Circle vs. Other Triangle
Square vs. Other Circle
...

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

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

如果这只是 2D 几何,那么判断任何形状的边缘路径是否相交应该很容易。

于 2012-09-06T17:09:37.137 回答
1

在这种情况下,通常使用双重调度。

于 2012-09-06T17:15:52.990 回答
1

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

正方形只是一个有 4 个点的多边形,它们恰好成直角。然后只需编写一种Path.CollidesWith(Path)方法并继续前进。

查看一些相关 问题

于 2012-09-06T17:06:43.713 回答