2d游戏引擎(二)——向引擎添加位图类

来源:互联网 发布:换主题的软件 编辑:程序博客网 时间:2024/05/06 04:36

 

 位图(Bitmap)类背后的思路是,提供一种从文件或者资源加载位图并将位图绘制到一个设备环境的方法。通过将这些功能结合到一个类中,我们就能够在游戏中创建极易使用的Bitmap对象,并且可以隐藏处理位图的各种繁杂工作。Bitmap类有以下需求:

1.从文件中加载位图

2.从资源中加载位图

3.创建纯色的空白位图

4.将位图绘制到设备环境

5.获得位图的宽度和高度

 

代码清单:

//-----------------------------------------------------------------// Bitmap Object// C++ Header - Bitmap.h//-----------------------------------------------------------------#pragma once//-----------------------------------------------------------------// Include Files//-----------------------------------------------------------------#include //-----------------------------------------------------------------// Bitmap Class//-----------------------------------------------------------------class Bitmap{protected:  // Member Variables  HBITMAP m_hBitmap;  int     m_iWidth, m_iHeight;  // Helper Methods  void Free();public:  // Constructor(s)/Destructor  Bitmap();  Bitmap(HDC hDC, LPTSTR szFileName);  Bitmap(HDC hDC, UINT uiResID, HINSTANCE hInstance);  Bitmap(HDC hDC, int iWidth, int iHeight, COLORREF crColor = RGB(0, 0, 0));  virtual ~Bitmap();  // General Methods  BOOL Create(HDC hDC, LPTSTR szFileName);  BOOL Create(HDC hDC, UINT uiResID, HINSTANCE hInstance);  BOOL Create(HDC hDC, int iWidth, int iHeight, COLORREF crColor);  void Draw(HDC hDC, int x, int y);  int  GetWidth() { return m_iWidth; };  int  GetHeight() { return m_iHeight; };};

 

