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


  這段時間在做一個小型游戲,在界面顯示的時候用到了一些圖形。一開始涉及到的圖形全都用控件的背景圖片代替了。這樣游戲運行的時候存在的一個很大的問題是游戲運行很慢。小組成員費盡周折,即將放棄,每一個成員都愁眉苦臉。我這心里也挺心酸的。。。

  好的廢話不多說了。為了改善游戲的運行效果,把原來控件的方式全都改成繪圖的方式,即用C#中DrawImage()方法進行繪圖,可以改善游戲運行慢的問題。然后開始測試DrawImage()方法的使用。圖片倒是出來了,而且也可以移動了,但是致命的問題出現了。就是圖片在移動的時候(實質上是圖片的重繪)出現了閃屏的問題。

  為了解決這個問題,在網上找了很多資料,參考了很多書,能解決閃屏問題的解決方法就是利用C#中提供的一種雙緩沖技術。

  但是網上或書上沒有一個能夠通過一個簡單的例子直接讓我明白如何使用雙緩沖技術的。花了好幾個小時的時間,最終還是自己琢磨出來了。分享給大家。同時也把我的這個簡單的測試小例子供大家學習,如何快速應用雙緩沖技術解決問題。

1.首先建立一個工程,在窗口中添加一個按鈕。當點擊這個按鈕式就開始顯示圖片的移動。

2.雙緩沖我采用的方法是:

  先建立一個虛擬畫布,並在Form1()的方法中加入

     SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint,
true); // 禁止擦除背景.
            SetStyle(ControlStyles.DoubleBuffer, true);

  

private Graphics g;
        Bitmap bmp = new Bitmap(600, 600);//這里是創建一個畫布
        Graphics g1;
        private int x=0;
        public Form1()
        {
            
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
            SetStyle(ControlStyles.DoubleBuffer, true);
            g1 = Graphics.FromImage(bmp);//這里是在畫布上建立一個Graphics對象,為了在畫布上畫圖形
            
            
            InitializeComponent();
            
        }

 

然后通過單擊按鈕事件,在畫布上顯示圖片並將畫布顯示到窗口

//button1的單擊處理事件
        private void button1_Click(object sender, EventArgs e)
        {
            
            //g1.DrawEllipse(new Pen(System.Drawing.Color.Red), 10, 10, 100, 100);
            g1.DrawImage(Image.FromFile("E:/down.png"), x, 10);//這是在畫布上繪制圖形
           this.CreateGraphics().DrawImage(bmp, 0, 0);//這句是將圖形顯示到窗口上
            timer1.Enabled = true;
           // g.Dispose();
        }

最后在通過timer控件使圖片不斷移動,代碼如下:

private void timer1_Tick(object sender, EventArgs e)
        {
            
            x++;//這是一個全局變量,用來改變圖片的橫坐標
            g1.Clear(Form1.DefaultBackColor);//這是清除畫布中前一個圖片
            g1.DrawImage(Image.FromFile("E:/down.png"), x, 10);//重繪新的圖片,此時位置較之前的地方橫坐標加1了
            this.CreateGraphics().DrawImage(bmp, 0, 0);//再次顯示到窗口上,沒有閃動
        }

如沒有加SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
            SetStyle(ControlStyles.DoubleBuffer, true);代碼,將會出現屏幕閃動。

下面給出完整的代碼:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ttest
{
    public partial class Form1 : Form
    {
        private Graphics g;
        Bitmap bmp = new Bitmap(600, 600);//這里是創建一個畫布
        Graphics g1;
        private int x=0;
        public Form1()
        {
            
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
            SetStyle(ControlStyles.DoubleBuffer, true);
            g1 = Graphics.FromImage(bmp);
            
            InitializeComponent();
            
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
           // g1 = this.CreateGraphics();
            
        }
        //button1的單擊處理事件
        private void button1_Click(object sender, EventArgs e)
        {
            
            //g1.DrawEllipse(new Pen(System.Drawing.Color.Red), 10, 10, 100, 100);
            g1.DrawImage(Image.FromFile("E:/down.png"), x, 10);//這是在畫布上繪制圖形
           this.CreateGraphics().DrawImage(bmp, 0, 0);//這句是將圖形顯示到窗口上
            timer1.Enabled = true;
           // g.Dispose();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            
            x++;//這是一個全局變量,用來改變圖片的橫坐標
            g1.Clear(Form1.DefaultBackColor);//這是清除畫布中前一個圖片
            g1.DrawImage(Image.FromFile("E:/down.png"), x, 10);//重繪新的圖片,此時位置較之前的地方橫坐標加1了
            this.CreateGraphics().DrawImage(bmp, 0, 0);//再次顯示到窗口上,沒有閃動
        }

        

       
    }
}

弄了一下午,終於解決閃屏問題了。。。


免責聲明!

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



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