2013-05-14 60 views
2

我編程我的C#學校項目一個俄羅斯方塊克隆。我使用Microsoft Visual Studio 2012遊戲本身作爲塊的二維陣列來實現(名單塊列表的),每塊都有其自己的紋理(BMP圖像)。我正在繪製整個數組到一個PictureBox控件,這是問題開始的地方。更新PictureBox上的圖像(移動/旋轉活動形狀)時,遊戲會略微滯後。我試圖畫一個Panel控件,但結果是一樣的。我有一個粗略的想法,可能會導致滯後,但我不知道如何擺脫它。C#俄羅斯方塊遊戲性能下降

這是遊戲「網格」的繪製方法:

public void Draw(Graphics g) 
{ 
    Brush brush; 
    Font font = new System.Drawing.Font("Arial", 5); 
    for (int i = 0; i < Width; i++) 
    for (int j = 0; j < Height; j++) 
    { 
      brush = new TextureBrush(Blocks[i][j].Texture); 
      if (Blocks[i][j].Occupied==true) 
      g.FillRectangle(brush, i * 20, j * 20, i * 20 + Blocks[i][j].Texture.Width, j * 20 + Blocks[i][j].Texture.Height); 
    } 
} 

這是活性四格拼板的拉伸方法:

public void Draw(Graphics g) 
{ 
    Brush brush = new TextureBrush(Blocks[0].Texture); 
    foreach (FullBlock b in Blocks) 
     g.FillRectangle(brush, b.x * 20, b.y * 20,b.Texture.Width, b.Texture.Height); 
} 

遊戲本身然後使用這兩者(雙緩衝未遂):

public void GameDraw(PictureBox p) 
{ 
    Graphics g = Graphics.FromImage(gb); 
    gameGrid.Draw(g); 
    PlayingShape.Draw(g); 
    p.Image = gb; 
    p.Refresh(); 
} 

其中​​是私人Bitmap v可以在類構造函數中創建一次(減少(不成功))滯後)。

每當比賽的狀態改變時,GameDraw方法被調用(例如移動/旋轉活動四格拼板和每一個「萬有引力」打勾)

+3

你不需要使用圖片框,使用標準的GDI +繪圖,它會運行*很多*更快。 – Tigran 2013-05-14 11:27:09

+0

if(Blocks [i] [j] .Occupied == true)<---不要這樣做。只需使用.Occupied,它將返回一個布爾值。 – 2013-05-14 13:04:07

回答

0

無需圖片框,添加自己的控制:

using System.Drawing; 
using System.Windows.Forms; 

namespace TetrisGame 
{ 
    public sealed class TetrisControl : Control 
    { 
     private TheBlockType[][] blocks = ...; 

     protected override void OnPaint(PaintEventArgs e) 
     { 
      //draw your stuff here direct to the control, no buffers in the middle 
      //if that causes flickering, turn on double buffering, but don't bother doing it yourself 
      //this is your existing draw method: 
      Draw(e.Graphics); 
     } 
    } 
} 

然後在每一個刻度或運動,做調用paint,只是無效控制:

tetris.Invalidate(); 
+0

謝謝,我會試試看。 – Dreamer 2013-05-14 13:00:49

+0

使用新類構建項目後,它將顯示在工具箱中,並可以像其他控件一樣放在窗體上。祝你好運! – weston 2013-05-14 13:02:22

4

你需要雙緩衝,您沒有設置。引用MSDN

雙緩衝使用的內存緩衝區來解決閃爍問題 與多個塗料業務相關聯。當啓用雙緩衝 ,油漆全部操作都先渲染到內存緩衝區 而不是紙面屏幕

可以使用Control.DoubleBuffered財產

+2

雙緩衝,遊戲編程,因爲冠軍的工具,永遠......我還記得在我的Commodore的Amiga用這個。 – 2013-05-14 11:38:46

+1

儘管圖像不閃爍,但我在GameDraw方法中解決了這個問題,首先繪製一個「隱形」位圖,然後將其複製到pictureBox.Image。圖像只是延遲更新。 – Dreamer 2013-05-14 12:07:32

0

還支持它,想開箱...而不是做一個完整的掃描網格,你可以讓每個形狀的鏈表的一部分,並重繪根據它們在網格中的位置......直到網格完全填滿,你會少做掃描。

或者,只考慮重繪你所需要重繪,即塊頂部附近的下降,沒有必要完全重繪滿格。

優化是什麼我們從動物身上分離出來。除了鴨嘴獸,誰是最佳生物。

+0

OP的程序應該能夠一遍又一遍地重繪整個屏幕而不會出現任何問題,這是大多數遊戲所做的。如果他們花費了很多時間去優化它,以便只做出改變,是的,他們會看到一個好處,但它只是隱藏真正的問題,編寫和調試需要更長的時間。 – weston 2013-05-14 12:59:30