小明陪你编游戏系列(四)GDI+实现双缓冲
来源:互联网 发布:名片录入软件 编辑:程序博客网 时间:2024/05/29 03:20
由于各方面原因,小明这次更新拖了很久,抱歉。
这次代码的下载地址如下:
http://download.csdn.net/detail/fukainankai/7382847
如果你看了执行了上周的代码,相信你一定会发现,程序存在闪烁问题,而且为了防止闪烁太严重,我只有在指定的时间才会进行重绘,而实际上,我们需要时时刻刻地描绘我们的画面,这样的话,这个程序就会闪得眼花缭乱了,今天就将介绍的双缓冲将会解决这个问题。
无论是GDI还是DirectX还是我们现在使用的GDI+,双缓冲的原理都是类似的。
我们可以试想一下,我们之前的程序,我们需要绘制一个背景,绘制背景地图上的每一个元素,绘制我们不断向前走的队伍,这还只是一个简单的游戏就有这么些个元素,那么这对设备的要求会非常高,最终造成的问题最明显的就是闪烁。
双缓冲的原理是这样的,首先我们并不直接将这些图元绘制到设备上,而是绘制到内存中的虚拟设备上,绘制结束后,将最终的结果一次性copy到图形设备单元(gdu)中,内存中运行的速度是很快的,所以,我们就可以避免了闪烁等问题。
好了,现在看看,我们的实现代码,先看看我们原先的Render函数:
if (m_pGraphics == NULL){return false;}m_pGraphics->Clear(Color::Blue);float fClientWidth;float fClientHeight;RECT rect;::GetClientRect(m_hwnd, &rect);fClientWidth = rect.right - rect.left;fClientHeight = rect.bottom - rect.top;float fWidth = fClientWidth/MAX_WIDTH;float fHeight = fClientHeight/MAX_HEIGHT;// Render map.for (int i=0; i<MAX_HEIGHT; i++){for(int j=0; j<MAX_WIDTH; j++){if (m_map[i][j]>0 && m_map[i][j]<g_nRoleCount){m_pGraphics->DrawImage(m_ImagePointerArray[m_map[i][j]], i*fWidth, j*fHeight, fWidth, fHeight);}}}// Render Teamfor(int i=0; i<TEAM_SIZE; i++){int nImageIndex = m_team.m_TeamMember[i].nRoleId;int x = m_team.m_TeamMember[i].x;int y = m_team.m_TeamMember[i].y;m_pGraphics->DrawImage(m_ImagePointerArray[nImageIndex], x*fWidth, y*fHeight, fWidth, fHeight);}return true;
然后,再看看改动后的:
if (m_pGraphics == NULL){return false;}float fClientWidth;float fClientHeight;RECT rect;::GetClientRect(m_hwnd, &rect);fClientWidth = rect.right - rect.left;fClientHeight = rect.bottom - rect.top;float fWidth = fClientWidth/MAX_WIDTH;float fHeight = fClientHeight/MAX_HEIGHT;Bitmap CacheImage( fClientWidth, fClientHeight);Graphics CacheGraphics( &CacheImage );CacheGraphics.Clear(Color::Blue);// Render map.for (int i=0; i<MAX_HEIGHT; i++){for(int j=0; j<MAX_WIDTH; j++){if (m_map[i][j]>0 && m_map[i][j]<g_nRoleCount){CacheGraphics.DrawImage(m_ImagePointerArray[m_map[i][j]], i*fWidth, j*fHeight, fWidth, fHeight);}}}// Render Teamfor(int i=0; i<TEAM_SIZE; i++){int nImageIndex = m_team.m_TeamMember[i].nRoleId;int x = m_team.m_TeamMember[i].x;int y = m_team.m_TeamMember[i].y;CacheGraphics.DrawImage(m_ImagePointerArray[nImageIndex], x*fWidth, y*fHeight, fWidth, fHeight);}m_pGraphics->DrawImage(&CacheImage, 0, 0);return true;
很简单吧,双缓冲就是这样了。如有任何问题,欢迎各位斧正!~
0 0
- 小明陪你编游戏系列(四)GDI+实现双缓冲
- 小明陪你编游戏系列(二)简单实现
- MFC设计局域网对战五子棋游戏(四)GDI+和GDI混合双缓冲绘图
- 小明陪你编游戏系列(三)第一次重构与状态机的实现
- GDI+ 双缓冲实现
- GDI+ 双缓冲实现
- GDI双缓冲实现与GDI+双缓冲实现
- GDI双缓冲的实现
- GDI+学习笔记(四)Bitmap与双缓冲
- 小明陪你编游戏系列(一)win32游戏开发快速入门
- 对话框 gdi+双缓冲实现代码
- 双缓冲技术(基于GDI+实现)
- GDI+学习笔记四-双缓冲图形类
- GDI双缓冲绘图
- gdi+ 双缓冲技术
- GDI双缓冲绘图
- GDI+双缓冲
- GDI+中的双缓冲
- 覆盖上一层普通的眼膜
- 用 HTTP 压缩加快 Web 数据的发送
- SetCapture ReleaseCapture
- 用 Psyco让Python运行得像C一样快
- Spring 3.2 源码解析 -- XML bean 元素到 BeanDefinition 解析过程
- 小明陪你编游戏系列(四)GDI+实现双缓冲
- 黑马程序员_封装继承多态
- 黑马程序员_内存管理与ARC原理
- 01 计算机系统漫游
- 黑马程序员_分类协议代码块
- Quartz中扩展MethodInvokingJobDetailFactoryBean实现对任务调度的拦截
- linux 替当前目录加权限
- 基于Spring MVC的简单HelloWorld实例
- [Linux]Fedora17/18安装Ruby1.8 和 Redmine 2.2