2011-03-28 39 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