我目前正在从事一个学校项目,该项目基本上是一个涉及 GDI-Winforms 动画的游戏。 我选择我的游戏类似于越狱,在这种游戏中,你试图逃离 jail ,而拿着手电筒的守卫在房间里走来走去。
所以,我有代表守卫的 Guard 类,并且有 A Path 可以走。此外,防护罩可以 90 度旋转。角度。 (动画到一定程度) 当我旋转守卫时,我实际上旋转了通过 Form_Paint 事件传递的 Graphics 对象:
void Game_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
ply.Draw(e.Graphics); // Draws the player
grd.Draw(e.Graphics); // Draws the guard
e.Graphics.DrawPolygon(Pens.Red, grd.GetPath()); // Draws the guard's path
}
当我只对付一名后卫时,效果很好。顺利,并做了他应该做的事情。 当我试图再增加 1 名 guard 时,他们开始 panic 。很快我发现这是因为我派两个守卫去绘制相同的图形实例。这也意味着,他们都在旋转它。 假设一个旋转 -90,另一个旋转,但他的 angle 类成员变量不会是 -90,那么一切都乱套了。
图形旋转方法(位于守卫类内部):
public Graphics RotateGuard(Graphics g, Point pivot, float angle) // returns the rotated Graphics object
{
if (!float.IsNaN(angle))
{
using (Matrix m = new Matrix())
{
m.RotateAt(angle, pivot);
g.Transform = m;
}
}
return g;
}
接下来我做的是给他们每个人 this.CreateGraphics()
。
void Game_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
ply.Draw(e.Graphics); // Draws the player
foreach (Guard grd in this.guards )
{
grd.Draw(this.CreateGraphics()); // Draws the guard
e.Graphics.DrawPolygon(Pens.Red, grd.GetPath()); // Draws the guard's path
}
}
然后一切正常。唯一的问题是,GPU 处理起来似乎真的很繁重。它比他应该绘制的每 5 帧少绘制一次守卫。
我用谷歌搜索但找不到任何东西,除了人们说“没有必要克隆图形对象”,但我仍然想不出任何更好的工作解决方案。
我怎样才能很好地解决这个问题呢? 提前致谢。
最佳答案
CreateGraphics()
是一个非常糟糕的主意。您应该对 PaintEventArgs
传递的 Graphics
进行所有绘图。所以你的初始代码就好了。但是,您需要做的是确保每个在其 Draw
方法中接收到 Graphics
的对象在完成其工作后保持不变。这可以通过使用 Graphics.Save 来实现和 Graphics.Restore像这样
class Guard
{
public void Draw(Graphics g)
{
var state = g.Save();
try
{
// The actual drawing code
}
finally
{
g.Restore(state);
}
}
}
关于C#-WinForms ||用于旋转的图形的多个实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33953369/