这段时间在做一个小型游戏,在界面显示的时候用到了一些图形。一开始涉及到的图形全都用控件的背景图片代替了。这样游戏运行的时候存在的一个很大的问题是游戏运行很慢。小组成员费尽周折,即将放弃,每一个成员都愁眉苦脸。我这心里也挺心酸的。。。

  好的废话不多说了。为了改善游戏的运行效果,把原来控件的方式全都改成绘图的方式,即用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#中利用双缓冲技术解决绘图闪屏问题。的更多相关文章

  1. Qt组件中的双缓冲无闪烁绘图

      双缓冲绘图在Qt4中,所有的窗口部件默认都使用双缓冲进行绘图.使用双缓冲,可以减轻绘制的闪烁感.在有些情况下,用户要关闭双缓冲,自己管理绘图.下面的语句设置了窗口部件的Qt::WA_PaintOn ...

  2. OpenGL中实现双缓冲技术

    在OpenGL中实现双缓冲技术的一种简单方法: 1.在调用glutInitDisplayMode函数时, 开启GLUT_DOUBLE,即glutInitDisplayMode(GLUT_RGB | G ...

  3. MFC中的双缓冲技术(解决绘图闪烁问题)

    转自 MFC绘图不闪烁——双缓冲技术[转] 在VC/MFC用CDC绘图时,频繁的刷新,屏幕会出现闪烁的现象,CPU时间占用率相当高,绘图效率极低,很容易出现程序崩溃. 所谓双缓冲技术,下面是百度百科的 ...

  4. VC 绘图,使用双缓冲技术实现

    VC 绘图,使用双缓冲技术实现 - Cloud-Datacenter-Renewable Energy-Big Data-Model - 博客频道 - CSDN.NET VC 绘图,使用双缓冲技术实现 ...

  5. VC++绘图时,利用双缓冲解决屏幕闪烁 转载

    最近做中国象棋,绘制界面时遇到些问题,绘图过程中屏幕闪烁,估计都会想到利用双缓冲来解决问题,但查了下网上双缓冲的资料,发现基本是MFC的,转化为VC++后,大概代码如下: void DrawBmp(H ...

  6. c++双缓冲技术,以避免闪烁绘图

    当数据量非常大时,画图可能须要几秒钟甚至更长的时间,并且有时还会出现闪烁现象,为了解决这些问题.可採用双缓冲技术来画图. 双缓冲即在内存中创建一个与屏幕画图区域一致的对象,先将图形绘制到内存中的这个对 ...

  7. 【MFC】MFC绘图不闪烁——双缓冲技术

    MFC绘图不闪烁——双缓冲技术[转] 2010-04-30 09:33:33|  分类: VC|举报|字号 订阅 [转自:http://blog.163.com/yuanlong_zheng@126/ ...

  8. Android开发之用双缓冲技术绘图

    双缓冲技术主要用在画图,动画效果上,其原理就是:将资源先载入到缓冲区,然后再将缓冲区整个载入到View上面去. 双缓冲技术可以有效防止闪烁,提高显示质量. DrawView.java: package ...

  9. Win32 GDI 非矩形区域剪裁,双缓冲技术

    传统的Win32通过GDI提供图形显示的功能,包括了基本的绘图功能,如画线.方块.椭圆等等,高级功能包括了多边形和Bezier的绘制.这样app就不用关心那些图形学的细节了,有点类似于UNIX上的X- ...

随机推荐

  1. 人人API 分享到人人功能 修改版

    最近在搞一个日程管理网站, 需要实现分享到人人功能, 所以找了一下人人API, 然后根据自己需要修改了一下. 首先得有一个人人给的js文件, 如下: var Renren = Renren || {} ...

  2. 嵌入式Linux学习小结

    这两个月一直在学习Linux.作为一名刚開始学习的人,学习期间难免磕磕碰碰.走弯路,可是,抱着不怕失败.多尝试的信念,终于还是坚持下来了. 如今已经清楚Linux的框架,知道怎么去开发一个Linux程 ...

  3. iOS英语—》中国本土化,如调用专辑,摄像头的变化“cancel”,“photos”至“撤消”,“摄像头”

    呼叫系统相册.系统相簿界面后标题显示"photos",可是手机语言已经设置显示中文,纠结半天,终于在info.plist设置解决这个问题. 仅仅须要改三个地方: 1.plist文件 ...

  4. spring mvc 错误摘要--。位。

    1....identifier of an instance of org.szgzw.ent.profile.baseinfo.enterprise.EnterpriseEntity was alt ...

  5. [LeetCode328]Odd Even Linked List

    题目: Given a singly linked list, group all odd nodes together followed by the even nodes. Please note ...

  6. 说说PHP的autoLoad自动加载机制

    __autoload的使用方法1: 最经常使用的就是这种方法,根据类名,找出类文件,然后require_one 复制代码 代码如下:function __autoload($class_name) { ...

  7. 如何在Dreamweaver中使用zen coding

    在我发表上一篇<Zen Coding: 一种快速编写HTML/CSS代码的方法>之后,有网友表示不知道怎么在Dreamweaver上使用zen coding插件.OK,今天我就写一篇详细的 ...

  8. 11gR2 Database Services for &quot;Policy&quot; and &quot;Administrator&quot; Managed Databases (文件 ID 1481647.1)

    In this Document   _afrLoop=1459311711568804&id=1481647.1&displayIndex=6&_afrWindowMode= ...

  9. [Django1.6]south于django1.6使用

    south在django1.6中的使用 django1.7中已经支持数据合并了,所以仅仅能在django1.4 1.5 1.6的版本号中使用south. south的主要作用就是做数据的合并,当我们在 ...

  10. 第三篇——第二部分——第四文 配置SQL Server镜像——非域环境

    原文:第三篇--第二部分--第四文 配置SQL Server镜像--非域环境 本文为非域环境搭建镜像演示,对于域环境搭建,可参照上文:http://blog.csdn.net/dba_huangzj/ ...