美化了一下Blog以及今日总结

12点前在Blog加了个日历和一个深圳的天气预告。实用性又强了一点点了
刚刚把CGraph类搞来搞去算是写得七七八八,基础的都搞得差不多了。
增加了Blt,BltFast的封装(越界判断)以及CLS,CountFPS等函数。

现在的demo是一个图片跟随鼠标移动,窗口模式下FPS平均为21,全屏约40多。
明天我想可以正式开始做GUI界面部分了。先把父类CObject做出来,然后一级一级继承下去……
CObject, CWnd, CForm, CControl,  CLabel, CTextBox, CButton, CHScroll, CVScroll, CMenu, CRadio, CCheckBox, CMessageBox……嗯,似乎看到了美好的前景……哈哈

把CGraph的代码帖出来。Blt那3个函数可能还有点东东需要改,丢失页面的还没处理。
还有CGame的代码。对了,那个网络通讯应该放在哪里处理呢……


//Graph.cpp
#include "StdAfx.h"

#include "./graph.h"

//测试页面
LPDIRECTDRAWSURFACE lpDDSZhaoyun;

CGraph::CGraph(void)
: m_WinHeight(0)
, m_WinWidth(0)
, m_ColorDepth(0)
, m_WinLeft(0)
, m_WinTop(0)
, m_nFrames(0)
{
}


CGraph::~CGraph(void)
{
}


// 初始化DirectDraw
bool CGraph::InitDDraw(int nWidth, int nHeight, int nColorDepth,bool bFullScreen)
{
 if(DirectDrawCreate(NULL, &lpDD, NULL) != DD_OK )
  return false;

 // Set CooperativeLevel
 DWORD dwFlags;
 if (bFullScreen)
 {
  dwFlags = DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT;
  this->bIsWindowMode = false;
 }else{
  dwFlags = DDSCL_NORMAL;
  this->bIsWindowMode = true;
 }
 if (lpDD->SetCooperativeLevel(hWnd,dwFlags) != DD_OK)
  return false;

 //Set DisplayMode
 m_WinHeight = nHeight;
 m_WinWidth = nWidth;


 if(!bFullScreen)
 {
  GetWindowRect(hWnd, &RectWin);
  RectWin.top += 23;
 }else{
  RectWin.left = 0;
  RectWin.top = 0;
  RectWin.bottom = nHeight;
  RectWin.right = nWidth;
 }

 m_ColorDepth = nColorDepth;
 if(bFullScreen)
  if(lpDD->SetDisplayMode(nWidth,nHeight,nColorDepth) != DD_OK)
   return false;

 //Set Window Style
 SetWindowStyle();

 //Init Primary and back Buffers
 DDSURFACEDESC  ddsd;
 HRESULT          ddrval;

 if(bFullScreen)
 {
  //Fullscreen mode

  ZeroMemory( &ddsd, sizeof( ddsd ) );
  ddsd.dwSize = sizeof( ddsd );
  ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
  ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
   DDSCAPS_FLIP |
   DDSCAPS_COMPLEX;
  ddsd.dwBackBufferCount = 1;

  //Create Primary surface.
  ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
  if( ddrval != DD_OK )
   return false;

  //Create BackBuffer surface
  ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
  if ( lpDDSPrimary->GetAttachedSurface (&ddsd.ddsCaps, &lpDDSBack) != DD_OK )
   return false;

 }else{

  //Window mode
     ddsd.dwSize = sizeof( ddsd );
  ddsd.dwFlags = DDSD_CAPS;
     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;


  //Create Primary surface.
  if( lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL ) != DD_OK )
  {
   return false;
  }


  //Create BackBuffer surface
  ZeroMemory(&ddsd, sizeof(ddsd));
  ddsd.dwSize = sizeof(ddsd);
  ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
  ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
  ddsd.dwWidth = m_WinWidth;
  ddsd.dwHeight = m_WinHeight;
  if( lpDD->CreateSurface( &ddsd, &lpDDSBack, NULL ) != DD_OK )
  {
   return false;
  }

  //设置关键色
  SetColorKey(lpDDSBack,RGB_32BIT(255,0,255));

 }


 //建立裁剪器
 CreateClipper();

 //测试页面初始化
 lpDDSZhaoyun = LoadBitmap(lpDD,"zhaoyun.bmp",0,0);
 SetColorKey(lpDDSBack, RGB_32BIT(255,0,0));
 SetColorKey(lpDDSZhaoyun, RGB_32BIT(255,0,255));

 return true;

}

 

