2011-03-28 41 views
1

我写了一个程序,绘制了一个棋盘游戏的具体情况(我认为它被称为“Ludo”)。现在我可以画出所有的场地和棋子等,但如果一个棋子移动了,我必须重画那个棋子。问题是,当我这样做时,屏幕会闪烁很短的时间。这可能是因为我首先清除了所有的字段和棋子,然后重新绘制它们(我会改进它,但问题会以更小的形式出现,我认为)仍然会出现,屏幕在我清除之间闪烁一切,直到我重绘了一切。有没有办法告诉C#在我告诉它之前不要重新绘制,即使我专门调用了像this.Controls.Clear()之类的东西?在函数的持续时间内强制不绘画

我已经用this.SuspendLayout()试过了,因为名字暗示它应该这样做,但那不行。

+2

刚试过this.DoubleBuffered = true;它确实减少了闪烁,但它仍然没有消失 – teuneboon 2011-03-28 20:59:35

+0

这里描述了更多更具体的缓冲选项,这对我的图表绘制项目非常有用。点击:http://www.codeproject.com/KB/graphics/DoubleBuffering.aspx – thmshd 2011-03-28 21:03:33

+0

如果.NET双缓冲实现不适合你,你应该尝试实现你自己的缓冲机制,将你的绘图缓存到位图,然后渲染整个位图。您正在经历屏幕撕裂,因为您基本上迫使您的显示设备连续快速刷新屏幕的多个部分。您希望最小化对显示器的绘制请求数量。 – 2011-03-28 21:04:28

回答

4

在Winforms自定义图形中,闪烁总是会有点问题。

尝试此操作:不要在某处绘制棋子的位置,而是将它们绘制到位图上。全部完成后,只需将表单上的PictureBox图像更改为位图即可。该表单将使用新的图像重新绘制。您可以使用两个Bitmap对象(无可否认这些对象相当大)并且每次都清理它们以避免程序成为内存管理器。瞧,你现在有“页面翻转”图形,可以绘制和显示独立于其他请求重绘表单。

+0

好主意,我会试试这个。不得不等待几分钟,然后我才能接受这个答案。 – teuneboon 2011-03-28 21:06:52

0

当您告诉它清除所有内容然后重新绘制它时,它会像那样闪烁。但是,当你移动一个棋子时,你不会在新的空间中画出棋子,并在原来的位置上画空白。这将移动棋子而不刷新整个屏幕或清除所有内容。

另外我认为你所说的游戏是国际象棋。这是我与Pawns认识的唯一一场比赛,我从来没有听说过Ludo。 :P

+0

Ludo是游戏的意大利人 – sehe 2011-03-28 21:01:18

+0

http://en.wikipedia.org/wiki/Ludo_%28board_game%29 – KeithS 2011-03-28 21:02:45

+1

现在有一个叫做互联网的疯狂的东西,事实证明这对发现事情很有用[你从来没有听说过](http:///en.wikipedia.org/wiki/Ludo_%28board_game%29)。 :) – 2011-03-28 21:02:49

0

最好的解决方案是KeithS,但更快的选择可能是:每个部分有两个图像,一个在白色,一个在黑色,加上两个空方块。在移动过程中,在离开的广场上放置适当的空白广场,并在目的广场上放置适当的部分。这是一个零闪烁,老年龄(这么快)的做法:)

0

虽然@ KeightS的解决方案是好的,我宁愿通过能够暂停解决它/简历图纸一起:

public partial class Form1 : Form 
{ 
    private bool suspendDraw; 

    public Form1() 
    { 
     this.InitializeComponent(); 
    } 

    public void SuspendDraw() 
    { 
     this.suspendDraw = true; 
    } 

    public void ResumeDraw() 
    { 
     this.suspendDraw = false; 
    } 

    private const int WM_PAINT = 0x000F; 

    protected override void WndProc(ref Message m) 
    { 
     if ((m.Msg != WM_PAINT) || (!this.suspendDraw && m.Msg == WM_PAINT)) 
     { 
      base.WndProc(ref m); 
     } 
    } 

} 

你只需要调用SuspendDraw/ResumeDraw()方法来控制允许绘画。

+0

尽管这比doublebuffer的闪烁更少,但它仍然会产生微小的闪烁,我可能总会有闪烁,但是我宁愿使用像KeithS那样的“黑客”解决方案,谢谢你的回答虽然 – teuneboon 2011-03-28 21:14:10

+0

@teuneboon - 是'DoubleBuffering'打开这个方法,因为它应该是真实的,当使用这种方法。 KeithS的解决方案*是*双缓冲......已经内置到.NET中。如果您担心这样的“黑客”解决方案,请不要使用GDI +作为图形,因为它不是硬件加速的! – TheCloudlessSky 2011-03-28 21:16:02