小明陪你编游戏系列(四)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
原创粉丝点击