HGE中的游戏GUI代码阅读

转载 2008年05月01日 23:34:00
HGE中的游戏GUI代码阅读

第一部分:

HGE helper类中的GUI:

引擎版本:1.60release。



文件:hgegui.h , hgegui.cpp, hgeguictrls.h , hgeguictrls.cpp

大致类图:



其中,hgeGUIObject是抽象基类,具体的控件类如按钮,文本标签,都是从它派生而来。HgeGUI属于整个GUI系统的manager,它会保存所有的控件。

关于hgeGUIObject的8个成员变量,文档里已经有所描述:

int id; //控件ID

bool bStatic; //是否可以接受键盘焦点

bool bVisible; //是否可见

bool bEnabled; //是否有效

hgeRect rect; //控件大小



hgeGUI *gui; //其属于的 manager ,相当于父对象

hgeGUIObject *next; //用于双向链表,把所有控件连接在一起

hgeGUIObject *prev;

static HGE *hge; //方便使用HGE接口

关于其部分接口的描述:

Render: 用于渲染控件到屏幕上

Update: 用于更新其动画

Enter: 控件刚显示时的动画

Leave: 控件要消失时的动画

IsDone: 控件刚显示和消失时的状态查询函数



该类也就是提供了一个抽象而已,利用C++语言的多态机制来方便hgeGUI管理所有的控件。其他具体的控件继承了hgeGUIObject后,必须实现构造函数和Render函数。



关于hgeGUI:

这个类应该属于manager。它负责管理所有的控件。

其数据成员:

hgeGUIObject *ctrls; //保存所有控件

hgeGUIObject *ctrlLock; //可能是用来保存当前被鼠标操作的控件

hgeGUIObject *ctrlFocus; //保存焦点控件

hgeGUIObject *ctrlOver; //用来保存鼠标指针所指的控件



int navmode;

int nEnterLeave;

hgeSprite *sprCursor; //渲染鼠标指针用的



float mx,my; //鼠标坐标

int nWheel; //滚轮偏移量

bool bLPressed, bLLastPressed;//本帧左键状态,上一帧的左键状态

bool bRPressed, bRLastPressed;

其Update方法会负责控件的进入和离开动画,还会负责整体的状态设置---哪些控件拥有焦点,哪些控件被鼠标正在操作,哪些控件正被鼠标指针指着,这些控件它都会保存起来。(也就是说,我们还是可以通过检查控件的状态来设置当鼠标指针在其上时的新动画。)



总体而言,该引擎的GUI还是很简单的。一个manager,负责管理所有的控件,然后一个抽象基类,用来协助manager管理---其他具体的控件都必须从那个抽象基类派生。



下面具体看一个Button控件:

Button类的定义如下:

class hgeGUIButton : public hgeGUIObject

{

public:

hgeGUIButton(int id, float x, float y, float w, float h, HTEXTURE tex, float tx, float ty);

virtual ~hgeGUIButton();



void SetMode(bool _bTrigger) { bTrigger=_bTrigger; }

void SetState(bool _bPressed) { bPressed=_bPressed; }

bool GetState() const { return bPressed; }



virtual void Render();

virtual bool MouseLButton(bool bDown);



private:

bool bTrigger;

bool bPressed;

bool bOldState;

hgeSprite *sprUp, *sprDown;

};

其中bTrigger表示该按钮的行为是否象一个RadioButton,bPressed表示当前按钮是否被按下,bOldState表示上一次按钮状态,特别用来实现bTrigger的,sprUp,sprDown分别用来绘制弹起和按下时的按钮外观。这两个精灵的创建都是从构造函数的tex上创建而来的,它要求两个状态必须保存在一幅纹理上,且顺序为从左至右。

按钮的实现代码也很简单:

void hgeGUIButton::Render()

{

if(bPressed) sprDown->Render(rect.x1, rect.y1);

else sprUp->Render(rect.x1, rect.y1);

}



bool hgeGUIButton::MouseLButton(bool bDown)

{

if(bDown)

{

bOldState=bPressed; bPressed=true;

return false;

}

else

{

if(bTrigger) bPressed=!bOldState;

else bPressed=false;

return true;

}

}



联系起来,当hgeGUI::Update里处理ProcessCtrl时,如果鼠标左键按下且其指针在按钮范围内,那么就调用hgeGUIButton::MouseLButton( true ),这个时候button的bPressed=true,那么在渲染的时候,自然就表现出被按下时的状态。

事实上对于这种类型的按钮---如同windows下的窗体按钮,我们一般不检查其是否被按下,而是检查其是否发生了clicked 这个事件,而这个事件是在先按下在弹起的情况下发生的。因此,判断该事件发生的条件就为:上一帧状态被按下,这一帧没被按下。



虽然HGE引擎的GUI很简单,但是其扩展性很好。因为hgeGUI::Update基本上派发了所有控件需要的消息---键盘操作,以及鼠标操作;而hgeGUIObject基类的很多成员函数都会处理这些消息,我们只需要派生hgeGUIObject,然后重载我们需要的消息处理即可。

第二部分:

HGE扩展GUI库,从HGE官方论坛下载(作者不明):

工程结构:



其中,guitest.cpp为测试文件。



类结构:



整个系统的工作原理:

