要澄清我的问题我的意思..我在使用.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()方法?
答案 0 :(得分:1)
这两种方法严重不同(第二种方法是首选)。
首先 - 在您的方法中,每次需要绘制内容时都会创建新的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);
}
所以你仍然使用Paint事件处理程序中的grahics对象,但只是将它传递给绘图方法。