我正在开发游戏,但目前正在运行基准测试。
如果有人能在这个问题上帮助我,我将不胜感激。
我正在做的是,当我单击开始按钮时,使用以下代码在面板上触发paint事件:
private void startToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
pnlArea.Invalidate();
}
catch (Exception)
{
throw;
}
}
然后在绘画事件中执行此操作:
private void pnlArea_Paint(object sender, PaintEventArgs e)
{
try
{
stopwatch = new Stopwatch();
// Begin timing
stopwatch.Start();
if (gameStatus == GameStatus.PlaceHead)
{
e.Graphics.DrawImage(dictHead["HeadRight"], 100, 100, 15, 15);
}
//e.Graphics.Clear(Color.White);
if (gameStatus == GameStatus.GameTest)
{
int x = 0;
int y = 0;
for (int i = 0; i < 5000; i++)
{
x += 15;
if (x > 1000)
{
x = 0;
y += 15;
}
e.Graphics.DrawImage(body.Value, x, y, 15, 15);
}
}
toolTimer.Text = Math.Round((stopwatch.Elapsed.TotalMilliseconds / 1000), 2).ToString() + "s";
// Stop timing
stopwatch.Stop();
}
catch (Exception)
{
throw;
}
}
这是我在上面的代码中绘制的正文部分:
这是确切的尺寸-> 15像素x 15像素
但这有时最多需要1.2秒!!!
有什么办法可以改善吗?
这是最终结果屏幕的示例:
最佳答案
您需要考虑如何最大程度地减少绘制绘图的次数。当前,您绘制5000个小盒子以生成网格。每次绘制一个框时,您都要执行几条指令,然后调用图形方法来渲染缩放的图像。每个网格正方形的开销很大。
因此,您首先要寻找的是找到更有效的图像绘制方法-例如,DrawImageUnscaled
的工作速度可能比DrawImage
更快,并且可以达到所需的结果。但这是对效率低下的算法的优化-要获得真正的性能优势,您需要做的就是查看是否可以采用新的,效率更高的算法。
如果必须使用位图进行渲染,请查看图案的重复方式-是否可以制作更大的位图来提供4x4或16x16的一组单元格,并进行渲染?还是代表整个列或行的位图?然后,您可以使用50个调用而不是5000个调用进行渲染。
但是,如果您不需要使用位图渲染,则可以做得更好。例如,如果您使用gfx.Clear(backgroundColor)
,然后向下和横跨绘制约140条黑线,则仅用141个调用就可以创建相同的显示。或者,如果您绘制约70个矩形,则每个调用可以有效地执行2条线,这大大减少了您必须进行的方法调用次数,并允许图形系统使用高度优化的线渲染和矩形渲染例程来突发绘制更多像素。 (实际上,由于系统知道直线始终是垂直和水平的,因此矩形的求解速度可能比通用直线快得多)。
(如果有些位不遵循此模式,那么您是否仍可以渲染背景网格,然后在顶部绘制更改?)
接下来,如果仅一小幅图像从一帧更改为下一帧,则即使其中4999个未更改,算法也将绘制5,000个框(或70个矩形,当1个就足够了)。因此,如果您(a)仅使 View 中需要更改的部分无效,并且(b)编写渲染例程来确定哪些网格正方形位于剪辑边界之外,因此毫无意义地绘制,则可以大大改善问题。这样可以减少更新到绘制1个矩形,而不是每帧5000个。 (另一种实现相同目的的方法是将图像保留在屏幕外的位图中,然后在其上绘制更改。将其渲染到主屏幕显示时,图形卡将为您裁剪并获得相同的结果-重绘速度更快)
都是通过“懒惰”并横向思考尽可能少的工作来实现相同的显示。 (让计算机运行得更快总是归结为要求它做得更少)