// 释放DirectDraw对象
void CGraph::FreeDDraw(void)
{
 if (lpDD != NULL)
    {
  _RELEASE( lpClipper );
  _RELEASE( lpDDSBack );
  _RELEASE( lpDDSPrimary );
  _RELEASE( lpDD );
 }
}

 

// 设置窗口风格与当前显示模式匹配
bool CGraph::SetWindowStyle(void)
{
 if(this->bIsWindowMode)
 {
  SetWindowLong(hWnd,GWL_EXSTYLE, WS_EX_OVERLAPPEDWINDOW);
  SetWindowLong(hWnd,GWL_STYLE, WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX);
  SetWindowPos(hWnd,HWND_NOTOPMOST, 0,0,m_WinWidth,m_WinHeight,SWP_SHOWWINDOW | SWP_NOMOVE );
 }else{
  SetWindowLong(hWnd,GWL_EXSTYLE,WS_EX_TOPMOST);
  SetWindowLong(hWnd,GWL_STYLE, WS_POPUP);
  SetWindowPos(hWnd,HWND_TOPMOST,0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN),SWP_SHOWWINDOW);
 }
 return true;
}

 

// 建立裁剪器
bool CGraph::CreateClipper(void)
{
 if( lpDD->CreateClipper( 0, &lpClipper, NULL ) != DD_OK)
 {
  #ifdef _DEBUG
   myTrace.Write("CGraph::CreateClipper() CreateClipper Error!/n");  
  #endif
  return false;
 }

 if(lpClipper->SetHWnd(0, hWnd) != DD_OK)
 {
  #ifdef _DEBUG
   myTrace.Write("CGraph::CreateClipper() SetHWnd Error!/n");  
  #endif
  return false;
 }

 
 if(lpDDSPrimary->SetClipper(lpClipper) != DD_OK)
 {
  #ifdef _DEBUG
   myTrace.Write("CGraph::CreateClipper() SetClipper Error!/n");  
  #endif
  return false;
 }
 return true;
}


// 设置关键色
HRESULT CGraph::SetColorKey(IDirectDrawSurface * pdds, COLORREF rgb)
{
    DDCOLORKEY          ddck;

 ddck.dwColorSpaceLowValue  = ColorMatch(pdds, rgb);
    ddck.dwColorSpaceHighValue = ddck.dwColorSpaceLowValue;
    return pdds->SetColorKey(DDCKEY_SRCBLT, &ddck);
}

 

// 获得指定颜色对应的调色板索引
DWORD CGraph::ColorMatch(IDirectDrawSurface * pdds, COLORREF rgb)
{
    COLORREF rgbT;
    HDC hdc;
    DWORD dw = CLR_INVALID;
    DDSURFACEDESC ddsd;
    HRESULT hres;

    if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)
    {
        rgbT = GetPixel(hdc, 0, 0);             // 保存当前值
        SetPixel(hdc, 0, 0, rgb);
        pdds->ReleaseDC(hdc);
    }
 
    ddsd.dwSize = sizeof(ddsd);
    while ((hres = pdds->Lock(NULL, &ddsd, 0, NULL)) == DDERR_WASSTILLDRAWING)
        ;

    if (hres == DD_OK)
    {
        dw  = *(DWORD *)ddsd.lpSurface;                     // 转化为DWORD
        dw &= (1 << ddsd.ddpfPixelFormat.dwRGBBitCount)-1;  // mask it to bpp
            
        pdds->Unlock(NULL);
    }

    if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)
    {
        SetPixel(hdc, 0, 0, rgbT);  //恢复原来值
        pdds->ReleaseDC(hdc);
    }

    return dw;
}

// 创建一个离屏Surface并加载bmp图片到页面
IDirectDrawSurface * CGraph::LoadBitmap(IDirectDraw * pdd, LPCSTR szBitmap , int dx , int dy)
{
    HBITMAP             hbm;
    BITMAP              bm;
    DDSURFACEDESC       ddsd;
    IDirectDrawSurface *pdds;

    //首先尝试作为资源加载
    hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), szBitmap, IMAGE_BITMAP, dx, dy,
  LR_CREATEDIBSECTION);
 //资源加载失败,作为文件加载
    if (hbm == NULL)
        hbm = (HBITMAP)LoadImage(NULL, szBitmap, IMAGE_BITMAP, dx, dy,
   LR_LOADFROMFILE|LR_CREATEDIBSECTION);

    if (hbm == NULL)
        return NULL;

    //获取图片大小
    GetObject(hbm, sizeof(bm), &bm);     

    //创建Surface
    ZeroMemory(&ddsd, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
    ddsd.dwWidth = bm.bmWidth;
    ddsd.dwHeight = bm.bmHeight;

    if (pdd->CreateSurface(&ddsd, &pdds, NULL) != DD_OK)
        return NULL; //创建Surface失败

 //加载图片
    CopyBitmap(pdds, hbm, 0, 0, 0, 0);
    DeleteObject(hbm);

    return pdds;
}

