轉載自:http://www.2cto.com/kf/201404/295500.html
這段時間在做一個小型游戲,在界面顯示的時候用到了一些圖形。一開始涉及到的圖形全都用控件的背景圖片代替了。這樣游戲運行的時候存在的一個很大的問題是游戲運行很慢。小組成員費盡周折,即將放棄,每一個成員都愁眉苦臉。我這心里也挺心酸的。。。
好的廢話不多說了。為了改善游戲的運行效果,把原來控件的方式全都改成繪圖的方式,即用C#中DrawImage()方法進行繪圖,可以改善游戲運行慢的問題。然后開始測試DrawImage()方法的使用。圖片倒是出來了,而且也可以移動了,但是致命的問題出現了。就是圖片在移動的時候(實質上是圖片的重繪)出現了閃屏的問題。
為了解決這個問題,在網上找了很多資料,參考了很多書,能解決閃屏問題的解決方法就是利用C#中提供的一種雙緩沖技術。
但是網上或書上沒有一個能夠通過一個簡單的例子直接讓我明白如何使用雙緩沖技術的。花了好幾個小時的時間,最終還是自己琢磨出來了。分享給大家。同時也把我的這個簡單的測試小例子供大家學習,如何快速應用雙緩沖技術解決問題。
1.首先建立一個工程,在窗口中添加一個按鈕。當點擊這個按鈕式就開始顯示圖片的移動。
2.雙緩沖我采用的方法是:
先建立一個虛擬畫布,並在Form1()的方法中加入
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
SetStyle(ControlStyles.DoubleBuffer, true);
1 private Graphics g; 2 3 Bitmap bmp = new Bitmap(600, 600);//這里是創建一個畫布 4 5 Graphics g1; 6 7 private int x=0; 8 9 public Form1() 10 11 { 12 SetStyle(ControlStyles.UserPaint, true); 13 14 SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景. 15 16 SetStyle(ControlStyles.DoubleBuffer, true); 17 18 g1 = Graphics.FromImage(bmp);//這里是在畫布上建立一個Graphics對,為了在畫布上畫圖形 19 20 InitializeComponent(); 21 }
然后通過單擊按鈕事件,在畫布上顯示圖片並將畫布顯示到窗口
1 //button1的單擊處理事件 2 3 private void button1_Click(object sender, EventArgs e) 4 5 { 6 7 //g1.DrawEllipse(new Pen(System.Drawing.Color.Red), 10, 10, 100, 100); 8 9 g1.DrawImage(Image.FromFile("E:/down.png"), x, 10);//這是在畫布上繪制圖形 10 11 this.CreateGraphics().DrawImage(bmp, 0, 0);//這句是將圖形顯示到窗口上 12 13 timer1.Enabled = true; 14 15 // g.Dispose(); 16 17 }
最后在通過timer控件使圖片不斷移動,代碼如下:
1 private void timer1_Tick(object sender, EventArgs e) 2 3 { 4 5 x++;//這是一個全局變量,用來改變圖片的橫坐標 6 7 g1.Clear(Form1.DefaultBackColor);//這是清除畫布中前一個圖片 8 9 g1.DrawImage(Image.FromFile("E:/down.png"), x, 10);//重繪新的圖片,此時位置較之前的地方橫坐標加1了 10 11 this.CreateGraphics().DrawImage(bmp, 0, 0);//再次顯示到窗口上,沒有閃動 12 13 }
下面給出完整的代碼:
1 using System; 2 3 using System.Collections.Generic; 4 5 using System.ComponentModel; 6 7 using System.Data; 8 9 using System.Drawing; 10 11 using System.Linq; 12 13 using System.Text; 14 15 using System.Windows.Forms; 16 17 18 19 namespace ttest 20 21 { 22 23 public partial class Form1 : Form 24 25 { 26 27 private Graphics g; 28 29 Bitmap bmp = new Bitmap(600, 600);//這里是創建一個畫布 30 31 Graphics g1; 32 33 private int x=0; 34 35 public Form1() 36 37 { 38 39 40 41 SetStyle(ControlStyles.UserPaint, true); 42 43 SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景. 44 45 SetStyle(ControlStyles.DoubleBuffer, true); 46 47 g1 = Graphics.FromImage(bmp); 48 49 50 51 InitializeComponent(); 52 53 54 55 } 56 57 58 59 private void Form1_Load(object sender, EventArgs e) 60 61 { 62 63 64 65 // g1 = this.CreateGraphics(); 66 67 68 69 } 70 71 //button1的單擊處理事件 72 73 private void button1_Click(object sender, EventArgs e) 74 75 { 76 77 78 79 //g1.DrawEllipse(new Pen(System.Drawing.Color.Red), 10, 10, 100, 100); 80 81 g1.DrawImage(Image.FromFile("E:/down.png"), x, 10);//這是在畫布上繪制圖形 82 83 this.CreateGraphics().DrawImage(bmp, 0, 0);//這句是將圖形顯示到窗口上 84 85 timer1.Enabled = true; 86 87 // g.Dispose(); 88 89 } 90 91 92 93 private void timer1_Tick(object sender, EventArgs e) 94 95 { 96 97 98 99 x++;//這是一個全局變量,用來改變圖片的橫坐標 100 101 g1.Clear(Form1.DefaultBackColor);//這是清除畫布中前一個圖片 102 103 g1.DrawImage(Image.FromFile("E:/down.png"), x, 10);//重繪新的圖片,此時位置較之前的地方橫坐標加1了 104 105 this.CreateGraphics().DrawImage(bmp, 0, 0);//再次顯示到窗口上,沒有閃動 106 107 } 108 109 }
}