Чи є якийсь спосіб зробити закруглені кути на прямокутнику, виведеному в XNA за допомогою примітивів (ліній-смужок)? Я хочу зробити свій інтерфейс трохи більш фантазійним, ніж він є, і я хотів би, щоб код був гнучким, без занадто багато текстур.
Чи є якийсь спосіб зробити закруглені кути на прямокутнику, виведеному в XNA за допомогою примітивів (ліній-смужок)? Я хочу зробити свій інтерфейс трохи більш фантазійним, ніж він є, і я хотів би, щоб код був гнучким, без занадто багато текстур.
Відповіді:
Ви можете зробити свій примітив і зробити шейдер, який може створити ці закруглені кути.
Ось простий піксельний шейдер у псевдокоді, який може намалювати округлий квадрат:
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)
Результат цього піксельного шейдера:
Якщо ви використовуєте шейдери, ви можете зробити дійсно фантазійний інтерфейс, навіть анімований.
Для мене чудовою для прототипу простих піксельних шейдерів є програма EvalDraw
Інший спосіб зробити це - використовувати "розтягування кнопки" (також називається "розтягнення коробки" або "дев'ять патчів"). По суті, ви створюєте зображення, яке складається з 9 частин:
Щоб намалювати цю кнопку будь-якого розміру, ви намалюєте кожен шматок (зверху вниз, зліва направо):
width - ((1) + (2)).Width
) у верхній частині цільового прямокутника, зсунувши ліворуч на ширину (1).height - ((1) + (2)).Height
) ліворуч від прямокутника призначення, верхній зсув на висоту (1).Якщо ви подивитесь на кнопку, то побачите, що не має значення, якщо (2), (5) і (7) масштабуватись горизонтально (адже це по суті пряма лінія); таким же чином (4), (5) і (6) можна масштабувати вертикально, не впливаючи на якість зображення.
Ось код для підходу "дев'ять патчів":
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);
}
}
Він викликається як:
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);
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();