// 把hbm位图Copy到目标Surface
HRESULT CGraph::CopyBitmap(IDirectDrawSurface * pdds, HBITMAP hbm, int x, int y, int dx, int dy)
{
    HDC                 hdcImage;
    HDC                 hdc;
    BITMAP              bm;
    DDSURFACEDESC       ddsd;
    HRESULT             hr;

    if (hbm == NULL || pdds == NULL)
        return E_FAIL;

    pdds->Restore();

 // 创建一个与当前屏幕相关的 memory device context
    hdcImage = CreateCompatibleDC(NULL);
    if (!hdcImage)
        OutputDebugString("createcompatible dc failed/n");
    SelectObject(hdcImage, hbm);

 // 得到bmp大小
    GetObject(hbm, sizeof(bm), &bm);   
    dx = dx == 0 ? bm.bmWidth  : dx;    // 只要参数指定了大小,则用指定大小, 否则用图片默认大小
    dy = dy == 0 ? bm.bmHeight : dy;

 // 得到页面大小
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
    pdds->GetSurfaceDesc(&ddsd);
 
    if ((hr = pdds->GetDC(&hdc)) == DD_OK)
    {
  //缩放Blt
        StretchBlt(hdc, 0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage, x, y, dx, dy, SRCCOPY);
        pdds->ReleaseDC(hdc);
    }

    DeleteDC(hdcImage);

    return hr;
}

// 加载一个Bitmap到页面(与LoadBitmap不同的是,这个函数不会创建Surface)
HRESULT CGraph::ReloadBitmap(IDirectDrawSurface * pdds, LPCSTR szBitmap)
{
    HBITMAP             hbm;
    HRESULT             hr;
 // 注释看LoadBitmap函数,相当接近.
 hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), szBitmap, IMAGE_BITMAP, 0, 0,
     LR_CREATEDIBSECTION);

 if (hbm == NULL)
        hbm = (HBITMAP)LoadImage(NULL, szBitmap, IMAGE_BITMAP, 0, 0,
    LR_LOADFROMFILE|LR_CREATEDIBSECTION);

 if (hbm == NULL)
    {
  char str[128];
  sprintf(str, "handle is null [%s]/n", szBitmap);
        OutputDebugString(str);
        return E_FAIL;
    }

 hr = CopyBitmap(pdds, hbm, 0, 0, 0, 0);
    if (hr != DD_OK)
    {
        OutputDebugString("ddcopybitmap failed/n");
    }


    DeleteObject(hbm);
    return hr;
}


// 输出字符串到指定页面位置
void CGraph::DDSPrint(IDirectDrawSurface * lpDDS, int x , int y , char * szMsg,...)
{

 va_list va;
 char str[512] = "";

 va_start(va,szMsg);
 vsprintf(str,szMsg,va);
 va_end(va); 

 HDC dc;
 lpDDS->GetDC(&dc);
 SetBkMode(dc, TRANSPARENT);
 SetTextColor(dc, RGB(255,255,255));
 TextOut(dc, x, y , str, (int)strlen(str));
 lpDDS->ReleaseDC(dc);

}

