2012-09-06 38 views
6

Tôi đang cố gắng thiết lập một số hình dạng 2D đơn giản có thể được kéo về cửa sổ bằng chuột. Tôi muốn các hình dạng để đăng ký một va chạm khi tôi kéo một trong những khác. Tôi có một giao diện.Sử dụng đa hình để phát hiện va chạm một cách thanh lịch

interface ICollidable 
{ 
    bool CollidedWith(Shape other); 
} 

Sau đó tôi có một lớp trừu tượng Hình dạng triển khai giao diện trên.

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

Sau đó tôi có mười lớp bê tông Circle, Square, Rectangle vv để mở rộng lớp Shape và triển khai phương thức trừu tượng. Những gì tôi muốn làm là đưa ra một số oop cách sạch sẽ và thanh lịch để làm việc phát hiện collosion thay vì có một khối lượng lớn các câu lệnh if trong phương pháp CollidedWith như là

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 
} 

Có ai bất kỳ ý tưởng. Đó là một vấn đề mà tôi đã nghĩ đến trước đây nhưng giờ đây tôi chỉ đang thực hành.

+0

Sẽ rất hữu ích nếu bạn có thể giải thích cách bạn xác định xung đột và cách nó có thể khác nhau giữa các lớp con. Có phải 'Hình dạng' cũng sẽ chứa bất kỳ thông tin nào về các tọa độ cá thể không? – mclark1129

+0

@Mick C. Tôi đã thay đổi mã chèn toàn bộ mã cho lớp Shape –

Trả lời

1

Thay vì các hình dạng cụ thể, tất cả chúng đều là Paths hoặc Regions.

Một hình vuông chỉ là một poly với 4 điểm, điều đó xảy ra ở các góc vuông. Sau đó, chỉ cần viết một phương thức Path.CollidesWith(Path) và đang trên đường đi.

Kiểm tra một số relatedquestions.

4

là việc phát hiện va chạm như vậy "Shape cụ thể" rằng có một thực hiện khác nhau cho mỗi hoán vị của

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

Có vẻ như bạn đang cố gắng để tạo ra một ma trận của tất cả các khả năng nhưng nếu bạn đưa ra 10 hình dạng mới, 20 trong tổng số, bạn có 400 possibilites.

Thay vào đó, tôi sẽ cố gắng đưa ra phương pháp chung Shape.Overlaps(Shape other) trong lớp trừu tượng của bạn để thỏa mãn tất cả chúng.

Nếu đây chỉ là Hình học 2D, nếu không quan trọng để tìm hiểu xem Đường dẫn cạnh của bất kỳ hình dạng nào có giao nhau hay không.

1

Double dispatch thường được sử dụng trong trường hợp này.

+1

Nếu bạn nghĩ về nó, điều này không thực sự khác với phương thức 'CollideWith' của OP với câu lệnh if lớn. Điểm khác biệt duy nhất là khung công tác sẽ xử lý logic chuyển đổi cho bạn. Vấn đề khác là cách tiếp cận này vẫn yêu cầu bạn phải sửa đổi mọi phân lớp và cung cấp một triển khai mới cho mọi kiểu mới được tạo ra, điều này sẽ dẫn đến gánh nặng bảo trì tăng theo cấp số nhân. – mclark1129

Các vấn đề liên quan