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(, );//这里是创建一个画布
Graphics g1;
private int x=;
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, );//这是在画布上绘制图形
this.CreateGraphics().DrawImage(bmp, , );//这句是将图形显示到窗口上
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, );//重绘新的图片,此时位置较之前的地方横坐标加1了
this.CreateGraphics().DrawImage(bmp, , );//再次显示到窗口上,没有闪动
}
如没有加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(, );//这里是创建一个画布
Graphics g1;
private int x=;
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, );//这是在画布上绘制图形
this.CreateGraphics().DrawImage(bmp, , );//这句是将图形显示到窗口上
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, );//重绘新的图片,此时位置较之前的地方横坐标加1了
this.CreateGraphics().DrawImage(bmp, , );//再次显示到窗口上,没有闪动
} }
}
弄了一下午,终于解决闪屏问题了。。。
C#中利用双缓冲技术解决绘图闪屏问题。的更多相关文章
- Qt组件中的双缓冲无闪烁绘图
双缓冲绘图在Qt4中,所有的窗口部件默认都使用双缓冲进行绘图.使用双缓冲,可以减轻绘制的闪烁感.在有些情况下,用户要关闭双缓冲,自己管理绘图.下面的语句设置了窗口部件的Qt::WA_PaintOn ...
- OpenGL中实现双缓冲技术
在OpenGL中实现双缓冲技术的一种简单方法: 1.在调用glutInitDisplayMode函数时, 开启GLUT_DOUBLE,即glutInitDisplayMode(GLUT_RGB | G ...
- MFC中的双缓冲技术(解决绘图闪烁问题)
转自 MFC绘图不闪烁——双缓冲技术[转] 在VC/MFC用CDC绘图时,频繁的刷新,屏幕会出现闪烁的现象,CPU时间占用率相当高,绘图效率极低,很容易出现程序崩溃. 所谓双缓冲技术,下面是百度百科的 ...
- VC 绘图,使用双缓冲技术实现
VC 绘图,使用双缓冲技术实现 - Cloud-Datacenter-Renewable Energy-Big Data-Model - 博客频道 - CSDN.NET VC 绘图,使用双缓冲技术实现 ...
- VC++绘图时,利用双缓冲解决屏幕闪烁 转载
最近做中国象棋,绘制界面时遇到些问题,绘图过程中屏幕闪烁,估计都会想到利用双缓冲来解决问题,但查了下网上双缓冲的资料,发现基本是MFC的,转化为VC++后,大概代码如下: void DrawBmp(H ...
- c++双缓冲技术,以避免闪烁绘图
当数据量非常大时,画图可能须要几秒钟甚至更长的时间,并且有时还会出现闪烁现象,为了解决这些问题.可採用双缓冲技术来画图. 双缓冲即在内存中创建一个与屏幕画图区域一致的对象,先将图形绘制到内存中的这个对 ...
- 【MFC】MFC绘图不闪烁——双缓冲技术
MFC绘图不闪烁——双缓冲技术[转] 2010-04-30 09:33:33| 分类: VC|举报|字号 订阅 [转自:http://blog.163.com/yuanlong_zheng@126/ ...
- Android开发之用双缓冲技术绘图
双缓冲技术主要用在画图,动画效果上,其原理就是:将资源先载入到缓冲区,然后再将缓冲区整个载入到View上面去. 双缓冲技术可以有效防止闪烁,提高显示质量. DrawView.java: package ...
- Win32 GDI 非矩形区域剪裁,双缓冲技术
传统的Win32通过GDI提供图形显示的功能,包括了基本的绘图功能,如画线.方块.椭圆等等,高级功能包括了多边形和Bezier的绘制.这样app就不用关心那些图形学的细节了,有点类似于UNIX上的X- ...
随机推荐
- 【Linux】lvm基础操作
新增两块硬盘,来进行实验: [root@jp ~]# fdisk -l Disk /dev/sda: 107.3 GB, 107374182400 bytes 255 heads, 63 sector ...
- Unbound classpath container: 'JRE System Library [jdk17060]' in project ***
项目报告的错误列表 Unbound classpath container: 'JRE System Library [jdk17060]' in project **** 误. 原因是,我升级JDK ...
- oracle 选择最频繁出现之前,5文章数据
SELECT * FROM ( SELECT PROJECT_LISTING.MATERIAL, COUNT (*) AS "出现次数" FROM PROJECT_LISTING ...
- 从零开始做UI-静电的sketch设计教室 视频教程
全套31集目录 01-初识Sketch http://www.ui.cn/detail/52223.html02-sketch的下载与安装 http://www.ui.cn/detail/5222 ...
- ios 动态设置Cell高低
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPa ...
- c# winfrom DataGridView使行高不可改变,使列头高度不可改变,
// 禁止用户改变DataGridView1的所有列的列宽 //DataGridView1.AllowUserToResizeColumns = false; //禁止用户改变DataGridView ...
- ASP.NET2.0自定义控件组件开发 第六章 深入讲解控件的属性
原文:ASP.NET2.0自定义控件组件开发 第六章 深入讲解控件的属性 深入讲解控件的属性持久化(一) 系列文章链接: ASP.NET自定义控件组件开发 第一章 待续 ASP.NET自定义控件组件开 ...
- CocoStudio学习资源
CocoStudio安装包及实例project:http://www.cocoachina.com/bbs/read.php?tid=154886 CocoStudio视频教程系列:http://mo ...
- MFC 盾webBrowser打开弹出的页面
void CansDlg::NewWindow3Explorer1(LPDISPATCH* ppDisp, BOOL* Cancel, unsigned long dwFlags, LPCTSTR b ...
- 深入理解Android中ViewGroup
文章目录 [隐藏] 一.ViewGroup是什么? 二.ViewGroup这个容器 2.1 添加View的算法 2.1.1 我们先来分析addViewInner方法: 2.1.2 addInArr ...