// 用指定色彩填充目标页面
void CGraph::CLS(IDirectDrawSurface * lpDDS, DWORD color)
{
 DDBLTFX ddbltfx;
 ddbltfx.dwSize=sizeof(ddbltfx);
 ddbltfx.dwFillColor=color;
 lpDDS->Blt(NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
}
// 直接用黑色填充BackBuffer
void CGraph::CLS(void)
{
 CLS(lpDDSBack,RGB_32BIT(0,0,0));
}
//设置窗口坐标
void CGraph::SetWinPos(int nLeft, int nTop)
{
 RectWin.left = nLeft;
 RectWin.top = nTop;
 RectWin.right = RectWin.left + m_WinWidth;
 RectWin.bottom = RectWin.top + m_WinHeight;
}
// 翻页函数, 将BackBuffer翻转到PrimaryBuffer
void CGraph::Flip(void)
{
 HRESULT ddrval;
 if(!bIsWindowMode)
 {
  //全屏模式
  while( 1 )
  {
   ddrval = lpDDSPrimary->Flip( NULL, 0 );
   if( ddrval == DD_OK )
   {
    break;
   }
   if( ddrval == DDERR_SURFACELOST )
   {
    if( lpDDSPrimary )
     ddrval = lpDDSPrimary->Restore();
    if( lpDDSBack )
     ddrval = lpDDSBack->Restore();
    //还要回复其他页面吗?
    
    if( ddrval != DD_OK )
    {
     break;
    }
   }
   if( ddrval != DDERR_WASSTILLDRAWING )
   {
    break;
   }
  }

 }else{
  //窗口模式
  lpDDSPrimary->Blt(&RectWin,lpDDSBack,NULL,DDBLT_WAIT, NULL);
 }
 m_nFrames ++;
}
// 返回当前FPS值,在Flip函数里累加m_nFrames
int CGraph::CountFPS(void)
{
 static long old_clock,ret;
 long new_clock;

 new_clock=timeGetTime();
 if( new_clock > old_clock + 1000 )
 {
  old_clock=new_clock;
  ret=m_nFrames;
  m_nFrames=0;
 } 
 return ret;
}
// 将会执行lpDDSSrc->Blt(),并且根据屏幕大小自动调整Blt的参数, 不带缩放
HRESULT CGraph::Blt(int x, int y, IDirectDrawSurface * lpDDSDest , LPRECT lpSrcRect,  IDirectDrawSurface * lpDDSSrc, DWORD Flags)
{
 HRESULT ddrval;
 LPRECT myRect;
 myRect = lpSrcRect;
 if (myRect == NULL)
 {
  myRect = new RECT;

  //获取目标表面的大小
  DDSURFACEDESC ddsd;
  ddsd.dwSize=sizeof(ddsd);
  ddrval=lpDDSSrc->GetSurfaceDesc(&ddsd);
  if( ddrval != DD_OK )
   return ddrval;

  //将整个目标表面作为目标Blt区域
  myRect->left = 0;
  myRect->top = 0;
  myRect->right = ddsd.dwWidth;
  myRect->bottom = ddsd.dwHeight;
 }

 //检查左右边界
 if( x<0 )
 {
  // 如果blt的坐标< 0 那么目标页面区域的左边界向右偏移 x 个象素
  myRect->left = myRect->left - x;
  x=0;
 }else if( x + myRect->right - myRect->left > m_WinWidth ){
  // 假若目标区域超过于窗口右边边界,则目标右边界向左偏移 x 个象素
  myRect->right = myRect->left + m_WinWidth - x;
 }

 //检查上下边界
 if( y<0 )
 {
  // 原理同上
  myRect->top  = myRect->top - y;
  y=0;
 }else if( y + myRect->bottom - myRect->top > m_WinHeight ){
  myRect->bottom = myRect->top + m_WinHeight - y;
 }

 // 执行Blt操作
 RECT DestRect;
 DestRect.left = x;
 DestRect.right = x + myRect->right - myRect->left;
 DestRect.top = y;
 DestRect.bottom = y + myRect->bottom - myRect->top;

 while( 1 )
 {
  ddrval = lpDDSDest->Blt( &DestRect, lpDDSSrc, myRect, Flags, NULL);
  if( ddrval == DD_OK )
   break;

  if( ddrval == DDERR_SURFACELOST )
  {
   // 页面丢失了, 恢复全部页面.
   #ifdef _DEBUG
    myTrace.Write("CGraph->Blt() Surface lost error./n");
   #endif
   break;
  }
  
  if( ddrval != DDERR_WASSTILLDRAWING )
      break;
    }
 if (lpSrcRect == NULL)
  _DELETE(myRect);
 return ddrval;
}
// 跟Blt函数相仿参数与DDraw的Blt相同,带缩放
HRESULT CGraph::Blt(LPRECT lpDestRect, IDirectDrawSurface * lpDDSDest, LPRECT lpSrcRect , IDirectDrawSurface * lpDDSSrc, DWORD Flags)
{
 HRESULT ddrval;
 LPRECT myRect;
 myRect = lpSrcRect;
 if (myRect == NULL)
 {
  myRect = new RECT;

  //获取目标表面的大小
  DDSURFACEDESC ddsd;
  ddsd.dwSize=sizeof(ddsd);
  ddrval=lpDDSSrc->GetSurfaceDesc(&ddsd);
  if( ddrval != DD_OK )
   return ddrval;

  //将整个目标表面作为目标Blt区域
  myRect->left = 0;
  myRect->top = 0;
  myRect->right = ddsd.dwWidth;
  myRect->bottom = ddsd.dwHeight;
 }

 //检查左右边界
 if( lpDestRect->left<0 )
 {
  // 如果blt的坐标< 0 那么目标页面区域的左边界向右偏移 x 个象素
  myRect->left = myRect->left - lpDestRect->left;
  lpDestRect->left=0;
 }else if( lpDestRect->left + myRect->right - myRect->left > m_WinWidth ){
  // 假若目标区域超过于窗口右边边界,则目标右边界向左偏移 x 个象素
  myRect->right = myRect->left + m_WinWidth - lpDestRect->left;
 }

 //检查上下边界
 if( lpDestRect->top<0 )
 {
  // 原理同上
  myRect->top  = myRect->top - lpDestRect->top;
  lpDestRect->top=0;
 }else if( lpDestRect->top + myRect->bottom - myRect->top > m_WinHeight ){
  myRect->bottom = myRect->top + m_WinHeight - lpDestRect->top;
 }

 // 执行Blt操作
 while( 1 )
 {
  ddrval = lpDDSDest->Blt( lpDestRect, lpDDSSrc, myRect, Flags, NULL);
  if( ddrval == DD_OK )
   break;

  if( ddrval == DDERR_SURFACELOST )
  {
   // 页面丢失了, 恢复全部页面.
   #ifdef _DEBUG
    myTrace.Write("CGraph->Blt() Surface lost error./n");
   #endif
   break;
  }
  
  if( ddrval != DDERR_WASSTILLDRAWING )
      break;
    }
 if (lpSrcRect == NULL)
  _DELETE(myRect);
 return ddrval;
}
// 将会执行lpDDSDest->BltFast(),并且根据屏幕大小自动调整Blt的参数
HRESULT CGraph::BltFast(int x, int y, IDirectDrawSurface * lpDDSDest , LPRECT lpSrcRect,  IDirectDrawSurface * lpDDSSrc, DWORD Flags)
{
 HRESULT ddrval;
 LPRECT myRect;
 myRect = lpSrcRect;
 if (myRect == NULL)
 {
  myRect = new RECT;

  //获取源表面的大小
  DDSURFACEDESC ddsd;
  ddsd.dwSize=sizeof(ddsd);
  ddrval=lpDDSSrc->GetSurfaceDesc(&ddsd);
  if( ddrval != DD_OK )
   return ddrval;

  //将整个目标表面作为目标Blt区域
  myRect->left = 0;
  myRect->top = 0;
  myRect->right = ddsd.dwWidth;
  myRect->bottom = ddsd.dwHeight;
 }

 //检查左右边界
 if( x<0 )
 {
  // 如果blt的坐标< 0 那么目标页面区域的左边界向右偏移 x 个象素
  myRect->left = myRect->left - x;
  x=0;
 }
 if( x + myRect->right - myRect->left > m_WinWidth ){
  // 假若目标区域超过于窗口右边边界,则目标右边界向左偏移 x 个象素
  myRect->right = myRect->left + m_WinWidth - x;
 }
 //检查上下边界
 if( y<0 )
 {
  // 原理同上
  myRect->top  = myRect->top - y;
  y=0;
 }
 if( y + myRect->bottom - myRect->top > m_WinHeight )
 {
  myRect->bottom = myRect->top + m_WinHeight - y;
 }
 // 执行BltFast操作
 while( 1 )
 {
  ddrval = lpDDSDest->BltFast( x, y, lpDDSSrc, myRect, Flags);
  if( ddrval == DD_OK )
   break;

  if( ddrval == DDERR_SURFACELOST )
  {
   // 页面丢失了, 恢复全部页面.
   #ifdef _DEBUG
    myTrace.Write("CGraph->BltFast() Surface lost error./n");
   #endif
   break;
  }
  
  if( ddrval != DDERR_WASSTILLDRAWING )
      break;
    }
 if (lpSrcRect == NULL)
  _DELETE(myRect);
 return ddrval;
}
// 功能测试函数
void CGraph::Test(void)
{

 RECT r;
 r.left = 0;
 r.right = 200;
 r.top = 0;
 r.bottom = 100;

 POINT p;
 GetCursorPos(&p);


 BltFast(p.x-RectWin.left, p.y-RectWin.top, lpDDSBack, NULL, lpDDSZhaoyun, DDBLTFAST_SRCCOLORKEY);
 //lpDDSBack->BltFast(p.x-RectWin.left, p.y-RectWin.top, lpDDSZhaoyun, NULL, DDBLTFAST_SRCCOLORKEY);

 
 DDSPrint(lpDDSBack,10,16,"Current FPS:%d",CountFPS());
 DDSPrint(lpDDSBack,10,32,"Window Rect: (L:%d,R:%d)-(R:%d,B:%d)",RectWin.left,RectWin.top,RectWin.right,RectWin.bottom);
}


//Game.cpp
#include "StdAfx.h"
#include "./game.h"
#include "./graph.h"
#include "./global.h"
#include "./trace.h"

CGame::CGame(void)
: bIsRunning(false)
, bActive(false)
, m_nWinWidth(0)
, m_nWinHeight(0)
, m_bFullscreen(false)
, m_nColorDepth(0)
{
 myGraph = new CGraph();
 bActive = true;
}

CGame::~CGame(void)
{
 delete myGraph;
}


// 初始化游戏变量
bool CGame::InitGameVariables(void)
{
 m_nWinWidth  = 800;
 m_nWinHeight = 600;
 m_bFullscreen = true;
 m_nColorDepth = 24;
 return true;
}

// 开始游戏
int CGame::Start(void)
{
 int rval;
#ifdef _DEBUG
 CTrace myTrace;
 myTrace.Write("-------------------------------------/n");
 myTrace.Write(" << New Instance begin >> /n");
 myTrace.Write("-------------------------------------/n");
#endif
 // 初始化 游戏设置
 InitGameVariables();
 // 初始化 DirectDraw
 if(!myGraph->InitDDraw(m_nWinWidth,m_nWinHeight,m_nColorDepth,m_bFullscreen))
 {
  #ifdef _DEBUG
   myTrace.Write("Function call /"myGraph->InitDDraw()/" Error./n");
  #endif
  MessageBox(hWnd,"DirectDraw初始化失败.","错误",MB_OK);
  return 0;
 }

 // 开始游戏
 bIsRunning = true;
 rval = GameLoop();
#ifdef _DEBUG
 myTrace.Write("------ Instance End. -------/n");
#endif
 return rval;

}

// 游戏消息循环
HRESULT CGame::GameLoop(void)
{

 MSG msg;
 //char szDebug[200];
 while (bIsRunning)
 {
  
  if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) && msg.message != WM_PAINT)
  {
   if (msg.message==WM_QUIT)
   {
    bIsRunning = false; //退出游戏
    break;
   }
   TranslateMessage(&msg);
   DispatchMessage(&msg);
  }
  else if(bActive)
  {
   MainLoop(); //游戏主循环
  }else{
   WaitMessage(); //等待消息
  }
  //sprintf(szDebug,"Msg=%d, Active=%d/n",msg.message,bActive);
  //OutputDebugString(szDebug);
 }
 //return msg.wParam;
 
 return 0;
}