用户继承抽象基类GUIApp,实现具体的OnEvent函数,然后该类会管理所有的GUIAppWindow对象,GUIAppWindow窗口对象会管理其上的所有子控件。



相应地,GUIApp派生类会直接得到鼠标和键盘消息,然后派发给所有窗口对象,然后窗口对象再把消息派发到具体的控件对象上。



这种Parent-Child关系大致为:


GUIAppWindow类保存有其所属的GUIApp对象指针,每个具体的控件又保存有其所属的GUIAppWindow 的对象指针。



当一个控件处理了某个事件后,例如按钮处理了鼠标单击事件,它就需要告诉外界用户单击了这个按钮。这里采用的方法是:在基类GUIAppObject里定义了一个虚函数OnEvent( int id)

,然后在其派生类GUIAppWindow里把这个函数重载为纯虚函数,函数有一个参数,那就是控件ID。当一个控件处理了某个事件后,就通过其内部保存的父窗口指针来调用OnEvent函数,然后GUIAppWindow的派生类---如果该类能产生对象,那么其必然实现了OnEvent的具体代码(这就是为什么在GUIAppWindow里要把OnEvent又重载为纯虚函数的原因),然后在此代码里,窗口根据传进来的控件ID来得知哪个控件发生了事件!



GUIAppWindow里有一个容器,它保存了所有该窗口上的控件。



所有控件再创建时,都是以其父窗口为参考坐标系的,也就是相对坐标,但是其实际保存的坐标却是绝对坐标—既相对于整个屏幕的坐标(如果是窗口程序,就相对于整个窗口)。大致过程为:在GUIAppWindow派生类中创建子控件时,给子控件指定的坐标为相对坐标,然后当 AddCtrl 时就会重新把子控件的坐标改变为绝对坐标。



GUIApp里直接有了BeginScene和EndScene的渲染代码。



要使用该扩展库,大致步骤为:

1. 继承GUIAppWindow类,在这个派生类里重载具体的处理OnEvent的函数,并创建所有该窗口上的子控件。

2. 继承GUIApp类,在这个派生类中创建窗口对象,并把窗口对象AddCtrl,在这里可以进行其他的初始化工作

3. 在FrameFunc里调用GUIApp::FrameFunc函数。



总体而言,这个扩展GUI主要是扩展了GUI Manager以及GUI Object,并且加入了Parent-Child机制。比较经典的部分在于提供了一个 OnEvent 函数,这样就可以让客户程序员能够得知窗体上的控件发生的事件。 ----其实这种方法的目的就跟Windows中的消息机制,Qt中的signal/slot机制一样。

VC6.0中如何改变对话框的背景颜色

黄基前(广西桂林)---- 笔者曾在《软件报》2000年第5期中讨论过如何改变控件的颜色,但还有相当一部分的读者来信提问:一个基于对话框的MFC AppWizard应用程序中,如何改变对话框的背景颜色...
  • nm
  • nm
  • 2000-08-16 10:26:00
  • 3351

HGE系列之七 管中窥豹(图形界面)

    HGE系列之七管中窥豹(图形界面)   这次的HGE源码之旅,让我们来看看HGE的图形用户界面(GUI)的实现,话说电脑技术发展至今,当年轰动一时的图形用户界面,而今早已司空见惯,想来不得不感...
  • tkokof1
  • tkokof1
  • 2010-08-31 07:22:00
  • 3859

hge模仿传奇游戏的源码

  • 2011年12月29日 10:12
  • 41.15MB
  • 下载

hgeGUI组件扩展基本步骤

  • yahreso
  • yahreso
  • 2009-08-31 20:31:00
  • 634

Hge游戏引擎超详细教程.rar

  • 2013年03月21日 15:48
  • 13.06MB
  • 下载

2D游戏引擎HGE例子程序和参考文档

  • 2012年11月12日 17:08
  • 31.8MB
  • 下载

HGE引擎结合设计模式写的一个小游戏

  • 2010年03月20日 23:00
  • 5.45MB
  • 下载

HGE系列之十 管中窥豹(游戏字体)

HGE系列之十 管中窥豹(游戏字体)对于一款游戏引擎来说,支持显示字体自然是必备的功能,HGE内建的字体功能虽然仅支持一般的位图字体,但是也算是简洁明了,这次的HGE源码之旅就让我们来看一看他的各中实...
  • tkokof1
  • tkokof1
  • 2011-03-13 19:45:00
  • 2607

hge养成类游戏《见习小恶魔威力加强版》源代码

   这是我用hge写的一个小游戏,现在放出源代码。这游戏是我以前在xp下写的,貌似该游戏在vista下会出现各种奇怪的现象……orz 注意:编译该代码需要自行前往hge官网下载hge的sdk,和an...
  • corivSky
  • corivSky
  • 2008-11-25 06:25:00
  • 6350

HGE引擎使用日志

这些日志都是很早前陆续写的,拿出来分享经验:2006-8-15       7:30开始学习HGE引擎。       从以前的接触中知道,HGE引擎基于DX8。       创建HGE最简单程序的步骤...
  • wenzhoufeng22
  • wenzhoufeng22
  • 2008-04-25 10:01:00
  • 8700
收藏助手
不良信息举报
您举报文章:HGE中的游戏GUI代码阅读
举报原因:
原因补充:

(最多只允许输入30个字)