MFC-双缓冲技术
来源:互联网 发布:113什么意思 网络聊天 编辑:程序博客网 时间:2024/05/17 01:19
在做俄罗斯方块游戏的时候,遇到游戏过程中屏幕闪烁问题,解决办法如下:
使用双缓冲技术解决屏幕闪烁
- 运行程序,会发现程序有些闪烁,这是因为程序受WM_TIMER 消息触发,调用OnTimer
函数,OnTimer 函数中调用Invalidate 函数的结果。Invalidate 的调用会触发对OnDraw 函数
的调用,从而不停地重绘窗口的结果。 - 在VC++的文档、视图结构中,CView 的OnDraw 函数用于实现绝大部分图形绘制的工
作。如果用户改变窗口尺寸,或者显示隐藏的区域,OnDraw 函数都将被调用来重画窗口。
并且,当程序文档中的数据发生改变时,一般必须通过调用视图的Invalidate(或InvalidateRect)
成员函数来通知Windows 所发生的改变,对Invalidate 的调用也会触发对OnDraw 函数的调
用。正因为OnDraw 函数被频繁调用,所以在其执行时,每次都刷新填充一次视图客户区域,
便会使屏幕不稳定,产生闪烁现象。 - 这里介绍采用双缓冲方式消除屏幕闪烁的方法。普通绘图方式与双缓冲绘图方式的区别
在于:普通绘图方式可以看做是在屏幕上直接绘制图形,双缓冲绘图方式是现在内存中创建
的“虚拟屏幕”上绘制,然后将绘制完成的图形一次性“拷贝”到屏幕上。
修改视图类的OnDraw 函数:
void CMyTetrisView::OnDraw(CDC* pDC){ CMyTetrisDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); int m_nWidth, m_nHeight; CDC m_memDC; CBitmap m_memBmp; //1.用于映射屏幕的内存设备环境 //获取游戏窗口的大小用于下面设置内存位图的尺寸 CRect windowRect; GetClientRect(&windowRect); m_nWidth = windowRect.Width(); m_nHeight = windowRect.Height(); //内存设备环境与屏幕设备环境关联(兼容) m_memDC.CreateCompatibleDC(pDC); //内存位图与与屏幕关联(兼容),大小为游戏窗口的尺寸 m_memBmp.CreateCompatibleBitmap(pDC, m_nWidth, m_nHeight); m_memDC.FillSolidRect(windowRect, RGB(0, 0, 0)); //内存设备环境与内存位图关联,以便通过m_memDC 在内存位图上作画 m_memDC.SelectObject(&m_memBmp); DrawImage(bin, outputImage, &m_memDC, bin2, outputImage2, binN, outputImageN, binN2, outputImageN2); //把内存DC 上的图形拷贝到电脑屏幕 pDC->BitBlt(0, 0, m_nWidth, m_nHeight, &m_memDC, 0, 0, SRCCOPY); m_memDC.DeleteDC(); //删除DC m_memBmp.DeleteObject(); //删除位图}
修改视图类的DrawImage 函数
// CMyTetrisView 消息处理程序void CMyTetrisView::DrawImage(CBin *bin, unsigned char** image, CDC *pDC, CBin *bin2, unsigned char** image2, CBin *binN, unsigned char** outputImageN, CBin *binN2, unsigned char** outputImageN2){ unsigned int width, i, j; unsigned int height; width = bin->getWidth(); height = bin->getHeight(); int nSize = 20; CRect rect; GetClientRect(&rect); pDC->FillSolidRect(rect, RGB(137, 137, 137)); //绘制背景色 CRect rc; CRect rc2; CRect rcN; CRect rcN2; COLORREF BrickColor[8] = { 0xFFFFFF, 0xFF0000, 0x00FF00, 0x0000FF, 0x00FFFF, 0xFFFF00, 0x800000, 0x800080 }; for (i = 0; i<height; i++) { for (j = 0; j<width; j++) { rc = CRect(j*nSize, i*nSize, (j + 1)*nSize, (i + 1)*nSize); rc2 = CRect((j + 24)*nSize, i*nSize, (j + 25)*nSize, (i + 1)*nSize); //绘制面板 if (image[i][j] != 0) { pDC->FillRect(rc, &CBrush(BrickColor[image[i][j]])); pDC->Draw3dRect(rc, GetLightColor(BrickColor[image[i][j]]), GetDarkColor(BrickColor[image[i][j]])); } if (image2[i][j] != 0) { pDC->FillRect(rc2, &CBrush(BrickColor[image2[i][j]])); pDC->Draw3dRect(rc2, GetLightColor(BrickColor[image2[i][j]]), GetDarkColor(BrickColor[image2[i][j]])); } } } for (i = 0; i<4; i++) { for (j = 0; j<8; j++) { rcN = CRect((j + 11)*nSize, (i + 5)*nSize, (j + 12)*nSize, (i + 6)*nSize); rcN2 = CRect((j + 37)*nSize, (i + 5)*nSize, (j + 38)*nSize, (i + 6)*nSize); if (outputImageN[i][j] != 0) { pDC->FillRect(rcN, &CBrush(BrickColor[outputImageN[i][j]])); pDC->Draw3dRect(rcN, GetLightColor(BrickColor[outputImageN[i][j]]), GetDarkColor(BrickColor[outputImageN[i][j]])); } if (outputImageN2[i][j] != 0) { pDC->FillRect(rcN2, &CBrush(BrickColor[outputImageN2[i][j]])); pDC->Draw3dRect(rcN2, GetLightColor(BrickColor[outputImageN2[i][j]]), GetDarkColor(BrickColor[outputImageN2[i][j]])); } } }}
1 0
- MFC 双缓冲技术
- MFC 双缓冲技术
- MFC-双缓冲技术
- MFC 双缓冲技术 【转】
- MFC 双缓冲技术和兼容DC
- MFC 双缓冲技术和兼容DC
- 【MFC】利用双缓冲技术解决屏闪问题
- 双缓冲技术做到MFC绘图不闪烁!!
- MFC绘图不闪烁——双缓冲技术[转]
- MFC绘图不闪烁——双缓冲技术 [转]
- MFC绘图不闪烁——双缓冲技术
- MFC 使用双缓冲技术绘制坐标曲线
- MFC绘图不闪烁——双缓冲技术[转]
- MFC绘图不闪烁——双缓冲技术
- 双缓冲技术解决MFC重绘闪烁问题
- MFC双缓冲技术的内存泄漏问题探究
- MFC防止绘图闪烁——双缓冲技术
- MFC 双缓冲画图
- 华为OJ 初级:数字颠倒
- nodejs基础概念解析
- Chaon_Android 设置EditText的颜色及其粗细
- 117. Populating Next Right Pointers in Each Node II
- redis生产环境中慎用keys模糊匹配方法
- MFC-双缓冲技术
- centos下采用rpm方式安装mysql
- Eclipse Java EE IDE for Web Developers部署项目到Tomcat的方法
- 自定义字母索引View
- JQ的input change事件
- Android N 程序适配要点
- vs 2015 编译cocos2dx 报错C1189 #error: Macro definition of snprintf conflicts with Standard Library func
- jquery datatable 取当前点击列的配置
- 糖果机器人_0005_day2_页面跳转_码全