读书人

请帮忙看看小弟我在GDI里这样双缓冲

发布时间: 2012-02-10 21:27:42 作者: rapoo

求助,请帮忙看看我在GDI里这样双缓冲对吗?怎么闪烁更严重了?
我写一个贪食蛇的游戏,就用SDK编程,写好后发现游戏显示时会闪,我google了一下,就用双缓冲写了一个绘图的函数,但是发现闪烁的更严重了,而且还会运行着突然一下就没有图象,只有背景了,请各位帮忙看看我写的对不对?谢谢!

//消息处理函数
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM

lParam)
{
static int cxClient, cyClient;
static int length,block;//蛇初始长度,把屏幕分成的块数
static int times; //定时器的周期
RECT rt;
HDC hdc;
PAINTSTRUCT ps;
switch (message) /* handle the messages */
{
case WM_CREATE:
GetClientRect(hwnd,&rt);
cxClient = rt.right;
cyClient = rt.bottom;
length = 5;
block = 80;
times = 300;
SetTimer(hwnd,ID_TIMER,times,NULL);
if(!InitGame(length,block,cxClient,cyClient))
{
MessageBox(NULL, "游戏初始化失败! ", "错误 ",MB_OK);
SendMessage(hwnd,WM_CLOSE,0,0);
}
break;

case WM_TIMER:
if(!Run())
{
KillTimer(hwnd,ID_TIMER);
InvalidateRect(hwnd,NULL,TRUE);
MessageBox(NULL, "你输了 ", "贪食蛇 ",MB_OK);


}
else
InvalidateRect(hwnd,NULL,TRUE);
break;

case WM_PAINT:
hdc = BeginPaint(hwnd,&ps);
//DrawGame(hdc); //直接画图的
DrawGame2(hdc,cxClient,cyClient); //用双缓冲画的
EndPaint(hwnd,&ps);
break;
//.....以下是菜单处理,略了
}

//draw.h
#ifndef DRAW_H
#define DRAW_H
//作图程序
#include <vector>
#include <windows.h>

using namespace std;

//双缓冲,还是闪烁
void DrawGame2(HDC hdc,int cx, int cy)
//cx,cy为在WM_CREATE中用GetClientRect的到的屏幕显示区的横纵坐标
{
vector <POINT> DrawSnake = GetSnake(); //蛇的每个结点的坐标
int i;
int stdx = GetStdx(),stdy = GetStdy(); /*在WM_CREATEcx/block,cy/block得到,是每个小格所含的像素数,block为游戏区域里所分成的单格数,即整个游戏区域分成block*block个单格。*/
POINT DrawApple = GetApple(); //果子的坐标,随机产生
SaveDC(hdc);
HDC memDC = CreateCompatibleDC(hdc);
HBITMAP memBit = CreateCompatibleBitmap(hdc,cx,cy),oldBit;//建立内存位图
oldBit = (HBITMAP)SelectObject(memDC,memBit);//将位图选入memDC
HBRUSH hbrSnake = CreateSolidBrush(RGB(100,200,140));//画蛇
HBRUSH hbrApple = CreateSolidBrush(RGB(20,120,200));//画果子
SelectObject(memDC, hbrSnake);
//画蛇
for(i = 0; i <GetLength(); i++)
{
Rectangle(memDC,stdx*DrawSnake.at(i).x,
stdy*DrawSnake.at(i).y,
stdx*(DrawSnake.at(i).x+1),
stdy*(DrawSnake.at(i).y+1));


}
//画果子
SelectObject(memDC,hbrApple);
Ellipse(memDC,stdx*DrawApple.x,stdy*DrawApple.y,
stdx*(DrawApple.x+1),
stdy*(DrawApple.y+1));
BitBlt(hdc,0,0,cx,cy,memDC,0,0,SRCCOPY); //显示

SelectObject(memDC,oldBit);//恢复memDC
DeleteDC(memDC); //删除memDC
RestoreDC(hdc,-1);//恢复hdc
//删除画刷
DeleteObject(hbrSnake);
DeleteObject(hbrApple);
}

//直接画,有闪烁
void DrawGame(HDC hdc)
{
vector <POINT> DrawSnake = GetSnake();
int i;
int stdx = GetStdx(),stdy = GetStdy();
POINT DrawApple = GetApple();
SaveDC(hdc);
HBRUSH hbrSnake = CreateSolidBrush(RGB(100,200,140));
HBRUSH hbrApple = CreateSolidBrush(RGB(20,120,200));
SelectObject(hdc, hbrSnake);
//画蛇
for(i = 0; i <GetLength(); i++)
{
Rectangle(hdc,stdx*DrawSnake.at(i).x,
stdy*DrawSnake.at(i).y,
stdx*(DrawSnake.at(i).x+1),
stdy*(DrawSnake.at(i).y+1));
}
//画果子
SelectObject(hdc,hbrApple);
Ellipse(hdc,stdx*DrawApple.x,stdy*DrawApple.y,
stdx*(DrawApple.x+1),
stdy*(DrawApple.y+1));
RestoreDC(hdc,-1);
DeleteObject(hbrSnake);
DeleteObject(hbrApple);
}


#endif


[解决办法]
状态没有改变的话就不要InvalidateRect()了,刷太频繁也会闪的

读书人网 >VC/MFC

热点推荐