Góc tròn trong XNA?


10

Có cách nào để tôi có thể tạo các góc tròn trên một hình chữ nhật được hiển thị trong XNA thông qua các nguyên hàm (dải dòng) không? Tôi muốn làm cho giao diện người dùng của mình trở nên lạ mắt hơn một chút so với hiện tại và tôi muốn mã phải linh hoạt, không có quá nhiều kết cấu liên quan.


Về cơ bản: Sử dụng một kết cấu cho dòng, một kết cấu cho các đầu tròn của dòng. Xoay và quy mô các họa tiết sử dụng hai kết cấu này một cách thích hợp.
Olhovsky

Câu trả lời:


8

Bạn có thể kết xuất nguyên thủy của mình và tạo một shader có thể tạo các góc tròn này.
Dưới đây là một pixel shader đơn giản trong mã giả có thể vẽ một hình vuông tròn:

xDist = abs(x-0.5)
yDist = abs(y-0.5)
xD = xDist*xDist*4
yD = yDist*yDist*4
alpha = floor((1-xD)*(1-yD)*5)

Kết quả của trình đổ bóng pixel này:

nhập mô tả hình ảnh ở đây

Nếu bạn sử dụng shader, bạn có thể tạo giao diện người dùng thực sự lạ mắt, thậm chí là hoạt hình.

Đối với tôi tuyệt vời để tạo mẫu pixel shader đơn giản là chương trình EvalDraw


5

Một cách khác để làm điều này là sử dụng 'nút kéo dài' (còn được gọi là 'kéo dài hộp' hoặc 'chín miếng'). Về cơ bản, bạn tạo một hình ảnh được tạo thành từ 9 phần:

Nút tài nguyên

Để vẽ nút đó ở bất kỳ kích thước nào, bạn vẽ từng mảnh (từ trên xuống dưới, từ trái sang phải):

  1. Vẽ unscaled ở phía trên bên trái của hình chữ nhật đích.
  2. Vẽ tỷ lệ theo chiều ngang (với width - ((1) + (2)).Width) ở trên cùng của hình chữ nhật đích, với phần bù bên trái theo chiều rộng của (1).
  3. Vẽ unscaled ở phía trên bên phải của hình chữ nhật đích.
  4. Vẽ tỷ lệ theo chiều dọc (với height - ((1) + (2)).Height) ở bên trái của hình chữ nhật đích, với phần bù trên cùng theo chiều cao của (1).
  5. Vẽ tỷ lệ theo cả hai hướng (với chiều rộng của (2) và chiều cao của (4)), được bù bởi chiều rộng và chiều cao của (1).
  6. Vẽ tỷ lệ theo chiều dọc (cùng chiều cao với (4)) ở bên phải hình chữ nhật đích, bù theo chiều cao của (1).
  7. Vẽ unscaled ở dưới cùng bên trái của hình chữ nhật đích.
  8. Vẽ tỷ lệ theo chiều ngang (cùng chiều cao với (2)) ở dưới cùng của hình chữ nhật đích, được bù bởi chiều rộng của (1).
  9. Vẽ unscaled ở dưới cùng bên phải của hình chữ nhật đích.

Nếu bạn nhìn vào nút, bạn sẽ thấy rằng nó không thành vấn đề nếu (2), (5) và (7) được thu nhỏ theo chiều ngang (vì thực chất nó là một đường thẳng); theo cách tương tự (4), (5) và (6) có thể được thu nhỏ theo chiều dọc mà không ảnh hưởng đến chất lượng của hình ảnh.


Vâng, điều này không trả lời trực tiếp câu hỏi - nhưng ai đó vẫn có thể thấy nó hữu ích.
Jonathan Dickinson

4
Nó được gọi là một miếng vá chín và thực sự linh hoạt hơn (và rẻ hơn!) So với sử dụng một shader vì bạn có thể làm cho nó trông giống như bạn muốn với một kết cấu. Sau đó, bạn có thể đặt tất cả các hình ảnh widget của bạn trong một tập bản đồ kết cấu duy nhất. Hầu hết các GUI làm theo cách này.
Elisée