//-----------------------------------------------------------------// Bitmap Object// C++ Source - Bitmap.cpp//-----------------------------------------------------------------//-----------------------------------------------------------------// Include Files//-----------------------------------------------------------------#include "Bitmap.h"//-----------------------------------------------------------------// Bitmap Constructor(s)/Destructor//-----------------------------------------------------------------Bitmap::Bitmap()  : m_hBitmap(NULL), m_iWidth(0), m_iHeight(0){}// Create a bitmap from a fileBitmap::Bitmap(HDC hDC, LPTSTR szFileName)  : m_hBitmap(NULL), m_iWidth(0), m_iHeight(0){  Create(hDC, szFileName);}// Create a bitmap from a resourceBitmap::Bitmap(HDC hDC, UINT uiResID, HINSTANCE hInstance)  : m_hBitmap(NULL), m_iWidth(0), m_iHeight(0){  Create(hDC, uiResID, hInstance);}// Create a blank bitmap from scratchBitmap::Bitmap(HDC hDC, int iWidth, int iHeight, COLORREF crColor)  : m_hBitmap(NULL), m_iWidth(0), m_iHeight(0){  Create(hDC, iWidth, iHeight, crColor);}Bitmap::~Bitmap(){  Free();}//-----------------------------------------------------------------// Bitmap Helper Methods//-----------------------------------------------------------------void Bitmap::Free(){  // Delete the bitmap graphics object  if (m_hBitmap != NULL)  {    DeleteObject(m_hBitmap);    m_hBitmap = NULL;  }}//-----------------------------------------------------------------// Bitmap General Methods//-----------------------------------------------------------------BOOL Bitmap::Create(HDC hDC, LPTSTR szFileName){  // Free any previous bitmap info  Free();  // Open the bitmap file  HANDLE hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL,    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);  if (hFile == INVALID_HANDLE_VALUE)    return FALSE;  // Read the bitmap file header  BITMAPFILEHEADER  bmfHeader;  DWORD             dwBytesRead;  BOOL bOK = ReadFile(hFile, &bmfHeader, sizeof(BITMAPFILEHEADER),    &dwBytesRead, NULL);  if ((!bOK) || (dwBytesRead != sizeof(BITMAPFILEHEADER)) ||    (bmfHeader.bfType != 0x4D42))//0x4D42 代表 "BM",为bmp文件的标志  {    CloseHandle(hFile);    return FALSE;  }  BITMAPINFO* pBitmapInfo = (new BITMAPINFO);  if (pBitmapInfo != NULL)  {    // Read the bitmap info header    bOK = ReadFile(hFile, pBitmapInfo, sizeof(BITMAPINFOHEADER),      &dwBytesRead, NULL);    if ((!bOK) || (dwBytesRead != sizeof(BITMAPINFOHEADER)))    {      CloseHandle(hFile);      //Free();      return FALSE;    }    // Store the width and height of the bitmap    m_iWidth = (int)pBitmapInfo->bmiHeader.biWidth;    m_iHeight = (int)pBitmapInfo->bmiHeader.biHeight;    // Get a handle to the bitmap and copy the image bits    PBYTE pBitmapBits;    m_hBitmap = CreateDIBSection(hDC, pBitmapInfo, DIB_RGB_COLORS,      (PVOID*)&pBitmapBits, NULL, 0);    if ((m_hBitmap != NULL) && (pBitmapBits != NULL))    {      SetFilePointer(hFile, bmfHeader.bfOffBits, NULL, FILE_BEGIN);//更改文件指针      bOK = ReadFile(hFile, pBitmapBits, pBitmapInfo->bmiHeader.biSizeImage,        &dwBytesRead, NULL);      if (bOK)        return TRUE;    }  }  // Something went wrong, so cleanup everything  Free();  return FALSE;}BOOL Bitmap::Create(HDC hDC, UINT uiResID, HINSTANCE hInstance){  // Free any previous DIB info  Free();  // Find the bitmap resource  HRSRC hResInfo = FindResource(hInstance, MAKEINTRESOURCE(uiResID), RT_BITMAP);  if (hResInfo == NULL)    return FALSE;  // Load the bitmap resource  HGLOBAL hMemBitmap = LoadResource(hInstance, hResInfo);  if (hMemBitmap == NULL)    return FALSE;  // Lock the resource and access the entire bitmap image  PBYTE pBitmapImage = (BYTE*)LockResource(hMemBitmap);  if (pBitmapImage == NULL)  {    FreeResource(hMemBitmap);    return FALSE;  }  // Store the width and height of the bitmap  BITMAPINFO* pBitmapInfo = (BITMAPINFO*)pBitmapImage;  m_iWidth = (int)pBitmapInfo->bmiHeader.biWidth;  m_iHeight = (int)pBitmapInfo->bmiHeader.biHeight;  // Get a handle to the bitmap and copy the image bits  PBYTE pBitmapBits;  m_hBitmap = CreateDIBSection(hDC, pBitmapInfo, DIB_RGB_COLORS,    (PVOID*)&pBitmapBits, NULL, 0);  if ((m_hBitmap != NULL) && (pBitmapBits != NULL))  {    const PBYTE pTempBits = pBitmapImage + pBitmapInfo->bmiHeader.biSize +      pBitmapInfo->bmiHeader.biClrUsed * sizeof(RGBQUAD);    //从图像数据区开始copy    CopyMemory(pBitmapBits, pTempBits, pBitmapInfo->bmiHeader.biSizeImage);    // Unlock and free the bitmap graphics object    UnlockResource(hMemBitmap);    FreeResource(hMemBitmap);    return TRUE;  }  // Something went wrong, so cleanup everything  UnlockResource(hMemBitmap);  FreeResource(hMemBitmap);  Free();  return FALSE;}BOOL Bitmap::Create(HDC hDC, int iWidth, int iHeight, COLORREF crColor){  // Create a blank bitmap  m_hBitmap = CreateCompatibleBitmap(hDC, iWidth, iHeight);  if (m_hBitmap == NULL)    return FALSE;  // Set the width and height  m_iWidth = iWidth;  m_iHeight = iHeight;  // Create a memory device context to draw on the bitmap  HDC hMemDC = CreateCompatibleDC(hDC);//为什么要用兼容的hdc?  // Create a solid brush to fill the bitmap  HBRUSH hBrush = CreateSolidBrush(crColor);  // Select the bitmap into the device context  HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemDC, m_hBitmap);  // Fill the bitmap with a solid color  RECT rcBitmap = { 0, 0, m_iWidth, m_iHeight };  FillRect(hMemDC, &rcBitmap, hBrush);  // Cleanup  SelectObject(hMemDC, hOldBitmap);  DeleteDC(hMemDC);  DeleteObject(hBrush);  return TRUE;}void Bitmap::Draw(HDC hDC, int x, int y){  if (m_hBitmap != NULL)  {    // Create a memory device context for the bitmap    HDC hMemDC = CreateCompatibleDC(hDC);    // Select the bitmap into the device context    HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemDC, m_hBitmap);    // Draw the bitmap to the destination device context    BitBlt(hDC, x, y, GetWidth(), GetHeight(), hMemDC, 0, 0, SRCCOPY);    // Restore and delete the memory device context    SelectObject(hMemDC, hOldBitmap);    DeleteDC(hMemDC);  }}

 

以下给出一个程序实例,应用Bitmap类。程序的效果是在窗口中定时循环显示一组幻灯片。

