2011-02-09 34 views
5

Vì vậy, tôi có lớp Panel này. Đó là một chút giống như một cửa sổ nơi bạn có thể thay đổi kích cỡ, đóng, thêm các nút, thanh trượt, vv Giống như màn hình trạng thái trong Morrowind nếu bất kỳ của bạn nhớ. Các hành vi tôi muốn là khi một sprite là bên ngoài giới hạn của bảng điều khiển nó không được rút ra và nếu nó là một phần bên ngoài chỉ có một phần bên trong được rút ra. Vì vậy, những gì nó làm ngay bây giờ là lần đầu tiên có được một hình chữ nhật đại diện cho các giới hạn của bảng điều khiển, và một hình chữ nhật cho sprite, nó tìm thấy hình chữ nhật của giao nhau giữa hai sau đó dịch giao nhau với các tọa độ địa phương của hình chữ nhật sprit và sử dụng rằng cho hình chữ nhật nguồn. Nó hoạt động và thông minh như tôi cảm thấy mã là tôi không thể lắc cảm giác rằng có một cách tốt hơn để làm điều này. Ngoài ra, với thiết lập này tôi không thể sử dụng ma trận chuyển đổi toàn cầu cho máy ảnh 2D của tôi, mọi thứ trong "thế giới" phải được chuyển qua một đối số máy ảnh để vẽ. Dù sao, đây là đoạn code tôi có:
cho Intersection:Làm thế nào tôi có thể thực hiện cắt trên hình chữ nhật xoay?

 public static Rectangle? Intersection(Rectangle rectangle1, Rectangle rectangle2) 
    { 
     if (rectangle1.Intersects(rectangle2)) 
     { 
      if (rectangle1.Contains(rectangle2)) 
      { 
       return rectangle2; 
      } 
      else if (rectangle2.Contains(rectangle1)) 
      { 
       return rectangle1; 
      } 
      else 
      { 
       int x = Math.Max(rectangle1.Left, rectangle2.Left); 
       int y = Math.Max(rectangle1.Top, rectangle2.Top); 
       int height = Math.Min(rectangle1.Bottom, rectangle2.Bottom) - Math.Max(rectangle1.Top, rectangle2.Top); 
       int width = Math.Min(rectangle1.Right, rectangle2.Right) - Math.Max(rectangle1.Left, rectangle2.Left); 
       return new Rectangle(x, y, width, height); 
      } 
     } 
     else 
     { 
      return null; 
     } 
    } 

và thực sự vẽ trên bảng điều khiển:

public void DrawOnPanel(IDraw sprite, SpriteBatch spriteBatch) 
    { 
     Rectangle panelRectangle = new Rectangle(
      (int)_position.X, 
      (int)_position.Y, 
      _width, 
      _height); 
     Rectangle drawRectangle = new Rectangle(); 

     drawRectangle.X = (int)sprite.Position.X; 
     drawRectangle.Y = (int)sprite.Position.Y; 
     drawRectangle.Width = sprite.Width; 
     drawRectangle.Height = sprite.Height; 

     if (panelRectangle.Contains(drawRectangle)) 
     { 
      sprite.Draw(
       spriteBatch, 
       drawRectangle, 
       null); 
     } 
     else if (Intersection(panelRectangle, drawRectangle) == null) 
     { 
      return; 
     } 
     else if (Intersection(panelRectangle, drawRectangle).HasValue) 
     { 
      Rectangle intersection = Intersection(panelRectangle, drawRectangle).Value; 

      if (Intersection(panelRectangle, drawRectangle) == drawRectangle) 
      { 
       sprite.Draw(spriteBatch, intersection, intersection); 
      } 
      else 
      { 
       sprite.Draw(
        spriteBatch, 
        intersection, 
        new Rectangle(
         intersection.X - drawRectangle.X, 
         intersection.Y - drawRectangle.Y, 
         intersection.Width, 
         intersection.Height)); 
      } 
     } 
    } 

Vì vậy, tôi đoán câu hỏi của tôi là, là có một cách tốt hơn để làm điều này?

Cập nhật: Chỉ cần tìm hiểu về thuộc tính ScissorRectangle. Điều này có vẻ giống như một cách tốt để làm điều này; nó đòi hỏi một đối tượng RasterizerState được thực hiện và được truyền vào trong quá trình spritebatch.Begin chấp nhận nó. Có vẻ như đây có lẽ là đặt cược tốt nhất. Ngoài ra còn có các Viewport mà tôi dường như có thể thay đổi xung quanh. Suy nghĩ? :)

+0

Tôi đề nghị bạn sử dụng một công thức rõ ràng hơn trong câu hỏi của bạn, một cái gì đó dọc theo dòng "Làm thế nào để thực hiện cắt trên hình chữ nhật xoay?". – Joh

+0

Ồ, tôi thậm chí còn không nghĩ đến việc quay vòng. Cảm ơn –

Trả lời

1

Có một số cách để giới hạn bản vẽ cho một phần của màn hình. Nếu khu vực này là hình chữ nhật (có vẻ như là trường hợp ở đây), bạn có thể đặt chế độ xem (xem GraphicsDevice) lên bề mặt của bảng điều khiển.

Đối với các khu vực không phải hình chữ nhật, bạn có thể sử dụng bộ đệm stencil hoặc sử dụng một số thủ thuật với bộ đệm độ sâu. Vẽ hình dạng của bề mặt trong bộ đệm stencil hoặc bộ đệm độ sâu, thiết lập trạng thái hiển thị của bạn để chỉ vẽ các pixel nằm trong hình bạn vừa render trong bộ đệm stencil/depth, cuối cùng là render các sprites của bạn.

1

Một cách để làm điều này là va chạm đơn giản trên mỗi pixel. Mặc dù đây là một ý tưởng tồi nếu các sprites lớn hay nhiều, đây có thể là một cách rất dễ dàng và nhanh chóng để hoàn thành công việc với các sprites nhỏ. Đầu tiên, thực hiện một vòng tròn giới hạn hoặc kiểm tra va chạm vuông đối với bảng điều khiển để xem liệu bạn có cần phát hiện từng pixel hay không. Sau đó, tạo một phương thức chứa để kiểm tra xem vị trí, tỷ lệ và xoay của sprite có đặt nó cho đến giờ trong bảng điều khiển mà nó phải được bao quanh hoàn toàn bởi bảng điều khiển, vì vậy bạn không cần va chạm trên mỗi pixel trong trường hợp đó. Điều này có thể được thực hiện khá dễ dàng bằng cách chỉ tạo một ô vuông có chiều rộng và chiều cao của chiều dài đường chéo của sprite, và kiểm tra va chạm với điều đó.

Cuối cùng, nếu cả hai lỗi này đều không thành công, chúng tôi phải thực hiện va chạm trên mỗi pixel. Đi qua và kiểm tra đối với mọi pixel trong sprite để xem nó có nằm trong giới hạn của bảng điều khiển hay không. Nếu không đặt giá trị alpha của pixel là 0.

Thats it.

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