创建圆角矩形Texture2D

我正在构建一个带有对话框的游戏,我希望能够在程序上为这些盒子生成纹理,其风格与最终幻想系列非常相似(想想最终幻想VII )。 这是我到目前为止的代码片段:

public class DialogBox { public Rectangle BoxArea { get; set; } public List BoxColors { get; set; } public List BorderColors { get; set; } public int BorderThickness { get; set; } public int BorderRadius { get; set; } private Texture2D texture; public void CreateBackdrop(ref GraphicsDevice graphics) { texture = new Texture2D(graphics, BoxArea.Width, BoxArea.Height, true, SurfaceFormat.Color); Color[] color = new Color[texture.Width * texture.Height]; for(int x = 0; x < texture.Width; x++) { for(int y = 0; y < texture.Height; y++) { switch(BoxColors.Count) { case 4: Color leftColor = Color.Lerp(BoxColor[0], BoxColor[1], (y / (texture.Height - 1))); Color rightColor = Color.Lerp(BoxColor[2], BoxColor[3], (y / (texture.Height - 1))); color[x + y * texture.Width] = Color.Lerp(leftColor, RightColor, (x / (texture.Width - 1))); break; case 2: color[x + y * texture.Width] = Color.Lerp(BoxColors[0], BoxColors[1], (x / (texture.Width - 1))); break; default: color[x + y * texture.Width]; break; } } } texture.SetData(color); } } 

我要找的是以下内容:

  • 4路渐变色(已实现)
  • 圆角矩形
  • 边框与渐变

任何帮助将不胜感激。

我通过这个问题找出了矩形。

我弄清楚我遇到了什么麻烦; 计算角弧。 我想到的是,人们可以使用距离点的距离来理解绘制边界的方式,而不是使用数学来计算圆内的点。 下面我发布了生成圆角矩形的代码。

 public Texture2D CreateRoundedRectangleTexture(GraphicsDevice graphics, int width, int height, int borderThickness, int borderRadius, int borderShadow, List backgroundColors, List borderColors, float initialShadowIntensity, float finalShadowIntensity) { if (backgroundColors == null || backgroundColors.Count == 0) throw new ArgumentException("Must define at least one background color (up to four)."); if (borderColors == null || borderColors.Count == 0) throw new ArgumentException("Must define at least one border color (up to three)."); if (borderRadius < 1) throw new ArgumentException("Must define a border radius (rounds off edges)."); if (borderThickness < 1) throw new ArgumentException("Must define border thikness."); if (borderThickness + borderRadius > height / 2 || borderThickness + borderRadius > width / 2) throw new ArgumentException("Border will be too thick and/or rounded to fit on the texture."); if (borderShadow > borderRadius) throw new ArgumentException("Border shadow must be lesser in magnitude than the border radius (suggeted: shadow <= 0.25 * radius)."); Texture2D texture = new Texture2D(graphics, width, height, false, SurfaceFormat.Color); Color[] color = new Color[width * height]; for (int x = 0; x < texture.Width; x++) { for (int y = 0; y < texture.Height; y++) { switch (backgroundColors.Count) { case 4: Color leftColor0 = Color.Lerp(backgroundColors[0], backgroundColors[1], ((float)y / (width - 1))); Color rightColor0 = Color.Lerp(backgroundColors[2], backgroundColors[3], ((float)y / (height - 1))); color[x + width * y] = Color.Lerp(leftColor0, rightColor0, ((float)x / (width - 1))); break; case 3: Color leftColor1 = Color.Lerp(backgroundColors[0], backgroundColors[1], ((float)y / (width - 1))); Color rightColor1 = Color.Lerp(backgroundColors[1], backgroundColors[2], ((float)y / (height - 1))); color[x + width * y] = Color.Lerp(leftColor1, rightColor1, ((float)x / (width - 1))); break; case 2: color[x + width * y] = Color.Lerp(backgroundColors[0], backgroundColors[1], ((float)x / (width - 1))); break; default: color[x + width * y] = backgroundColors[0]; break; } color[x + width * y] = ColorBorder(x, y, width, height, borderThickness, borderRadius, borderShadow, color[x + width * y], borderColors, initialShadowIntensity, finalShadowIntensity); } } texture.SetData(color); return texture; } private Color ColorBorder(int x, int y, int width, int height, int borderThickness, int borderRadius, int borderShadow, Color initialColor, List borderColors, float initialShadowIntensity, float finalShadowIntensity) { Rectangle internalRectangle = new Rectangle((borderThickness + borderRadius), (borderThickness + borderRadius), width - 2 * (borderThickness + borderRadius), height - 2 * (borderThickness + borderRadius)); if (internalRectangle.Contains(x, y)) return initialColor; Vector2 origin = Vector2.Zero; Vector2 point = new Vector2(x, y); if (x < borderThickness + borderRadius) { if (y < borderRadius + borderThickness) origin = new Vector2(borderRadius + borderThickness, borderRadius + borderThickness); else if (y > height - (borderRadius + borderThickness)) origin = new Vector2(borderRadius + borderThickness, height - (borderRadius + borderThickness)); else origin = new Vector2(borderRadius + borderThickness, y); } else if (x > width - (borderRadius + borderThickness)) { if (y < borderRadius + borderThickness) origin = new Vector2(width - (borderRadius + borderThickness), borderRadius + borderThickness); else if (y > height - (borderRadius + borderThickness)) origin = new Vector2(width - (borderRadius + borderThickness), height - (borderRadius + borderThickness)); else origin = new Vector2(width - (borderRadius + borderThickness), y); } else { if (y < borderRadius + borderThickness) origin = new Vector2(x, borderRadius + borderThickness); else if (y > height - (borderRadius + borderThickness)) origin = new Vector2(x, height - (borderRadius + borderThickness)); } if (!origin.Equals(Vector2.Zero)) { float distance = Vector2.Distance(point, origin); if (distance > borderRadius + borderThickness + 1) { return Color.Transparent; } else if (distance > borderRadius + 1) { if (borderColors.Count > 2) { float modNum = distance - borderRadius; if (modNum < borderThickness / 2) { return Color.Lerp(borderColors[2], borderColors[1], (float)((modNum) / (borderThickness / 2.0))); } else { return Color.Lerp(borderColors[1], borderColors[0], (float)((modNum - (borderThickness / 2.0)) / (borderThickness / 2.0))); } } if (borderColors.Count > 0) return borderColors[0]; } else if (distance > borderRadius - borderShadow + 1) { float mod = (distance - (borderRadius - borderShadow)) / borderShadow; float shadowDiff = initialShadowIntensity - finalShadowIntensity; return DarkenColor(initialColor, ((shadowDiff * mod) + finalShadowIntensity)); } } return initialColor; } private Color DarkenColor(Color color, float shadowIntensity) { return Color.Lerp(color, Color.Black, shadowIntensity); } 

使用上面的所有代码,结果如下: 行动中的圆角纹理