// 设置窗口是否活动
void CGame::SetActive(bool Active)
{
 bActive = Active;
}

// 游戏主循环,负责更新状态,绘图翻页,响应等
void CGame::MainLoop(void)
{
 myGraph->CLS();  // 用黑色清空缓冲页
 /  更新数据  /
 //
 // 1.更新鼠标坐标/按钮状态数据
 // 2.更新键盘输入数据
 // 3.处理数据/鼠标命令
 //
 /  渲染场景  /
 //
 // 1.贴场景图
 // 2.贴场景物体, 人物
 // 3.贴窗口等GUI
 //
 /
 myGraph->Test(); // 这个测试函数模拟对缓冲页的绘画过程

 myGraph->Flip(); // 翻页
 return;
}

// 结束游戏
bool CGame::Quit(void)
{
 myGraph->FreeDDraw();
 return true;
}

// 返回游戏窗口宽度
int CGame::GetGameWinWidth(void)
{
 return m_nWinWidth;
}

// 返回游戏窗口高度
int CGame::GetGameWinHeight(void)
{
 return m_nWinHeight;
}


// 传递给CGraph用于制定窗口模式下的翻页Blt区域参数
void CGame::SetWinPos(int nLeft, int nTop)
{
 myGraph->SetWinPos(nLeft,nTop);
}

// 返回是否全屏
bool CGame::IsFullScreen(void)
{
 return m_bFullscreen;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值