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 }
}
作者:郭小雷
出处:http://www.cnblogs.com/Ray1024/
版权声明:本文的版权归作者与博客园共有。转载时须注明本文的作者及详细链接,否则作者将保留追究其法律责任。
欢迎大家学习、共享,如果文章中有错误或漏洞,请大家在评论区留言!!
出处:http://www.cnblogs.com/Ray1024/
版权声明:本文的版权归作者与博客园共有。转载时须注明本文的作者及详细链接,否则作者将保留追究其法律责任。
欢迎大家学习、共享,如果文章中有错误或漏洞,请大家在评论区留言!!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?