有什么方法可以通过图元(直线)在XNA中渲染的矩形上制作圆角?我想让UI变得比以前更漂亮,并且我希望代码灵活,并且不涉及太多纹理。
基本上:对线条使用一种纹理,对线条的圆端使用一种纹理。适当地旋转和缩放使用这两个纹理的精灵。
—
Olhovsky 2011年
有什么方法可以通过图元(直线)在XNA中渲染的矩形上制作圆角?我想让UI变得比以前更漂亮,并且我希望代码灵活,并且不涉及太多纹理。
Answers:
另一种方法是使用“按钮拉伸”(也称为“框拉伸”或“九补丁”)。本质上,您创建的图像由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();