使用XNA以编程方式绘制线条的问题已涵盖here。但是,我希望允许用户在画布上绘图,就像绘制应用程序一样,如MS Paint。
这当然要求鼠标指针位置的每个x和/或y坐标发生变化,以便在画布上以蜡笔颜色实时绘制线条的另一个“点”。
在鼠标移动事件中,为了逐点绘制线,XNA API的注意事项是什么?当然,从字面上看,我并不是这样画线,而是一系列“点”。每个“点”可以并且可能应该大于单个像素。想想用毡尖笔画画。
答案 0 :(得分:7)
您提供的文章提出了一种使用基元绘制线条的方法;换句话说,矢量图形。像Paint这样的应用程序主要是基于像素(尽管像Photoshop这样的更高级的软件具有矢量和光栅化功能)。
由于你希望它是“类似绘画”,我肯定会采用基于像素的方法:
我在答案的底部添加了我正在使用的图像类的粗略草稿。但无论如何,代码应该是不言自明的。
如前所述,您还需要实现一种方法,将图像转换为Texture2D并将其绘制到屏幕上。
首先,我们创建一个新的10x10图像并将所有像素设置为白色。
var image = new Grid<Color>(10, 10);
image.Initilaize(() => Color.White);
接下来我们设置一个画笔。画笔本质上只是一个应用于整个图像的功能。在这种情况下,该函数应将指定圆内的所有像素设置为深红色。
// Create a circular brush
float brushRadius = 2.5f;
int brushX = 4;
int brushY = 4;
Color brushColor = new Color(0.5f, 0, 0, 1); // dark red
现在我们应用画笔。请参阅我的答案,了解如何identify the pixels inside a circle。 您可以使用鼠标输入进行画笔偏移,并使用户能够实际绘制位图。
double radiusSquared = brushRadius * brushRadius;
image.Modify((x, y, oldColor) =>
{
// Use the circle equation
int deltaX = x - brushX;
int deltaY = y - brushY;
double distanceSquared = Math.Pow(deltaX, 2) + Math.Pow(deltaY, 2);
// Current pixel lies inside the circle
if (distanceSquared <= radiusSquared)
{
return brushColor;
}
return oldColor;
});
您还可以在画笔颜色和旧像素之间进行插值。例如,您可以通过让混合量取决于画笔中心与当前像素之间的距离来实现“软”画笔。
为了绘制手绘线,只需重复应用刷子,每次使用不同的偏移量(取决于鼠标移动):
我显然跳过了一些必要的属性,方法和数据验证,但你明白了这个想法:
public class Image
{
public Color[,] Pixels { get; private set; }
public Image(int width, int height)
{
Pixels= new Color[width, height];
}
public void Initialize(Func<Color> createColor)
{
for (int x = 0; x < Width; x++)
{
for (int y = 0; y < Height; y++)
{
Pixels[x, y] = createColor();
}
}
}
public void Modify(Func<int, int, Color, Color> modifyColor)
{
for (int x = 0; x < Width; x++)
{
for (int y = 0; y < Height; y++)
{
Color current = Pixels[x, y];
Pixels[x, y] = modifyColor(x, y, current);
}
}
}
}