比较简单的2D游戏引擎C++类

//GameEngine.h文件:

#pragma once
#include <windows.h>

LRESULT CALLBACK WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
class GameEngine
{
protected:
HINSTANCE m_hInst;    // 应用程序实例句柄
HWND   m_hWnd;     // 窗口句柄
LPSTR   m_szWndTitle;   // 窗口标题
int    m_cxGame;    // 游戏画面宽度
int    m_cyGame;    // 游戏画面高度
int    m_iFrameDelay;   // 帧之间延迟的毫秒数
BOOL   m_bPause;    // 指示游戏是否暂停
HDC    m_hdcMem;    
HBITMAP   m_hBitmap;

public:
GameEngine(LPSTR szWndTitle, int cx, int cy, int iFrameRate);
virtual ~GameEngine(void);
int   Run(void);
LRESULT HandleEvent(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
BOOL Init(HINSTANCE hInst);

// 访问内部字段
HWND GetWnd(void) { return m_hWnd; }
BOOL IsPause(void) { return m_bPause; }
int   GetFrameDelay(void) { return m_iFrameDelay; }
int   GetGameWidth(void) { return m_cxGame; }
int   GetGameHeight(void) { return m_cyGame; }


private:
BOOL CreateWnd (HINSTANCE hInst);
BOOL CreateBackBuffer(void);

// 用户要重写的接口
protected:
virtual BOOL SetGameParams(void) = 0;    // 初始化角色的参数
virtual void PaintToMemDC(void) = 0;     // 重绘帧
virtual void ChangeGameParams(void) = 0;    // 改变角色的状态

virtual void OnKeyPress(void) = 0;      // 处理按键
virtual void OnMouseLButtonDown(int x, int y) = 0; // 处理鼠标左键按下
virtual void OnMouseLButtonUp(int x, int y) = 0;   // 处理鼠标左键释放
virtual void OnMouseRButtonDown(int x, int y) = 0; // 处理鼠标左键按下
virtual void OnMouseRButtonUp(int x, int y) = 0;   // 处理鼠标右键释放
virtual void OnMouseMove(int x, int y) = 0;    // 处理鼠标移动
};

//

GameEngine.Cpp文件

#include "./gameengine.h"

/***************** GameEngine Class ********************************************/
GameEngine::GameEngine(LPSTR szWndTitle, int cx, int cy, int iFrameRate)
{
m_hWnd    = NULL;
m_cxGame   = cx;
m_cyGame   = cy;
m_iFrameDelay = 1000 / iFrameRate;
m_bPause   = FALSE;
m_hBitmap   = NULL;
m_hdcMem   = NULL;
m_szWndTitle = szWndTitle;
}

GameEngine::~GameEngine(void)
{
if (m_hBitmap)
   DeleteObject (m_hBitmap);
if (m_hdcMem)
   DeleteObject (m_hdcMem);
}

BOOL GameEngine::CreateWnd(HINSTANCE hInst)
{
// 创建窗口类
WNDCLASS wc;
wc.cbClsExtra    = 0;
wc.cbWndExtra    = 0;
wc.hbrBackground   = (HBRUSH)(COLOR_WINDOW + 1);
wc.hInstance    = m_hInst;
wc.hCursor     = LoadCursor (NULL, IDC_ARROW);
wc.hIcon     = LoadIcon (NULL, IDI_APPLICATION);
wc.lpfnWndProc    = WndProc;
wc.lpszClassName   = m_szWndTitle;
wc.lpszMenuName    = NULL;
wc.style     = CS_HREDRAW | CS_VREDRAW;

// 注册窗口类
if (!RegisterClass(&wc))
   return FALSE;

// 根据游戏画面计算窗口大小和位置
int cxWnd = m_cxGame + GetSystemMetrics (SM_CXBORDER) * 2;
int cyWnd = m_cyGame + GetSystemMetrics (SM_CYBORDER) * 2 +
   GetSystemMetrics (SM_CYCAPTION);
if (wc.lpszMenuName != NULL)
   cyWnd += GetSystemMetrics (SM_CYMENU);
int x = (GetSystemMetrics(SM_CXSCREEN) - cxWnd) / 2;
int y = (GetSystemMetrics(SM_CYSCREEN) - cyWnd) / 2;

// 创建窗口
m_hWnd = CreateWindow (m_szWndTitle, m_szWndTitle, WS_POPUPWINDOW
   | WS_CAPTION | WS_MINIMIZEBOX , x, y, cxWnd, cyWnd,
    NULL, NULL, m_hInst, NULL);
if (!m_hWnd)
   return FALSE;
return TRUE;
}

LRESULT GameEngine::HandleEvent(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;

switch (msg)
{
case WM_SETFOCUS:
   m_bPause = FALSE;
   return 0;

case WM_KILLFOCUS:
   m_bPause = TRUE;
   return 0;

case WM_PAINT:  
   hdc = BeginPaint(hWnd, &ps);
   BitBlt(hdc, 0, 0, m_cxGame, m_cyGame, m_hdcMem, 0, 0, SRCCOPY);
   EndPaint(hWnd, &ps);
   return 0;

case WM_LBUTTONDOWN:
   OnMouseLButtonDown (LOWORD(lParam), HIWORD(lParam));
   return 0;

case WM_LBUTTONUP:
   OnMouseLButtonUp (LOWORD(lParam), HIWORD(lParam));
   return 0;

case WM_RBUTTONDOWN:
   OnMouseRButtonDown (LOWORD(lParam), HIWORD(lParam));
   return 0;

case WM_RBUTTONUP:
   OnMouseRButtonUp (LOWORD(lParam), HIWORD(lParam));
   return 0;

case WM_MOUSEMOVE:
   OnMouseMove (LOWORD(lParam), HIWORD(lParam));
   return 0;

case WM_DESTROY:
   DeleteObject (m_hBitmap);
   DeleteObject (m_hdcMem);
   PostQuitMessage(0);
   return 0;
}
return DefWindowProc (hWnd, msg, wParam, lParam);
}

int GameEngine::Run(void)
{
MSG msg;
static int iTickTrigger = 0;
int    cTick;
while (TRUE)
{
   if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
   {
    if (msg.message == WM_QUIT)
     break;
    TranslateMessage (&msg);
    DispatchMessage (&msg);
   }
   else
   {
    //确保游戏引擎没有休眠
    if (!m_bPause)
    {
     //检查滴答计数
     cTick = GetTickCount();
     if (cTick > iTickTrigger)
     {
      iTickTrigger = cTick + GetFrameDelay();
      OnKeyPress();    // 处理用户的按键
      ChangeGameParams();   // 更改游戏参数
      PaintToMemDC();    // 在后台更新画面
      InvalidateRect (m_hWnd, NULL, FALSE);   // 更新前台画面
     }
    }
   }
}
return 0;
}

BOOL GameEngine::CreateBackBuffer(void)
{
HDC hdc = GetDC(m_hWnd);
m_hdcMem = CreateCompatibleDC (hdc);
if (!m_hdcMem) return FALSE;
m_hBitmap = CreateCompatibleBitmap (hdc, m_cxGame, m_cyGame);
if (!m_hBitmap) return FALSE;
SelectObject (m_hdcMem, m_hBitmap);
ReleaseDC (m_hWnd, hdc);
return TRUE;
}

BOOL GameEngine::Init (HINSTANCE hInst)
{
if (!CreateWnd(hInst))
   return FALSE;
if (!CreateBackBuffer())
   return FALSE;
if (!SetGameParams())
   return FALSE;
// 游戏引擎准备就绪后就显示窗口
ShowWindow (m_hWnd, SW_NORMAL);
UpdateWindow (m_hWnd);
return TRUE;
}

// GameEngine类使用方法示例(由于它是一个抽象类,有纯虚方法,所以要派生出一个类来实现这些方

// 法,我派生出一个MyGameEngine类

// MyGameEngine.h文件
#pragma once
#include "gameengine.h"
class MyGameEngine :
public GameEngine
{
public:
MyGameEngine(LPSTR szWndTitle, int cx, int cy, int iFrameRate);
~MyGameEngine(void);

protected:
BOOL SetGameParams(void);
void ChangeGameParams(void);
void PaintToMemDC(void);
void OnKeyPress(void);
void OnMouseLButtonDown(int x, int y);
void OnMouseLButtonUp(int x, int y);  
void OnMouseRButtonDown(int x, int y);
void OnMouseRButtonUp(int x, int y);  
void OnMouseMove(int x, int y);
};

//MyGameEngine.Cpp文件
#include "./mygameengine.h"
MyGameEngine::MyGameEngine(LPSTR szWndTitle, int cx, int cy, int iFrameRate)
:GameEngine(szWndTitle, cx, cy, iFrameRate)
{
}

MyGameEngine::~MyGameEngine(void)
{
}

BOOL MyGameEngine::SetGameParams()
{
return TRUE;
}

void MyGameEngine::PaintToMemDC()
{   
}
void MyGameEngine::ChangeGameParams()
{
}
void MyGameEngine::OnKeyPress()
{
}
void MyGameEngine::OnMouseLButtonDown (int x, int y)
{
}
void MyGameEngine::OnMouseLButtonUp (int x, int y)
{
}
void MyGameEngine::OnMouseRButtonDown (int x, int y)
{
}
void MyGameEngine::OnMouseRButtonUp (int x, int y)
{
}
void MyGameEngine::OnMouseMove (int x, int y)
{
}

主文件main.cpp

#include "MyGameEngine.h"
// 唯一的全局变量
MyGameEngine * g_pGE = new MyGameEngine(TEXT("MyGame"), 640, 480, 60);

int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPreInst, PSTR szCmdLine, int iCmdShow)
{
int iRet;

if (g_pGE == NULL)
   return   -1;
if (g_pGE->Init(hInst))
   iRet = g_pGE->Run();
else
   MessageBox (NULL, TEXT("游戏引擎初始化失败!"), TEXT("初始化失败"), MB_ICONERROR);
delete g_pGE;
return iRet;
}

LRESULT CALLBACK WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
return g_pGE->HandleEvent(hWnd, msg, wParam, lParam);
}

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值