现在的位置: 首页 > 综合 > 正文

HGE系列之五 管中窥豹(基础类别)

2013年10月03日 ⁄ 综合 ⁄ 共 6158字 ⁄ 字号 评论关闭

 

    HGE系列之五 管中窥豹(基础类别)

 

  继上次我们编写了那个小程序之后,想必大家对于HGE的认识都有了进一步的提高,那么现在,我想则是时候来一番“管中窥豹”,睹一睹HGE的源码实现了 :)而相应的源码文件位于一下两个文件夹下:hge/hge181/include 和 hge/hge181/src

 

一. HGE的主要程序结构 

 

  还记的之前我们见过的一张HGE结构示意图吗?

 

  

 

  

  

  图中的HGE Helper Classes 和 HGE Core Functions基本就构成了HGE的骨架,只是上图并没有涉及过多细节,更详细的类别内容自然需要参照HGE源码了:)

 

  虽说我们这次的目的是研习HGE的源码,但这次我们也大可不必一口气将他们全部看遍,捡出其中较为简略的几个看看我想便以足矣,毕竟是刚刚开始了解HGE源码,我们大可不必操之过急,一步一步的前进,相信终有学有所成的一天,如果过于急躁,反倒是会适得其反,常言道:“欲速则不达”嘛:)

  好了,不多赘言,让我们先来瞅一瞅HGE中几个比较基础的类别,我将它们皆归为base,意为起基本的支撑作用、为其他类别提供服务的一些类别,由于HGE是一款2D引擎,其base类别也相对简易,以此开始我们的代码之旅我想还是颇为恰当的:

  

  类名:hgeRect 

  功能:矩形类,顾名思义,代表的是一个矩形

  头文件hge/hge181/include/hgerect.h

  实现文件:hge/hge181/src/helpers/hgerect.cpp

  

  头文件如下所列:

  

class hgeRect

{

public:

 // 代表矩形的左上角以及右下角坐标,设置为public权限以方便访问

    float x1, y1, x2, y2;

    // 相对直观的构造函数,注意一下bClean这个变量

 hgeRect(float _x1, float _y1, float _x2, float _y2) {x1=_x1; y1=_y1; x2=_x2; y2=_y2; bClean=false; }

 hgeRect() {bClean=true;}

    

    // 将矩形坐标内容“清空”

 void    Clear() {bClean=true;}

    // 查询是否“清空”

 bool    IsClean() const {return bClean;}

    // 设置矩形的坐标

 void Set(float _x1, float _y1, float _x2, float _y2) { x1=_x1; x2=_x2; y1=_y1; y2=_y2; bClean=false; }

    // 根据所给圆的圆心坐标及半径,设置矩形坐标

 void SetRadius(float x, float y, float r) { x1=x-r; x2=x+r; y1=y-r; y2=y+r; bClean=false; }

    // 根据所给坐标“裁剪”矩形

 void Encapsulate(float x, float y);

    // 测试所给坐标是否位于矩形内

 bool TestPoint(float x, float y) const;

    // 测试两个矩形是否相交

 bool Intersect(const hgeRect *rect) const;

 

private:

 bool bClean;

};

  

  代码还是相当清晰的,相信大家根据注释已然了解了十之八九,其中值得一提,一是矩形类中设置的一个不怎么直观的bClean布尔值,其目的其实相当直观,无非是为了支持快速的清空设置和查找,是一种比较普遍的“空间”换“时间”的做法;二则是Intersect这个成员函数的实现方法:

 

bool hgeRect::Intersect(const hgeRect *rect) const

