HGE游戏引擎是一个开源2D游戏引擎,基于directX。
它的渲染及逻辑是基于帧回调的框架模式,
其提供一些基本的图像操作和输入控制功能。
我在之前写一个2D游戏的时候对它整个框架进行了一次封装,很多地方写得比较恶心,请原谅我在变量上命名的不规范。
在此分享出来,主要可以参考一下大体框架吧。
HGE游戏引擎基于帧的回调让我很不爽,因为咱的游戏逻辑一般是连续的,跟具体帧无关,所以我把整个HGE跑在自己的一个线程之中。我的游戏逻辑部分通过发消息,通知界面更新 以及获取用户输入。
在HGE的主框架下分四个部分
1. 资源管理 2.消息管理 3.声音管理 4.UI管理
下面是GDE_UI_HGEFramework.h
/* * CopyRight 2009 - 2010 GDE工作室 * 游戏UI系统 - HGE 引擎框架类 * =================================== * 整个UI系统调用HGE游戏引擎的主框架 * * 2010/01/08 cg create */ #ifndef GDE_UI_HGE_FRAMEWORK_H_ #define GDE_UI_HGE_FRAMEWORK_H_ #include "GDE_UI_ResourceManager.h" #include "GDE_UI_UIManager.h" #include "GDE_UI_MessageManager.h" #include "GDE_UI_SoundManager.h" #pragma comment(lib,"GDE_UI/HGE/lib/hge.lib") #pragma comment(lib,"GDE_UI/HGE/lib/hgehelp.lib") #pragma comment(linker, "/NODEFAULTLIB:libc.lib") #include "GDE_UI_thread_core.h" namespace GDE { namespace GDE_UI { //HGE引擎框架 class HGE_Framework { public: //唯一实例 static HGE_Framework* Instance() { static HGE_Framework* instance_ = 0; if( !instance_ ) { instance_ = new HGE_Framework(); } return instance_; } ~HGE_Framework() { delete m_ResManager; delete m_MessageManager; delete m_SoundManager; delete m_UIManager; } //开始运行 void Run() { //获取资源指针 pHGE = m_ResManager->GetHGEPtr(); pGUI = m_ResManager->GetGuiPtr(); //初始化子类中的HGE核心指针 m_MessageManager->Ready(); m_UIManager->Ready(); //开始主循环 if(pHGE->System_Initiate() && pHGE) { pHGE->System_Start(); } else MessageBox(NULL, pHGE->System_GetErrorMessage(), "Error", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL); } //HGE框架逻辑函数 static bool FrameFunc() { SMART_LOCK( 0 )//线程锁 HGE_Framework::Instance()->m_MessageManager->ProcessMessage();//处理消息 HGE_Framework::Instance()->m_UIManager->Handler();//处理用户操作 return FALSE; } //HGE框架渲染函数 static bool RenderFunc() { SMART_LOCK( 0 )//线程锁 HGE_Framework::Instance()->pHGE->Gfx_Clear(0); //清屏 HGE_Framework::Instance()->pHGE->Gfx_BeginScene(); //开始渲染 HGE_Framework::Instance()->m_UIManager->Render();//绘制 HGE_Framework::Instance()->pHGE->Gfx_EndScene(); //结束渲染 return FALSE; } //成员子管理器指针 ResourceManager* m_ResManager; MessageManager* m_MessageManager; SoundManager* m_SoundManager; UIManager* m_UIManager; //HGE系统相关资源指针 HGE* pHGE; hgeGUI* pGUI; private: //私有构造,不允许实例化 HGE_Framework() :pHGE(0) ,pGUI(0) { m_ResManager = new ResourceManager(); m_MessageManager = new MessageManager(); m_SoundManager = new SoundManager(); m_UIManager = new UIManager(); } }; } } #endif;
资源管理类,下面给出
GDE_UI_ResourceManager.h
/* * CopyRight 2009 - 2010 GDE工作室 * 游戏UI系统 - HGE 引擎框架类 - 资源管理器 * =================================== * HGE引擎资源管理类 * * 本类的资源主要实现对HGE资源的维护 和对HGE API封装提供工具集 * 并维护HGE的配置环境 * * 2010/01/08 cg create */ #ifndef GDE_UI_FRAMEWORK_RESOURCEMANAGER_H_ #define GDE_UI_FRAMEWORK_RESOURCEMANAGER_H_ #include "./HGE/cn/GfxFont.h" #include "./HGE/cn/GfxEdit.h" #include "./HGE/include/hge.h" #include "./HGE/include/hgegui.h" #include "./HGE/include/hgeguictrls.h" #include "./HGE/include/hgeresource.h" #include <string> namespace GDE { namespace GDE_UI { //资源管理类 class ResourceManager { public: //构造函数,加载HGE全局资源 ResourceManager(); //析构函数,释放HGE全局资源 ~ResourceManager(); //获取HGE指针 HGE* GetHGEPtr() { return pHGE; } //获取GUI指针 hgeGUI* GetGuiPtr() { return pGUI; } //读取图片 void LoadImage( std::string const& filename, hgeSprite*& p_sprite, HTEXTURE& tex ); private: HGE* pHGE; hgeGUI* pGUI; hgeResourceManager m_HgeResManager; }; } } #endif
GDE_UI_ResourceManager.cpp
#include "GDE_UI_HGEFramework.h" #include "GDE_UI_ResourceManager.h" namespace { std::string const RES_MANAGER_FILENAME = "res/res_s"; int const WIN_SCREENWIDTH = 800; int const WIN_SCREENHEIGHT = 600; std::string const WIN_TITILE = "HGE TEST WINDOW"; int const WIN_COLORMODE = 32; int const WIN_MAXFPS = 100; int const WIN_WINDOWED = true; } namespace GDE { namespace GDE_UI { //构造函数 ResourceManager::ResourceManager() : m_HgeResManager( RES_MANAGER_FILENAME.c_str() ) { //建立HGE全局实例 pHGE = hgeCreate(HGE_VERSION); //初始化配置 pHGE->System_SetState(HGE_INIFILE, "hgedemo.ini"); pHGE->System_SetState(HGE_LOGFILE, "hgedemo.log"); pHGE->System_SetState(HGE_FRAMEFUNC, &HGE_Framework::FrameFunc); pHGE->System_SetState(HGE_RENDERFUNC, &HGE_Framework::RenderFunc); pHGE->System_SetState(HGE_TITLE, WIN_TITILE.c_str()); pHGE->System_SetState(HGE_SCREENWIDTH, WIN_SCREENWIDTH); pHGE->System_SetState(HGE_SCREENHEIGHT, WIN_SCREENHEIGHT); pHGE->System_SetState(HGE_SCREENBPP, WIN_COLORMODE); pHGE->System_SetState(HGE_FPS,WIN_MAXFPS); pHGE->System_SetState(HGE_WINDOWED, WIN_WINDOWED); pHGE->System_SetState(HGE_HIDEMOUSE, false); pHGE->System_SetState(HGE_USESOUND, false); pHGE->System_SetState(HGE_DONTSUSPEND, true);//失去焦点不挂起 pHGE->System_SetState((hgeIntState)14, (int)0xFACE0FF); //禁用HGE LOGO //初始化GUI pGUI = new hgeGUI(); pGUI->SetNavMode(HGEGUI_UPDOWN | HGEGUI_CYCLED); pGUI->Enter(); } ResourceManager::~ResourceManager() { // 销毁gui delete pGUI; // 销毁资源管理器 m_HgeResManager.Purge(); // HGE结束 pHGE->System_Shutdown(); pHGE->Release(); } void ResourceManager::LoadImage( std::string const& filename, hgeSprite*& p_sprite, HTEXTURE& tex ) { if( p_sprite ) delete p_sprite; //销毁之前的图片 tex = pHGE->Texture_Load( filename.c_str() ); //装载纹理 int w = pHGE->Texture_GetWidth( tex ); int h = pHGE->Texture_GetHeight( tex ); p_sprite = new hgeSprite( tex, 0, 0, w, h ); //剪裁精灵 } } }
比较重要的是消息传递机制,我仿照了MFC的消息宏定义机制,下面给出消息模块的核心代码
//消息映射宏定义 #define BEGIN_MESSAGE_MAP()\ typedef void (MessageManager::*MessageFunction)();\ std::map<UIMessage, MessageFunction> message_functions_;\ void InitMessageMap()\ { #define ON_MESSAGE( ID, memberFuc )\ message_functions_[ID] = &MessageManager::memberFuc; #define END_MESSAGE_MAP\ } .... //这里是我游戏中具体的一些消息 //消息类型 typedef int UIMessage; UIMessage const UIMessage_UpdateBackImg = 0; //更新背景图片 UIMessage const UIMessage_AddRole = 10; //增加角色 UIMessage const UIMessage_RemoveRole = 11; //删除角色 UIMessage const UIMessage_UpdateRole = 12; //更新角色列表 UIMessage const UIMessage_AttackInfo = 13; //角色掉血显示 UIMessage const UIMessage_UpdateDialog = 20; //更新对话框 UIMessage const UIMessage_HideDialog = 21; //隐藏对话框 UIMessage const UIMessage_UpdateSmallMap = 30; //更新小地图 UIMessage const UIMessage_UpdateGameInfo = 40; //更新游戏提示信息 UIMessage const UIMessage_UpdateButton = 50; //增加按钮 UIMessage const UIMessage_RemoveButton = 51; //删除按钮 UIMessage const UIMessage_RemoveAllButtons = 52; //移除所有按钮 UIMessage const UIMessage_UpdatePopMenu = 60; //弹出菜单 UIMessage const UIMessage_HidePopMenu = 61; //隐藏弹出菜单 UIMessage const UIMessage_UpdateZoneBlock= 70; //更新地图块 UIMessage const UIMessage_HideZoneBlock = 71; //清除地图块 //消息映射实现 BEGIN_MESSAGE_MAP() ON_MESSAGE( UIMessage_UpdateBackImg, UpdateBackImage ) ON_MESSAGE( UIMessage_AddRole, AddRole ) ON_MESSAGE( UIMessage_RemoveRole, RemoveRole ) ON_MESSAGE( UIMessage_UpdateRole, UpdateRole ) ON_MESSAGE( UIMessage_AttackInfo, RoleAttackInfo ) ON_MESSAGE( UIMessage_UpdateDialog, UpdateDialog ) ON_MESSAGE( UIMessage_HideDialog, HideDialog ) ON_MESSAGE( UIMessage_UpdateSmallMap, UpdateSmallMap ) ON_MESSAGE( UIMessage_UpdateGameInfo, UpdateGameInfo ) ON_MESSAGE( UIMessage_UpdateButton, UpdateButton ) ON_MESSAGE( UIMessage_RemoveButton, RemoveButton ) ON_MESSAGE( UIMessage_RemoveAllButtons, RemoveAllButtons ) ON_MESSAGE( UIMessage_UpdatePopMenu, UpdatePopMenu ) ON_MESSAGE( UIMessage_HidePopMenu, HidePopMenu ) ON_MESSAGE( UIMessage_UpdateZoneBlock, UpdateZoneBlock ) ON_MESSAGE( UIMessage_HideZoneBlock, HideZoneBlock ) END_MESSAGE_MAP() //处理消息 void ProcessMessage() { for( int i = 0; i < m_MessageList.size(); ++i ) { ( this->*message_functions_[m_MessageList[i]] )(); } m_MessageList.clear(); }
最后是整个HGE引擎启动的方式
GDE_UI_HGE.h
#ifndef GDE_UI_HGE_H_ #define GDE_UI_HGE_H_ #include <windows.h> #include <string> #include "GDE_UI_HGEFramework.h" /* GDE HGE游戏引擎模块 2009-11-21 var | author | brief ================================================ 1.0 cg create */ namespace GDE { namespace GDE_UI { //HGE线程入口 static DWORD WINAPI HGEThreadProc(LPVOID lpParameter) { HGE_Framework::Instance()->Run(); return 0; } } } #endif
游戏初始化的时候
//创建hge线程
hge_thread = CreateThread( NULL, 0,
HGEThreadProc, NULL, 0, NULL );
就可以了