C#中利用雙緩沖技術解決繪圖閃屏問題


轉載自: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     }
  }

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM