如何用C++编程制作一个简单的游戏引擎
Posted watsonbu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何用C++编程制作一个简单的游戏引擎相关的知识,希望对你有一定的参考价值。
- 写一个游戏引擎类的头文件(.h);
- 写一个游戏引擎类的实现文件(.cpp);
- 在编程中如何调用游戏引擎。
一 、在VS2015中新建一个 Visual C++ 常规空项目,添加一个游戏引擎头文件实现文件。详细步骤如下:
二 、游戏引擎头文件 GameEngine.h 源代码:
#pragma once
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow);
LRESULT CALLBACK WndProc(HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam);
BOOL GameInitialize(HINSTANCE hInstance);
void GameStart(HWND hWindow);
void GameEnd();
void GameActivate(HWND hWindow);
void GameDeactivate(HWND hWindow);
void GamePaint(HDC hDC);
void GameCycle();
class GameEngine
protected:
//成员变量
static GameEngine* m_pGameEngine;
HINSTANCE m_hInstance;
HWND m_hWindow;
TCHAR m_szWindowClass[32];
TCHAR m_szTitle[32];
WORD m_wIcon, m_wSmallIcon;
int m_iWidth, m_iHeight;
int m_iFrameDelay;
BOOL m_bSleep;
public:
//构造函数/析构函数
GameEngine(HINSTANCE hInstance, LPTSTR szWindowClass, LPTSTR szTitle,
WORD wIcon, WORD wSmallIcon, int iWidth = 640, int iHeight = 480);
virtual ~GameEngine();
static GameEngine* GetEngine() return m_pGameEngine; ;
BOOL Initialize(int iCmdShow);
LRESULT HandleEvent(HWND hWindow, UINT msg, WPARAM wParam,
LPARAM lParam);
HINSTANCE GetInstance() return m_hInstance; ;
HWND GetWindow() return m_hWindow; ;
void SetWindow(HWND hWindow) m_hWindow = hWindow; ;
LPTSTR GetTitle() return m_szTitle; ;
WORD GetIcon() return m_wIcon; ;
WORD GetSmallIcon() return m_wSmallIcon; ;
int GetWidth() return m_iWidth; ;
int GetHeight() return m_iHeight; ;
int GetFrameDelay() return m_iFrameDelay; ;
void SetFrameRate(int iFrameRate)
m_iFrameDelay = 1000 / iFrameRate;
;
BOOL GetSleep() return m_bSleep; ;
void SetSleep(BOOL bSleep) m_bSleep = bSleep; ;
;
三 、游戏引擎实现文件 GameEngine.cpp 源代码:
#include "GameEngine.h"
GameEngine *GameEngine::m_pGameEngine = NULL;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow)
MSG msg;
static int iTickTrigger = 0;
int iTickCount;
if (GameInitialize(hInstance))
// 初始化游戏引擎
if (!GameEngine::GetEngine()->Initialize(iCmdShow))
return FALSE;
// 进入主消息循环
while (TRUE)
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
// 处理消息
if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
else
//确保游戏引擎没有处在休眠状态
if (!GameEngine::GetEngine()->GetSleep())
// Check the tick count to see if a game cycle has elapsed
iTickCount = GetTickCount();
if (iTickCount > iTickTrigger)
iTickTrigger = iTickCount +
GameEngine::GetEngine()->GetFrameDelay();
GameCycle();
return (int)msg.wParam;
// 结束游戏
GameEnd();
return TRUE;
LRESULT CALLBACK WndProc(HWND hWindow, UINT msg, WPARAM wParam, LPARAM lParam)
// 将所有Windows消息路由到游戏引擎
return GameEngine::GetEngine()->HandleEvent(hWindow, msg, wParam, lParam);
//-----------------------------------------------------------------
// 游戏引擎的构造函数/析构函数
//-----------------------------------------------------------------
GameEngine::GameEngine(HINSTANCE hInstance, LPTSTR szWindowClass,
LPTSTR szTitle, WORD wIcon, WORD wSmallIcon, int iWidth, int iHeight)
// 设置游戏引擎的成员变量
m_pGameEngine = this;
m_hInstance = hInstance;
m_hWindow = NULL;
if (lstrlen(szWindowClass) > 0)
lstrcpy(m_szWindowClass, szWindowClass);
if (lstrlen(szTitle) > 0)
lstrcpy(m_szTitle, szTitle);
m_wIcon = wIcon;
m_wSmallIcon = wSmallIcon;
m_iWidth = iWidth;
m_iHeight = iHeight;
m_iFrameDelay = 50; // 游戏周期,一般设为20帧/秒
m_bSleep = TRUE;
GameEngine::~GameEngine()
BOOL GameEngine::Initialize(int iCmdShow)
WNDCLASSEX wndclass;
// 为主窗口创建窗口类
wndclass.cbSize = sizeof(wndclass);
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = m_hInstance;
wndclass.hIcon = LoadIcon(m_hInstance,
MAKEINTRESOURCE(GetIcon()));
wndclass.hIconSm = LoadIcon(m_hInstance,
MAKEINTRESOURCE(GetSmallIcon()));
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = m_szWindowClass;
// 注册窗口类
if (!RegisterClassEx(&wndclass))
return FALSE;
// 根据游戏大小计算窗口大小和位置
int iWindowWidth = m_iWidth + GetSystemMetrics(SM_CXFIXEDFRAME) * 2,
iWindowHeight = m_iHeight + GetSystemMetrics(SM_CYFIXEDFRAME) * 2 +
GetSystemMetrics(SM_CYCAPTION);
if (wndclass.lpszMenuName != NULL)
iWindowHeight += GetSystemMetrics(SM_CYMENU);
int iXWindowPos = (GetSystemMetrics(SM_CXSCREEN) - iWindowWidth) / 2,
iYWindowPos = (GetSystemMetrics(SM_CYSCREEN) - iWindowHeight) / 2;
// 创建窗口
m_hWindow = CreateWindow(m_szWindowClass, m_szTitle, WS_POPUPWINDOW |
WS_CAPTION | WS_MINIMIZEBOX, iXWindowPos, iYWindowPos, iWindowWidth,
iWindowHeight, NULL, NULL, m_hInstance, NULL);
if (!m_hWindow)
return FALSE;
// 显示并更新窗口
ShowWindow(m_hWindow, iCmdShow);
UpdateWindow(m_hWindow);
return TRUE;
LRESULT GameEngine::HandleEvent(HWND hWindow, UINT msg, WPARAM wParam, LPARAM lParam)
// 将Windows消息路由到游戏引擎成员函数
switch (msg)
case WM_CREATE:
// 设置游戏窗口并开始游戏
SetWindow(hWindow);
GameStart(hWindow);
return 0;
case WM_SETFOCUS:
//激活游戏并更新睡眠状态
GameActivate(hWindow);
SetSleep(FALSE);
return 0;
case WM_KILLFOCUS:
// 停用游戏并更新睡眠状态
GameDeactivate(hWindow);
SetSleep(TRUE);
return 0;
case WM_PAINT:
HDC hDC;
PAINTSTRUCT ps;
hDC = BeginPaint(hWindow, &ps);
// 绘制游戏
GamePaint(hDC);
EndPaint(hWindow, &ps);
return 0;
case WM_DESTROY:
// 结束游戏并退出应用程序
GameEnd();
PostQuitMessage(0);
return 0;
return DefWindowProc(hWindow, msg, wParam, lParam);
四 、调用游戏引擎,添加一个要做的游戏应用文件 FIRSTGAME.cpp 源码如下:
#pragma once
#include <windows.h>
#include "Resource.h"
#include "GameEngine.h"
GameEngine* g_pGame;
BOOL GameInitialize(HINSTANCE hInstance)
// 创建游戏引擎
g_pGame = new GameEngine(hInstance, TEXT("第一个游戏"),
TEXT("第一个游戏"), IDI_ICON1, IDI_ICON2);
//IDI_ICON1, IDI_ICON2 这是建立游戏资源.ico后缀图片的ID
if (g_pGame == NULL)
return FALSE;
// 设定游戏速度为15帧/秒
g_pGame->SetFrameRate(15);
return TRUE;
void GameStart(HWND hWindow)
void GameEnd()
// 清理游戏引擎
delete g_pGame;
void GameActivate(HWND hWindow)
HDC hDC;
RECT rect;
// 在游戏屏幕上绘制激活文本
GetClientRect(hWindow, &rect);
hDC = GetDC(hWindow);
DrawText(hDC, TEXT("第一个游戏开始!"), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
ReleaseDC(hWindow, hDC);
void GameDeactivate(HWND hWindow)
HDC hDC;
RECT rect;
// 在游戏屏幕上绘制激停文本
GetClientRect(hWindow, &rect);
hDC = GetDC(hWindow);
DrawText(hDC, TEXT("第一个游戏结束!"), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
ReleaseDC(hWindow, hDC);
void GamePaint(HDC hDC)
void GameCycle()
HDC hDC;
HWND hWindow = g_pGame->GetWindow();
// 在游戏屏幕上的任意位置绘制游戏图标
hDC = GetDC(hWindow);
DrawIcon(hDC,200,200,(HICON)(WORD)GetClassLong(hWindow, GCL_HICON));
ReleaseDC(hWindow, hDC);
五 、编译后运行画面:
六 、源代码出自如下书籍资料:
1.游戏编程精粹 作者:(美) Michael Dickheiser著
2.游戏编程入门 作者:(美) Michael Morrison著
如何为 Python 制作 C++ 库
【中文标题】如何为 Python 制作 C++ 库【英文标题】:How to make a C++ library for Python 【发布时间】:2014-07-16 10:39:03 【问题描述】:我是面向对象编程的新手,我正在努力寻找一个关于如何用 C++ 创建一个可以导入 Python 的库的好教程。
目前我只是想做一个简单的例子,将两个数字相加。我对这个过程感到困惑。本质上我希望能够在 Python 中做这样的事情:
import MyCPPcode
MyCPPcode.Add(5,3) #function prints 5+3=8
我不要求提供完整的代码示例,只是我需要采取的步骤。 我需要制作 .dll 还是静态库?我正在使用 MS Visual Studio 2013。
此外,该过程是否以任何方式为 Python 定制 C++ 库代码,或者该库是否也可用于其他语言?
【问题讨论】:
Boost Python 库怎么样?稍微搜索一下就不会难找到自己。 @JoachimPileborg 从我已经研究/尝试使用 Boost 的一个简单示例来看,这样的简单示例比我仅使用ctypes
更复杂。
你检查过tutorial中的例子吗?比这更简单的东西很难被击败。
***.com/questions/5081875/ctypes-beginner 太简单了。
可能你不会坚持写这么琐碎的代码。 Boost 当然有更大的开销,但是如果你的 c++ 库获取类和更多功能,使用 ctypes
会变得很困难......
【参考方案1】:
虽然我无法指导您完成整个过程,因为我对python不太了解,以下是我所知道的:
绝对有可能。虽然不适合刚接触面向对象编程的人,但它被称为 python-C/C++ API。如果你在 python 文档中搜索它,有几个章节是关于它的。
虽然您展示的示例函数可能看起来像来自 python 的函数,但该过程在 c++ 中更加冗余(在幕后)。有一些工具可以解决这个问题,例如 Cython,但如果你想学习,我建议使用纯 Python API。
至于其他语言的可用性...嗯,内部函数(即添加两个数字)当然是通用 c++,因此您可以在其他项目中重用它们,但是是的,创建的库将可以使用python,而不是别的东西。
【讨论】:
以上是关于如何用C++编程制作一个简单的游戏引擎的主要内容,如果未能解决你的问题,请参考以下文章