1. 程式人生 > >比較簡單的2D遊戲引擎C++類

比較簡單的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);
}

相關推薦

比較簡單2D遊戲引擎C++

//GameEngine.h檔案: #pragma once#include <windows.h> LRESULT CALLBACK WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);clas

WIN7+VS2010編譯兩款2D遊戲引擎 風魂和HGE(C++原始碼)

新浪部落格 http://service.weibo.com/staticjs/weiboshow.swf?verifier=a63d6d67&uid=1283818905&width=230&height=500&fansRow=2&a

windows下用mingw32+sdl進行簡單2d遊戲開發(c語言)

#include<stdio.h> #include "SDL/SDL.h" #include "SDL/SDL_image.h" SDL_Surface *screen; void video_init(){ //遊戲圖形模式初始化 if(SDL_Init(SDL_INIT_VIDEO

2D遊戲引擎的測試程式以及截圖

基於HGE作為核心的,雖然HGE不咋地,不過至少能用--!本來整了一個Ogre3D的閹割版:Ogre2D.奈何效率低下了,似乎也太過於複雜了>_<遊戲引擎基本上建立在我從CEGUI剝離的事件系統之上的.寫了一個演示遊戲:連連看.還有一個測試程式.測試程式的截圖如下:連連看截圖如下:

雜談:Gamemaker 2d遊戲引擎

最近喜歡上這款遊戲引擎,製作2d遊戲。我一直比較喜歡2d類的遊戲,至於3d因為製作成本較高,加上沒這種條件製作。現在能喜歡上做一些小遊戲。過去一直做頁遊,做介面,做模組比較多一點。使用GameMaker 製作的2d 遊戲 可以發揮很大想象空間,細心去挖潛還是可以

Java 2D 遊戲引擎開發(一)

以前就想用java做桌面端遊戲,基於awt和swing,這樣可以在輕易的跨平臺執行,同時還比Python,Javascript之類的高效。不過很可惜,一直沒有找到一個合適的java寫的2d遊戲引擎。前幾天偶然發現了一本書,科學出版社出版的《Java遊戲程式設計》,譯自Dav

一個容易上手的2D遊戲引擎love2d (lua)

給大家推薦一個容易上手的2D遊戲引擎love2d 該遊戲引擎包括一個圖形引擎和一個物理引擎Box2d,整體表現效果不俗,且使用Lua作為程式設計介面,比較容易上手。love2d的網址是:http://love2d.org/

開源2D遊戲引擎(Java&Android),LGame-0.3.2版正式釋出

PS:為了多平臺版本的優化與整合,本年內(2011)不會正式釋出0.3.3版LGame。不過,LGame專案SVN根目錄下有LGame-Anroid-0.3.3版的測試版jar及原始碼提供。除尚未附帶RTS模組外,該版與正式的0.3.3內容完全一致(此版會每週進行一次Bug

橫跨2D與3D!專屬C#開發者的超強遊戲引擎Paradox

Paradox是日本Silicon Studio公司推出的一款開源的全新遊戲開發引擎,能夠讓你使用C#程式語言來構建出符合心意的跨平臺遊戲,支援iOS、Android和Windows Phone等平臺,程式碼已託管至Github上。其中的Game Studio能夠很好的幫你管理所有的遊戲資源,實時的展現

Unity3D 遊戲引擎C#使用Socket與HTTP連接server數據傳輸包

tco 類型 oba connect asp bre amp 客戶 star 近期比較忙。有段時間沒寫博客拉。近期項目中須要使用HTTP與Socket。雨松MOMO把自己這段時間學習的資料整理一下。有關Socket與HTTP的基礎知識MOMO就不贅述拉,不懂得朋友自己

分享我寫的2D格鬥遊戲C語言實現

fpm cal srm i2c cga wsb rpi blank iii Json、FastJson、Gson 數據結構對單鏈表進行數據排序 請教各位幾個小問題,有點暈了不太理解 StringUtil對字符串類型參數進行校驗的工具類 11r玖橇粱http://p.baid

Xenko C#開源遊戲引擎入門

on() actor scale con 為什麽 pro and 三維 str 最近使有和 Three.js 開發三維頁面,覺得很有趣。以前在做WP應用的時候使用過MonoGame做過一點東西,後來Windows 10上來,MonoGame好像不怎麽支持了,也沒

遊戲引擎架構》讀書筆記-遊戲引擎中的C++

《遊戲引擎架構》在兩年前就買了,而且自己也大體的看過一遍,因為自己想學習引擎的底層知識,所以重新又找出了這本書再讀一遍,並把根據自己的理解寫一些讀書筆記在這裡與大家交流。        閒話少續,開始本篇的內容,這本書的第一部分是基礎篇,第一章概述

2D遊戲生成平滑地形的最簡單的方法是什麼?

https://gxnotes.com/article/82289.html 問題描述 為”Moon Buggy”或“路線960”的2D遊戲生成平滑地形的最簡單的方法是什麼? 我在stackoverflow.com得到一個答案,生成一個隨機高度的陣列,並在後面模糊。是的,這是

Godot3遊戲引擎入門之二:第一個簡單遊戲場景

一、前言 最近工作時間安排地非常緊湊,除了週日一天,已經沒有其他空閒時間了。不過到了 10 月份會慢慢恢復,目前我在抽出一點時間好好準備這個 Godot 系列,邊寫邊學習邊迎接Godot 3.1 版本的到來,也算是一件高興地事情,哈哈。 :sunglasses:

關於複製建構函式及關於簡單函式使用(C++)

剛學C++,關於複製建構函式的思考: 關於複製建構函式 : 相當於在記憶體新建一個類,再把資料複製給目標。可以是不完全複製(也是其存在意義),比如資料加減等。 三種使用情景: 1.用已知物件初始化信物件; 2.形參為物件; 3.返回值為物件; 簡單函式: 1.宣

C 遊戲引擎開發

                遊戲引擎開發  你是否夢想寫一部格鬥遊戲但卻無從著手呢?是否你只因遊戲開發好玩而對之感興趣?本文我們將分析一個通用的跨平臺遊戲引擎,每個遊戲開發新手都可以自由地使用它。  1. 3D遊戲引擎的簡短歷史  在遊戲開發中,從一開始就確定正確的開發平臺是很重要的。是否你的遊戲支援Wi

C++和物件的簡單認識

C++類的定義: 類是定義同一類所有物件的變數和方法的藍圖或原型 類也可以定義類變數和類方法。可以從類的例項中或者直接從類中訪問類變數和方法。類方法只能操作類變數,不必訪問例項變數或例項方法。系統在第一次在程式中遇到一個類時為這個類建立它的所有類變數的拷貝,這個類的所有例項共

C#實現簡單的K-means聚演算法

namespace K_means{    public class Kmeans    {        double[,] inPut;//資料        int k;//類別數        int Num;//檔案數        int sub;//特徵值數  

2D的RPG遊戲人物角色移動程式碼(以egret遊戲引擎、TypeScript語言為例)

一般2D的RPG人物移動有三種: (一)背景固定,角色移動 (二)角色固定,背景移動 (三)角色移動,背景動態移動 第一種在移動端的遊戲比較少見,但在PC端的模擬類遊戲比較常見,因為螢幕較大,背景固定即可,角色在背景上移動;第二種在移動端比較多見,就是角色固定在螢幕中間