在上一篇文章中,介绍了一种基于组件方式的游戏UI架构设计方案,在这里,笔者将介绍如何利用CEGUI和Lua来实现这种灵活的框架。
CEGUI是一个兼容OpenGL、DirectX的优秀开源GUI库,关于她的介绍以及如何在Direct3D中使用她,可以参考
http://blog.csdn.net/Lodger007/archive/2007/07/02/1675141.aspx一文。Lua是一种强大的脚本语言,她使用栈作为数据接口,能够很容易地与其它语言交互,关于她的介绍可以参考
http://www.lua.org/,以及笔者以前翻译的三篇系列文章:Lua入门(
http://blog.csdn.net/Lodger007/archive/2006/06/26/836466.aspx)、调用Lua函数(
http://blog.csdn.net/Lodger007/archive/2006/06/26/836897.aspx)、在Lua中调用C++函数(
http://blog.csdn.net/Lodger007/archive/2006/06/26/837349.aspx)。
在实现中,作为UI组件管理器的GUISystem是一个单件,这样,你能够很方便地在任何地方使用其全局唯一的对象。下面是Singleton和GUISystem的实现代码:
/**/
/// Singleton.h
#pragma once
#define SINGLETON(class_name)
friend class Singleton < class_name > ;
private :
class_name() ... {}
~ class_name() ... {}
class_name( const class_name & );
class_name & operator = ( const class_name & );
#define SINGLETON2(class_name)
friend class Singleton < class_name > ;
private :
class_name( const class_name & );
class_name & operator = ( const class_name & );
template < typename T > class Singleton
... {
protected:
Singleton() ...{}
virtual ~Singleton() ...{}
Singleton(const Singleton< T >&) ...{}
Singleton< T >& operator = (const Singleton< T >&) ...{}
public:
static T& GetSingleton()
...{
static T _singleton;
return _singleton;
}
} ;
#pragma once
#define SINGLETON(class_name)
friend class Singleton < class_name > ;
private :
class_name() ... {}
~ class_name() ... {}
class_name( const class_name & );
class_name & operator = ( const class_name & );
#define SINGLETON2(class_name)
friend class Singleton < class_name > ;
private :
class_name( const class_name & );
class_name & operator = ( const class_name & );
template < typename T > class Singleton
... {
protected:
Singleton() ...{}
virtual ~Singleton() ...{}
Singleton(const Singleton< T >&) ...{}
Singleton< T >& operator = (const Singleton< T >&) ...{}
public:
static T& GetSingleton()
...{
static T _singleton;
return _singleton;
}
} ;
/**/
/// GUISystem
#pragma once
#include " Singleton.h "
#include " UIObject.h "
#include < CEGUI.h >
#include < RendererModules / directx9GUIRenderer / d3d9renderer.h >
#include < map >
#include < set >
class GUISystem : public Singleton < GUISystem >
... {
SINGLETON( GUISystem )
private:
std::map<std::string , UIObject*> _UIMap; /**//// 游戏中需要用到的所有UI对象
typedef std::map<std::string , UIObject*>::iterator MapIter;
std::set<UIObject*> _curUIList; /**//// 当前场景中使用的UI对象列表
CEGUI::DirectX9Renderer* _pCEGUIRender; /**//// CEGUI Render
CEGUI::Window* _pGameGUI; /**//// 顶层UI
private:
/**//** 载入所有UI对象 */
void LoadAllUI();
/**//** 从脚本中读入场景UI */
void ReadFromScript(const std::string& id);
public:
/**//** 初始化GUI系统 **/
bool Initialize(LPDIRECT3DDEVICE9 pD3DDevice);
/**//** 得到当前需要的UI对象 */
void LoadCurUI(int sceneId);
/**//** 得到当前场景所需的UI对象 */
std::set<UIObject*>& GetCurUIList();
/**//** 得到UI对象 */
UIObject* GetUIObject(const std::string id);
} ;
#pragma once
#include " Singleton.h "
#include " UIObject.h "
#include < CEGUI.h >
#include < RendererModules / directx9GUIRenderer / d3d9renderer.h >
#include < map >
#include < set >
class GUISystem : public Singleton < GUISystem >
... {
SINGLETON( GUISystem )
private:
std::map<std::string , UIObject*> _UIMap; /**//// 游戏中需要用到的所有UI对象
typedef std::map<std::string , UIObject*>::iterator MapIter;
std::set<UIObject*> _curUIList; /**//// 当前场景中使用的UI对象列表
CEGUI::DirectX9Renderer* _pCEGUIRender; /**//// CEGUI Render
CEGUI::Window* _pGameGUI; /**//// 顶层UI
private:
/**//** 载入所有UI对象 */
void LoadAllUI();
/**//** 从脚本中读入场景UI */
void ReadFromScript(const std::string& id);
public:
/**//** 初始化GUI系统 **/
bool Initialize(LPDIRECT3DDEVICE9 pD3DDevice);
/**//** 得到当前需要的UI对象 */
void LoadCurUI(int sceneId);
/**//** 得到当前场景所需的UI对象 */
std::set<UIObject*>& GetCurUIList();
/**//** 得到UI对象 */
UIObject* GetUIObject(const std::string id);
} ;
这里需要说明一下,_pGameGUI的作用。CEGUI是以树形结构来管理每个UI部件的,所以在游戏场景中,我们需要这么一个根节点,_pGameGUI就是这个根的指针,也可以理解为顶层容器。如果你对CEGUI::DirectX9Render的使用有疑问,请参考在DirectX 3D中使用CEGUI一文,在此就不再迭述。下面是GUISystem.cpp代码:
#include
"
GUISystem.h
"