{

 if(fabs(x1 + x2 - rect->x1 - rect->x2) < (x2 - x1 + rect->x2 - rect->x1))

  if(fabs(y1 + y2 - rect->y1 - rect->y2) < (y2 - y1 + rect->y2 - rect->y1))

   return true;

 

 return false;

}

 

  黑体加粗的两个if语句便是该函数的核心逻辑,可能一眼看去并不直观,但只要动手画张示意图,基本便可解其含义,而fabs函数的存在,自然是为了避免出现负数的情况,因为无论两个矩形想减次序为何,光就数值大小来言都是正确的,只是相差一个正负号而已:)

 

  

  ( 注:就X轴来说,两个矩形相交的充要条件即是:

      abs( x1' - x1 + x2' - x2 )  <  x2 -x1 + x2' - x1' ,Y轴情况类似 

 

类名:hgeColorRGB&hgeColorHSV 

功能:色彩类,代表一种颜色

头文件hge/hge181/include/hgecolor.h

实现文件:无

 

首先,hgecolor.h文件全局定义了一个内联函数,用于裁剪颜色值至 0.0~1.0 范围:

 

inline void ColorClamp(float &x) { if(x<0.0f) x=0.0f; if(x>1.0f) x=1.0f; }

 

代码相对简易,两个条件判断而已,故而使用内联,以消除调用该函数的开销。

 

接着是hgeRGB的定义:

 

class hgeColorRGB

{

public:

    // 代表Red、Green、Blue及Alpha值,定义为public属性以方便存取

 float  r,g,b,a;

    

    // 相对直观的构造函数,分别传递四个相应的颜色值参数

 hgeColorRGB(float _r, float _g, float _b, float _a) { r=_r; g=_g; b=_b; a=_a; }

    // 直接使用一个DWORD值来构造

 hgeColorRGB(DWORD col) { SetHWColor(col); }

    // 缺省构造函数,四个参数皆赋值为零

 hgeColorRGB() { r=g=b=a=0; }

    

    // 自定义 减法 操作符,以支持 hgeColorRGB - hgeColorRGB 类型操作

 hgeColorRGB  operator-  (const hgeColorRGB &c) const { return hgeColorRGB(r-c.r, g-c.g, b-c.b, a-c.a); }

    // 自定义 加法 操作符,以支持 hgeColorRGB + hgeColorRGB 类型操作

 hgeColorRGB  operator+  (const hgeColorRGB &c) const { return hgeColorRGB(r+c.r, g+c.g, b+c.b, a+c.a); }

    // 自定义 乘法 操作符,以支持 hgeColorRGB * hgeColorRGB 类型操作

 hgeColorRGB  operator*  (const hgeColorRGB &c) const { return hgeColorRGB(r*c.r, g*c.g, b*c.b, a*c.a); }

    // 自定义 自减 操作符,以支持 hgeColorRGB -= hgeColorRGB 类型操作

 hgeColorRGB& operator-= (const hgeColorRGB &c)  { r-=c.r; g-=c.g; b-=c.b; a-=c.a; return *this;   }

    // 自定义 自加 操作符,以支持 hgeColorRGB += hgeColorRGB 类型操作

 hgeColorRGB& operator+= (const hgeColorRGB &c)  { r+=c.r; g+=c.g; b+=c.b; a+=c.a; return *this;   }

    // 自定义 等号 操作符,以支持 hgeColorRGB == hgeColorRGB 类型操作

 bool   operator== (const hgeColorRGB &c) const { return (r==c.r && g==c.g && b==c.b && a==c.a);  }

    // 自定义 不等号 操作符,以支持 hgeColorRGB != hgeColorRGB 类型操作

 bool   operator!= (const hgeColorRGB &c) const { return (r!=c.r || g!=c.g || b!=c.b || a!=c.a);  }

    // 自定义 除法 操作符,以支持 hgeColorRGB / scalar 类型操作

 hgeColorRGB  operator/  (const float scalar) const { return hgeColorRGB(r/scalar, g/scalar, b/scalar, a/scalar); }

    // 自定义 乘法 操作符,以支持 hgeColorRGB * scalar 类型操作

 hgeColorRGB  operator*  (const float scalar) const { return hgeColorRGB(r*scalar, g*scalar, b*scalar, a*scalar); }

    // 自定义 自乘 操作符,以支持 hgeColorRGB *= scalar 类型操作

 hgeColorRGB& operator*= (const float scalar)    { r*=scalar; g*=scalar; b*=scalar; a*=scalar; return *this;   }

    // 裁剪函数

 void   Clamp() { ColorClamp(r); ColorClamp(g); ColorClamp(b); ColorClamp(a); }

    // 设置硬件颜色值(0.0~1.0范围),参数是一个DWORD,注意移位操作的使用

 void   SetHWColor(DWORD col) { a = (col>>24)/255.0f; r = ((col>>16) & 0xFF)/255.0f; g = ((col>>8) & 0xFF)/255.0f; b = (col & 0xFF)/255.0f; }

    // 取得硬件颜色值,返回值是一个DWORD,注意移位操作的使用

 DWORD   GetHWColor() const { return (DWORD(a*255.0f)<<24) + (DWORD(r*255.0f)<<16) + (DWORD(g*255.0f)<<8) + DWORD(b*255.0f); }

};

 

// 全局定义的一个 乘法 操作符,以支持 sc * hgeColor 类型操作

inline hgeColorRGB operator* (const float sc, const hgeColorRGB &c) { return c*sc; }

 

至此hgeColor就已解析完毕,是不是非常简单 :)相应的hgeColorHSV的代码与hgeColorRGB大同小异,只不过换了一种颜色系(HSV)表示,有兴趣的朋友可以在相应源码文件中查看,在此我就不重复了(秉承DRY原则 :))

 