//-----------------------------------------------------------------// Slideshow Application// C++ Header - Slideshow.h//-----------------------------------------------------------------#pragma once//-----------------------------------------------------------------// Include Files//-----------------------------------------------------------------#include #include "Resource.h"#include "GameEngine.h"#include "Bitmap.h"//-----------------------------------------------------------------// Global Variables//-----------------------------------------------------------------HINSTANCE   g_hInstance;GameEngine* g_pGame;const int   g_iNUMSLIDES = 6;//幻灯片数量Bitmap*     g_pSlides[g_iNUMSLIDES];int         g_iCurSlide;

 

//-----------------------------------------------------------------// Slideshow Application// C++ Source - Slideshow.cpp//-----------------------------------------------------------------//-----------------------------------------------------------------// Include Files//-----------------------------------------------------------------#include "Slideshow.h"//-----------------------------------------------------------------// Game Engine Functions//-----------------------------------------------------------------BOOL GameInitialize(HINSTANCE hInstance){  // Create the game engine  g_pGame = new GameEngine(hInstance, TEXT("Slideshow"),    TEXT("Slideshow"), IDI_SLIDESHOW, IDI_SLIDESHOW_SM);  if (g_pGame == NULL)    return FALSE;    // Set the frame rate  g_pGame->SetFrameRate(1);  // Store the instance handle  g_hInstance = hInstance;  return TRUE;}void GameStart(HWND hWindow){  // Create and load the slide bitmaps  HDC hDC = GetDC(hWindow);  g_pSlides[0] = new Bitmap(hDC, TEXT("Image1.bmp"));  g_pSlides[1] = new Bitmap(hDC, TEXT("Image2.bmp"));  g_pSlides[2] = new Bitmap(hDC, TEXT("Image3.bmp"));  g_pSlides[3] = new Bitmap(hDC, IDB_IMAGE4, g_hInstance);  g_pSlides[4] = new Bitmap(hDC, IDB_IMAGE5, g_hInstance);  g_pSlides[5] = new Bitmap(hDC, 640, 480, RGB(0, 0, 0));  // Set the first slide  g_iCurSlide = 0;}void GameEnd(){  // Cleanup the slide bitmaps  for (int i = 0; i < g_iNUMSLIDES; i++)    delete g_pSlides[i];  // Cleanup the game engine  delete g_pGame;}void GameActivate(HWND hWindow){}void GameDeactivate(HWND hWindow){}void GamePaint(HDC hDC){  // Draw the current slide bitmap  g_pSlides[g_iCurSlide]->Draw(hDC, 0, 0);}void GameCycle(){  static int iDelay = 0;  // Establish a 3-second delay before moving to the next slide  if (++iDelay > 3)  {    // Restore the delay counter    iDelay = 0;    // Move to the next slide    if (++g_iCurSlide == g_iNUMSLIDES)      g_iCurSlide = 0;    // Force a repaint to draw the next slide    InvalidateRect(g_pGame->GetWindow(), NULL, FALSE);  }}

 

 

//-----------------------------------------------------------------// Slideshow Resource Identifiers// C++ Header - Resource.h//-----------------------------------------------------------------//-----------------------------------------------------------------// Icons                    Range : 1000 - 1999//-----------------------------------------------------------------#define IDI_SLIDESHOW       1000#define IDI_SLIDESHOW_SM    1001//-----------------------------------------------------------------// Bitmaps                  Range : 2000 - 2999//-----------------------------------------------------------------#define IDB_IMAGE1          2000#define IDB_IMAGE2          2001#define IDB_IMAGE3          2002#define IDB_IMAGE4          2003#define IDB_IMAGE5          2004

 

 

//-----------------------------------------------------------------// Slideshow Resources// RC Source - Slideshow.rc//-----------------------------------------------------------------//-----------------------------------------------------------------// Include Files//-----------------------------------------------------------------#include "Resource.h"//-----------------------------------------------------------------// Icons//-----------------------------------------------------------------IDI_SLIDESHOW      ICON         "Res//Slideshow.ico"IDI_SLIDESHOW_SM   ICON         "Res//Slideshow_sm.ico"//-----------------------------------------------------------------// Bitmaps//-----------------------------------------------------------------IDB_IMAGE1         BITMAP       "Res//Image1.bmp"IDB_IMAGE2         BITMAP       "Res//Image2.bmp"IDB_IMAGE3         BITMAP       "Res//Image3.bmp"IDB_IMAGE4         BITMAP       "Res//Image4.bmp"IDB_IMAGE5         BITMAP       "Res//Image5.bmp"

 

 

 

 

 

原创粉丝点击