0

Đây là mã cho phương pháp "chín miếng":

public static class SpriteBatchExtensions
{
    public static void DrawRoundedRect(this SpriteBatch spriteBatch, Rectangle destinationRectangle, 
        Texture2D texture, int border, Color color)
    {
        // Top left
        spriteBatch.Draw(
            texture, 
            new Rectangle(destinationRectangle.Location, new Point(border)), 
            new Rectangle(0, 0, border, border), 
            color);

        // Top
        spriteBatch.Draw(
            texture, 
            new Rectangle(destinationRectangle.Location + new Point(border, 0), 
                new Point(destinationRectangle.Width - border * 2, border)), 
            new Rectangle(border, 0, texture.Width - border * 2, border), 
            color);

        // Top right
        spriteBatch.Draw(
            texture, 
            new Rectangle(destinationRectangle.Location + new Point(destinationRectangle.Width - border, 0), new Point(border)), 
            new Rectangle(texture.Width - border, 0, border, border), 
            color);

        // Middle left
        spriteBatch.Draw(
            texture, 
            new Rectangle(destinationRectangle.Location + new Point(0, border), new Point(border, destinationRectangle.Height - border * 2)), 
            new Rectangle(0, border, border, texture.Height - border * 2), 
            color);

        // Middle
        spriteBatch.Draw(
            texture, 
            new Rectangle(destinationRectangle.Location + new Point(border), destinationRectangle.Size - new Point(border * 2)), 
            new Rectangle(border, border, texture.Width - border * 2, texture.Height - border * 2), 
            color);

        // Middle right
        spriteBatch.Draw(
            texture, 
            new Rectangle(destinationRectangle.Location + new Point(destinationRectangle.Width - border, border), 
                new Point(border, destinationRectangle.Height - border * 2)), 
            new Rectangle(texture.Width - border, border, border, texture.Height - border * 2), 
            color);

        // Bottom left
        spriteBatch.Draw(
            texture, 
            new Rectangle(destinationRectangle.Location + new Point(0, destinationRectangle.Height - border), new Point(border)), 
            new Rectangle(0, texture.Height - border, border, border), 
            color);

        // Bottom
        spriteBatch.Draw(
            texture, 
            new Rectangle(destinationRectangle.Location + new Point(border, destinationRectangle.Height - border), 
                new Point(destinationRectangle.Width - border * 2, border)), 
            new Rectangle(border, texture.Height - border, texture.Width - border * 2, border), 
            color);

        // Bottom right
        spriteBatch.Draw(
            texture, 
            new Rectangle(destinationRectangle.Location + destinationRectangle.Size - new Point(border), new Point(border)), 
            new Rectangle(texture.Width - border, texture.Height - border, border, border), 
            color);
    }
}

Nó được gọi là:

spriteBatch.DrawRoundedRect(
    dest, // The coordinates of the Rectangle to be drawn
    rectangleTexture, // Texture for the whole rounded rectangle
    16, // Distance from the edges of the texture to the "middle" patch
    Color.OrangeRed);

Điều này không làm việc cho tôi ... Tôi chỉ nhận được một hình chữ nhật bình thường. Đây là cách tôi sử dụng nóTexture2D _texture = new Texture2D(GraphicsDevice, 1, 1); _texture.SetData(new Color[] { Color.Blue }); SpriteBatch sb = new SpriteBatch(GraphicsDevice); sb.Begin(); //sb.Draw(_texture, new Rectangle(100, 100, 100, 100), Color.White); sb.DrawRoundedRect(_texture, new Rectangle(100, 100, 100, 100), Color.Pink, 16); sb.End();
Leonardo Seccia

Kết cấu của bạn chỉ là một pixel màu xanh, phương pháp này giả định các góc tròn là một phần của kết cấu của bạn.
sdgfsdh

xin lỗi - rất mới đối với nền tảng ... cảm ơn vì đã quay lại với tôi rất nhanh
Leonardo Seccia
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.