如何使用XNA创建类似Paint的应用程序? [英] How to create Paint-like app with XNA?
问题描述
在此处中涉及了以编程方式使用XNA绘制线条的问题. >.但是,我希望允许用户像使用MS Paint这样的绘图应用程序一样在画布上进行绘图.
The issue of programmatically drawing lines using XNA has been covered here. However, I want to allow a user to draw on a canvas as one would with a drawing app such as MS Paint.
这当然需要鼠标指针位置中的每个x和/或y坐标更改,以导致在画布上以蜡笔颜色实时绘制线条的另一个点".
This of course requires each x and/or y coordinate change in the mouse pointer position to result in another "dot" of the line being drawn on the canvas in the crayon color in real time.
在鼠标移动事件中,为了逐点绘制线条,XNA API需要考虑哪些因素?从字面上看,当然,我并不是在画一条线,而是一连串的点".每个点"可以而且可能应该大于单个像素.考虑用毡尖的笔绘画.
In the mouse move event, what XNA API considerations come into play in order to draw the line point by point? Literally, of course, I'm not drawing a line as such, but rather a sequence of "dots". Each "dot" can, and probably should, be larger than a single pixel. Think of drawing with a felt tip pen.
推荐答案
您提供的文章建议了一种使用基本体绘制线条的方法;换句话说,矢量图形.诸如Paint之类的应用程序大多是基于 pixels 的(即使像Photoshop这样的更高级的软件也具有矢量和光栅化功能).
The article you provided suggests a method of drawing lines with primitives; vector graphics, in other words. Applications like Paint are mostly pixel based (even though more advanced software like Photoshop has vector and rasterization features).
由于您希望它是"Paint-like",所以我绝对会使用基于像素的方法:
Since you want it to be "Paint-like" I would definitely go with the pixel based approach:
- 创建颜色值的网格. (扩展 System.Drawing.Bitmap 类或实现自己的.)
- 开始(游戏)循环:
- 处理输入并相应地更新网格中的颜色值.
- 将位图转换为Texture2D .
- 使用sprite批处理或自定义渲染器将纹理绘制到屏幕上.
- Create a grid of color values. (Extend the System.Drawing.Bitmap class or implement your own.)
- Start the (game) loop:
- Process input and update the color values in the grid accordingly.
- Convert the Bitmap to a Texture2D.
- Use a sprite batch or custom renderer to draw the texture to the screen.
在位图上绘制
我在答案的底部添加了我正在使用的图像类的粗略草稿.但是无论如何,代码应该是不言自明的.
Drawing on the bitmap
I added a rough draft of the image class I am using here at the bottom of the answer. But the code should be quite self-explanatory anyways.
如前所述,您还需要实现一种将图像转换为Texture2D并将其绘制到屏幕上的方法.
As mentioned before you also need to implement a method for converting the image to a Texture2D and draw it to the screen.
首先,我们创建一个新的10x10图像,并将所有像素设置为白色.
First we create a new 10x10 image and set all pixels to white.
var image = new Grid<Color>(10, 10);
image.Initilaize(() => Color.White);
接下来,我们设置一个画笔.本质上,画笔只是应用于整个图像的功能.在这种情况下,该功能应将指定圆圈内的所有像素设置为深红色.
Next we set up a brush. A brush is in essence just a function that is applied on the whole image. In this case the function should set all pixels inside the specified circle to a dark red color.
// 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
现在,我们应用画笔.有关如何识别圆圈内的像素,请参见我的此类解答. 您可以使用鼠标输入作为笔刷偏移量,并允许用户实际在位图上绘制.
Now we apply the brush. See this SO answer of mine on how to identify the pixels inside a circle. You can use mouse input for the brush offsets and enable the user to actually draw on the bitmap.
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;
});
您还可以在笔刷颜色和旧像素之间进行插值.例如,您可以通过使混合量取决于画笔中心与当前像素之间的距离来实现软"画笔.
You could also interpolate between the brush color and the old pixel. For example, you can implement a "soft" brush by letting the blend amount depend on the distance between the brush center and the current pixel.
要绘制徒手线条,只需重复应用画笔,每次都有不同的偏移量(取决于鼠标的移动):
In order to draw a freehand line simply apply the brush repeatedly, each time with a different offset (depending on the mouse movement):
我显然跳过了一些必要的属性,方法和数据验证,但您明白了:
I obviously skipped some necessary properties, methods and data validation, but you get the idea:
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);
}
}
}
}
这篇关于如何使用XNA创建类似Paint的应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!