利用CEGUI+Lua实现灵活的游戏UI框架

          在上一篇文章中,介绍了一种基于组件方式的游戏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;
    }

}
;
/// 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);
}
;

        这里需要说明一下,_pGameGUI的作用。CEGUI是以树形结构来管理每个UI部件的,所以在游戏场景中,我们需要这么一个根节点,_pGameGUI就是这个根的指针,也可以理解为顶层容器。如果你对CEGUI::DirectX9Render的使用有疑问,请参考在DirectX 3D中使用CEGUI一文,在此就不再迭述。下面是GUISystem.cpp代码:

#include  " GUISystem.h "
  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
下面是基于glfw的实现glfwSetScrollCallback,并在实现中调用injectMouseWheelChange通知cegui的代码: ```cpp #include <CEGUI/CEGUI.h> #include <CEGUI/RendererModules/OpenGL/GL3Renderer.h> #include <GLFW/glfw3.h> GLFWwindow* window; CEGUI::OpenGL3Renderer* renderer; CEGUI::GUIContext* context; void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) { CEGUI::Vector2f mousePos = context->getMouseCursor()->getPosition(); CEGUI::MouseWheelEventArgs args; args.window = context->getRootWindow(); args.position = mousePos; args.scroll = static_cast<float>(yoffset); context->injectMouseWheelChange(args); } int main() { // 初始化glfw和CEGUI glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); window = glfwCreateWindow(800, 600, "CEGUI with GLFW", nullptr, nullptr); glfwMakeContextCurrent(window); CEGUI::OpenGL3Renderer& renderer = CEGUI::OpenGL3Renderer::create(); CEGUI::System::create(renderer); // 初始化CEGUI上下文和根窗口 context = &CEGUI::System::getSingleton().getDefaultGUIContext(); CEGUI::WindowManager& winMgr = CEGUI::WindowManager::getSingleton(); CEGUI::Window* rootWindow = winMgr.createWindow("DefaultWindow", "root"); context->setRootWindow(rootWindow); // 注册glfw的滚动回调函数 glfwSetScrollCallback(window, scroll_callback); // 主循环 while (!glfwWindowShouldClose(window)) { glfwPollEvents(); // 更新CEGUI上下文 context->injectTimePulse(1.0f); CEGUI::System::getSingleton().renderAllGUIContexts(); glfwSwapBuffers(window); } // 清理CEGUI和glfw CEGUI::System::destroy(); CEGUI::OpenGL3Renderer::destroy(renderer); glfwTerminate(); return 0; } ``` 在上面的代码中,我们使用glfwSetScrollCallback注册了一个滚动回调函数scroll_callback。当滚轮滚动时,该回调函数会被调用。在scroll_callback中,我们调用context->injectMouseWheelChange(args)来通知CEGUI滚轮事件的发生。其中,args包含了滚轮事件的相关信息,例如滚轮滚动的距离、滚轮事件发生时鼠标的位置等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值