另外值得提到的一点是,hge文档中所谓的hgeColor实际上只是一个别名(alias)类:

 

#define hgeColor hgeColorRGB

 

不过个人感觉既然是定义类型,那么使用 typedef 更为妥当...

 

类名:hgeStringTable

功能:字符串表,应用于HGE的资源管理中的一个base类别

头文件hge/hge181/include/hgestrings.h

实现文件:hge/hge181/src/helpers/hgestrings.cpp

 

  首先来看一个定义在文件开头的结构(struct)定义:

 

struct NamedString

{

 char   name[MAXSTRNAMELENGTH];

 char   *string;

 NamedString  *next;

};

 

  很简洁,其中的MAXSTRNAMELENGTH是一个预定义宏:

 

#define MAXSTRNAMELENGTH 64

 

  所以由此来看,name这个结构成员仅仅是个普通字符数组罢了~~~大抵的作用想必也是用来存储字符而已...

  而结构中*next这个自向指针的定义,让人不禁想起单链表的节点定义,如果你也是这么想的话,那么恭喜你,这是正确的直觉!这个名为NamedString的结构就是用来构成链表的!:)

  那么char *string这个成员变量又是用来干什么的呢?在此我们好像还不能妄下定义,但是不用着急,我们再耐心的往下看:

 

class hgeStringTable

{

public:

    // 构造函数,从filename文件中解析字符串

 hgeStringTable(const char *filename);

 ~hgeStringTable();

    // 获取名为name的字符串

 char   *GetString(const char *name);

 

private:

    // 私有定义的拷贝构造函数,禁止拷贝构造

 hgeStringTable(const hgeStringTable &);

    // 私有的自定义 赋值 函数,禁止赋值操作

 hgeStringTable& operator= (const hgeStringTable &);

    //  NamedString指针,可以认为是一个单链表头结点 :)

 NamedString  *strings;

    // 静态HGE指针变量,用于调用HGE提供的资源加载操作

 static HGE  *hge;

};

 

  先让我们看看较为简单的 ~hgeStringTable 和 GetString :

 

hgeStringTable::~hgeStringTable()

{

 NamedString *str, *strnext;

    // 将当前头结点付给str

 str=strings;

    // 当 str 不为空(NULL)

 while(str)

 {

        // 获取str的下一个指向节点

  strnext=str->next;

抱歉!评论已关闭.