首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

,请帮忙看看小弟我在GDI里这样双缓冲对吗?如何闪烁更严重了

2012-02-10 
求助,请帮忙看看我在GDI里这样双缓冲对吗?怎么闪烁更严重了?我写一个贪食蛇的游戏,就用SDK编程,写好后发现

求助,请帮忙看看我在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()了,刷太频繁也会闪的

热点排行