2012-06-01 40 views
0

我已經實現了一個簡單的多線程服務器\客戶端遊戲作爲我大學的任務。爲什麼我的表單閃爍

上除了主線程客戶端

有:

1線程負責畫圖玩的理由和形式對玩家的。

2線程與服務器通信以發送方向和接收的位置和其他信息。

首先我使用的調用技術,但因爲我用的是它的圖形配置後,沒有工作。看到Draw on a form by a separate thread

所以爲了避免和規範引出線,我只是升旗「的Invalidate」引出線上的每一個具體的時間,離開它的實際操作主線程:

public Form1() 
    { 
     SetStyle(ControlStyles.OptimizedDoubleBuffer, true); 
     InitializeComponent(); 
    } 

    private void Draw() 
    { 
     while (true) 
     { 
      Thread.Sleep(200); 
      Invalidate(); 
     } 
    } 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     base.OnPaint(e); 

     if (map.hasGraph) 
     { 
      map.Draw(e.Graphics); 
      if (this.Index != null) 
       e.Graphics.FillRectangle(Brush, Rectangle); 
      if (OpponentIndex != null) 
       e.Graphics.FillRectangle(OpponentBrush, OpponentRectangle); 
     } 
    } 

這裏的問題是,形式是任意的方式閃爍,即使我使用雙緩衝,當我增加睡眠時間引出線減少閃爍,但我認爲200ms的已經太多了。 有什麼建議嗎?

[編輯]

我意識到,我是從代碼和這使得問題的屬性編輯器設置雙緩衝標誌(這可能是一個愚蠢的想法),但我花了一個半小時的測試我代碼與其中一個標誌和他們兩個,當我從兩個地方設置雙緩衝標誌時引發的問題,我的問題已解決,但現在我需要知道這是否可以解決它。

+2

顯示您如何使用雙緩衝,有一個爲沒有證據它在片段中。 –

+0

這可能會發生,如果你把它抹掉,然後將你的緩衝圖像繪製到它上面。而不是最後一個緩衝圖像。 – Doomsknight

+0

我們可以假設這是winforms嗎?什麼是繪畫,繪畫盒,面板的控制? –

回答

2

它必須得到每況愈下的時間越長它運行嗎?

每次你的程序描繪它啓動畫,其中有一個無限循環,它調用paint,這就要求再拉一個無限循環。看來你在這裏有一個循環引用。如果我可以假設Map.Draw是私人無效的draw()

有一個更容易的解決了這個,一切都畫成位圖然後繪製bitpmap在OnPaint事件。

Bitmap buffer=new Bitmap(this.Width, this.Height); //make sure to resize the bitmap during the Form.Onresize event 
Form1() 
{ 
    InitializeComponent(); 
    Timer timer=new Timer(); 
    timer.Interval= 100; 
    timer.Tick+=...... 
    timer.Start() 
} 

//the Timer tick event 
private void timer_tick(.... 
{ 
    if (map.hasGraph) 
    { 
     using (Graphics g = Graphics.FromImage(buffer)) 
     { 
      //You might need to clear the Bitmap first, and apply a backfround color or image 
      //change color to whatever you want, or don't use this line at all, I don't know 
      g.Clear(Color.AliceBlue); 

      if (this.Index != null) 
       g.FillRectangle(Brush, Rectangle); 
      if (OpponentIndex != null) 
       g.FillRectangle(OpponentBrush, OpponentRectangle); 
     } 
    panel1.BackgroundImage=buffer; 
    } 
} 

注意我沒有語法準確性進行測試。

+0

如果你願意,我可以更好地解釋這一點。但它應該消除很多閃爍問題,我將頻率設置爲每秒10幀,將刻度值更改爲任何您想要的值,以每秒5幀的速度更改該值。更改timer.interval =(以毫秒爲單位) –

+0

I可能沒有很清楚地描述這個想法,我相信我沒有循環引用,因爲draw方法是一個獨立線程的開始方法,所以沒有人調用它,但是負責任的線程。任何看到的版本。 –

0
  1. 創建一個圖像,將用於存儲最後呈現的場景。
  2. 創建新的線程蒙山將繪製到圖像
  3. 創建一個定時器whitch將刷新圖像
  4. 複製圖像,從而在計時器滴答