【问题标题】:Efficiently draw a grid in Windows Forms在 Windows 窗体中高效地绘制网格
【发布时间】:2010-05-02 13:02:57
【问题描述】:

我正在用 C# 编写康威生命游戏的实现。这是我用来绘制网格的代码,它在我的 panel_Paint 事件中。 g 是图形上下文。

for (int y = 0; y < numOfCells * cellSize; y += cellSize)
{
     for (int x = 0; x < numOfCells * cellSize; x += cellSize)
     {
          g.DrawLine(p, x, 0, x, y + numOfCells * cellSize);
          g.DrawLine(p, 0, x, y + size * drawnGrid, x);
     }
}

当我运行我的程序时,它在完成绘制网格之前没有响应,在 numOfCells = 100 & cellSize = 10 时需要几秒钟。删除所有乘法会使其更快,但速度不会很快。

有没有更好/更有效的方法来绘制我的网格?

谢谢

【问题讨论】:

  • 如果您只是在 IDE 中单步执行此操作,您将能够回答您自己的问题。
  • 这太有趣了。我只是认真地为game of life 编写了添加单元格的东西,并搜索了一种绘制网格的方法。我看到的第一件事是有人要求为game of life 绘制网格:D。

标签: c# optimization graphics drawing


【解决方案1】:

你不需要嵌套循环:

for (int i = 0; i < numOfCells; i++)
{
    // Vertical
    g.DrawLine(p, i * cellSize, 0, i * cellSize, numOfCells * cellSize);
    // Horizontal
    g.DrawLine(p, 0, i * cellSize, numOfCells * cellSize, i * cellSize);
}

【讨论】:

    【解决方案2】:

    问题是您正在为每个 Y 坐标绘制 X 线。您可以先在一个循环中渲染 Y 线,然后在另一个循环中渲染 X 线来简化。

    这是一个简单的例子

      for (int y = 0; y < numOfCells; ++y)
      {
        g.DrawLine(p, 0, y * cellSize, numOfCells * cellSize, y * cellSize);
      }
    
      for (int x = 0; x < numOfCells; ++x)
      {
        g.DrawLine(p, x * cellSize, 0, x * cellSize, numOfCells * cellSize);
      }
    

    随着你的进步,你可以使用双缓冲来减少任何闪烁等。看看 Control.SetStyle http://msdn.microsoft.com/en-us/library/system.windows.forms.control.setstyle.aspx

    【讨论】:

    • 或者在同一个循环中,如果网格是正方形;)
    • @Thomas,同意。我在回答时遇到了这个问题,我的观点是 OP 没有看到基本问题,这就是为什么我首先选择显而易见的问题,然后在理解问题后从那里改进。但只是一个意见。
    • 呃,我不知道我在想什么嵌套循环。谢谢您的帮助。开启双缓冲好像没什么作用,不过没关系,我启动的时候只有一点点闪烁。
    • @Joel,你应该看看 Thomas 解决方案,它更加优化,因为它只执行一个循环,而不是上面的 2 个。
    • 这实际上是我使用的解决方案,因为我的网格是正方形。但是,我选择了您的解决方案作为答案,因为您提供了更多细节。
    【解决方案3】:

    使用网格线创建一个 100x100 像素的位图图像,并将其显示在图块中。
    确保瓷砖之间的接缝不会导致网格空间不连续。

    【讨论】:

      【解决方案4】:

      为此,您应该查看 XNA。在呈现的窗口中而不是在 WinForm 中执行此操作可能会更有效。

      XNA 是 C# 的游戏框架。 更多信息请访问http://creators.xna.com/

      【讨论】:

        【解决方案5】:

        我知道这已经很晚了,但在这里......

        for (int x = 0; x < 20; x++)
        {
            for (int y = 0; y < 20; y++)
            {
                g.drawRectangle(Pens.Black, x * 32, y * 32, 32, 32);
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-09-28
          • 1970-01-01
          • 1970-01-01
          • 2016-05-26
          • 2020-08-04
          相关资源
          最近更新 更多