c#.网在Paint事件处理程序之外绘图是不好的做法吗?

本文关键字:绘图 Paint 网在 事件处理 程序 | 更新日期: 2023-09-27 17:50:56

为了澄清我的问题的意思…当我使用。net框架在c#中制作游戏时,我习惯于执行自己的DrawScene()方法,并在我想要重新绘制游戏图像时调用它(基本上是在游戏中的任何实例移动或改变其形状/状态之后),如下所示:

private void DrawScene()
{
    Graphics g = this.CreateGraphics();
    g.Clear(Color.Black);
    g.DrawImage(myBitmap, 0, 0);
    g.Dispose();
}

通过这样做,在我的Paint事件处理程序中,我所做的就是:

private void Form1_Paint(object sender, PaintEventArgs e)
{
    DrawScene();
}

,例如,当我想在玩家做出一些移动后重新绘制时,我只需以同样的方式调用DrawScene():

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Keycode == Keys.Up)
    {
        hero.y -= 5;
    }
    DrawScene();
}

那样做和这样做(我注意到大多数人都这样做)有什么区别吗?

private void Form1_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.Clear(Color.Black);
    e.Graphics.DrawImage(myBitmap, 0, 0);
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Keycode == Keys.Up)
    {
        hero.y -= 5;
    }
    this.Invalidate();
}

对不起,如果我说得太多了,但我只是想把我的问题弄清楚。

所以,如果上面两种情况的绘图方式完全相同(从图形的角度来看),并且保持我在第一种情况下的通常实现是没有害处的。那么什么时候使用invalidate()方法最好呢?

c#.网在Paint事件处理程序之外绘图是不好的做法吗?

这两种方法差别很大(首选第二种)。

首先-在你的方法,你是创建新的Graphics对象,每次你需要画一些东西,而在Paint事件处理程序,你每次使用相同的图形对象。

这增加了内存的使用(因为重绘可能会非常频繁地发生),也因为你没有处理你正在创建的图形(基本上你应该对任何实现IDisposable的对象做这件事,你不再需要使用)——图形使用的系统资源没有被释放。

此外,您的窗体可以重新绘制,而不是手动调用,但在一些其他情况下(重叠的其他窗口,显示/隐藏等)。如果你的绘画将在Paint处理程序中完成,那么它们将自动完成,但在你的"第一"方法中,除非你手动调用你的绘画方法,否则不会自动完成。

所以基本上最好在Paint事件处理程序中绘制所有内容(并调用Invalidate甚至Refresh来强制重新绘制),而不是在单独的方法中手动绘制。

有时候(如果你的绘图需要很多代码,并且可以在逻辑上分成几个部分),这样处理会更好:

private void DrawScene(Graphics g)
{
    g.Clear(Color.Black);
    g.DrawImage(myBitmap, 0, 0);
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
    DrawScene(e.Graphics);
    DrawSomething(e.Graphics);
}

所以你仍然使用绘图事件处理程序中的图形对象,但只是将其传递给绘图方法。