HGE教程翻译(6)

Tutorial 06 – 创建菜单

 

这个教程显示如何创建通用的GUI控制和菜单。

创建通用控制

首先我们定义控制类,从hgeGUIObject继承:

 

class hgeGUIMenuItem : public hgeGUIObject
    
    
{
    
    
public:
    
    
  hgeGUIMenuItem(int id, hgeFont *fnt, HEFFECT snd,
    
    
          float x, float y, float delay, char *title);
    
    

  
  
   
    
  
  
  virtual void  Render();
    
    
  virtual void  Update(float dt);
    
    

  
  
   
    
  
  
  virtual void  Enter();
    
    
  virtual void  Leave();
    
    
  virtual bool  IsDone();
    
    
  virtual void  Focus(bool bFocused);
    
    
  virtual void  MouseOver(bool bOver);
    
    

  
  
   
    
  
  
  virtual bool  MouseLButton(bool bDown);
    
    
  virtual bool  KeyClick(int key, int chr);
    
    

  
  
   
    
  
  
private:
    
    
  hgeFont       *fnt;
    
    
  HEFFECT       snd;
    
    
  float         delay;
    
    
  char          *title;
    
    

  
  
   
    
  
  
  hgeColor      scolor, dcolor, scolor2, dcolor2, color;
    
    
  hgeColor      sshadow, dshadow, shadow;
    
    
  float         soffset, doffset, offset;
    
    
  float         timer, timer2;
    
    
};
    
    

 

构造函数初始化数据成员id, bStatic, bVisible, bEnabled rect

 

hgeGUIMenuItem::hgeGUIMenuItem(int _id, hgeFont *_fnt,
    
    
                HEFFECT _snd, float _x, float _y,
    
    
                float _delay, char *_title)
    
    
{
    
    
  id=_id;
    
    
  fnt=_fnt;
    
    
  snd=_snd;
    
    
  delay=_delay;
    
    
  title=_title;
    
    

  
  
   
    
  
  
  color.SetHWColor(0xFFFFE060);
    
    
  shadow.SetHWColor(0x30000000);
    
    
  offset=0.0f; timer=-1.0f; timer2=-1.0f;
    
    

  
  
   
    
  
  
  bStatic=false; bVisible=true; bEnabled=true;
    
    

  
  
   
    
  
  
  float w=fnt->GetStringWidth(title);
    
    
  rect.Set(_x-w/2, _y, _x+w/2, _y+fnt->GetHeight());
    
    
}
    
    

 

Render函数是重点,每个控制都要定义它。

 

void hgeGUIMenuItem::Render()
    
    
{
    
    
  fnt->SetColor(shadow.GetHWColor());
    
    
  fnt->Render(rect.x1+offset+3, rect.y1+3, HGETEXT_LEFT, title);
    
    
  fnt->SetColor(color.GetHWColor());
    
    
  fnt->Render(rect.x1-offset, rect.y1-offset, HGETEXT_LEFT, title);
    
    
}
    
    

 

所有其他方法都是可选的,你可以不定义。


Update在每次GUI更新并需要渲染时调用。在这例子中我们有两个定时器根据时间调节颜色和位置,

 

void hgeGUIMenuItem::Update(float dt)
    
    
{
    
    
  if(timer2 != -1.0f)
    
    
  {
    
    
    timer2+=dt;
    
    
    if(timer2 >= delay+0.1f)
    
    
    {
    
    
      color=scolor2+dcolor2;
    
    
      shadow=sshadow+dshadow;
    
    
      offset=0.0f;
    
    
      timer2=-1.0f;
    
    
    }
    
    
    else
    
    
    {
    
    
      if(timer2 < delay) { color=scolor2; shadow=sshadow; }
    
    
      else {
    
    
        color=scolor2+dcolor2*(timer2-delay)*10;
    
    
        shadow=sshadow+dshadow*(timer2-delay)*10;
    
    
      }
    
    
    }
    
    
  }
    
    
  else if(timer != -1.0f)
    
    
  {
    
    
    timer+=dt;
    
    
    if(timer >= 0.2f)
    
    
    {
    
    
      color=scolor+dcolor;
    
    
      offset=soffset+doffset;
    
    
      timer=-1.0f;
    
    
    }
    
    
    else
    
    
    {
    
    
      color=scolor+dcolor*timer*5;
    
    
      offset=soffset+doffset*timer*5;
    
    
    }
    
    
  }
    
    
}
    
    

 

EnterGUI将要出现在屏幕上时调用。一个控制动画应该在这里进入:

 

void hgeGUIMenuItem::Enter()
    
    
{
    
    
  hgeColor tcolor2;
    
    

  
  
   
    
  
  
  scolor2.SetHWColor(0x00FFE060);
    
    
  tcolor2.SetHWColor(0xFFFFE060);
    
    
  dcolor2=tcolor2-scolor2;
    
    

  
  
   
    
  
  
  sshadow.SetHWColor(0x00000000);
    
    
  tcolor2.SetHWColor(0x30000000);
    
    
  dshadow=tcolor2-sshadow;
    
    

  
  
   
    
  
  
  timer2=0.0f;
    
    
}
    
    

 

LeaveGUI要从屏幕消失时调用。

 

void hgeGUIMenuItem::Leave()
    
    
{
    
    
  hgeColor tcolor2;
    
    

  
  
   
    
  
  
  scolor2.SetHWColor(0xFFFFE060);
    
    
  tcolor2.SetHWColor(0x00FFE060);
    
    
  dcolor2=tcolor2-scolor2;
    
    

  
  
   
    
  
  
  sshadow.SetHWColor(0x30000000);
    
    
  tcolor2.SetHWColor(0x00000000);
    
    
  dshadow=tcolor2-sshadow;
    
    

  
  
   
    
  
  
  timer2=0.0f;
    
    
}
    
    

 

IsDone用来检测这个控制是否完成Enter/Leave动画。完成返回true

 

bool hgeGUIMenuItem::IsDone()
    
    
{
    
    
  if(timer2==-1.0f) return true;
    
    
  else return false;
    
    
}
    
    

 

Focus当控制获得或失去键盘输入焦点时调用。

 

void hgeGUIMenuItem::Focus(bool bFocused)
    
    
{
    
    
  hgeColor tcolor;
    
    

  
  
   
    
  
  
  if(bFocused)
    
    
  {
    
    
    hge->Effect_Play(snd);
    
    
    scolor.SetHWColor(0xFFFFE060);
    
    
    tcolor.SetHWColor(0xFFFFFFFF);
    
    
    soffset=0;
    
    
    doffset=4;
    
    
  }
    
    
  else
    
    
  {
    
    
    scolor.SetHWColor(0xFFFFFFFF);
    
    
    tcolor.SetHWColor(0xFFFFE060);
    
    
    soffset=4;
    
    
    doffset=-4;
    
    
  }
    
    

  
  
   
    
  
  
  dcolor=tcolor-scolor;
    
    
  timer=0.0f;
    
    
}
    
    

 

MouseOver用来通知鼠标指针进入或离开它的区域。这里我们只设置输入焦点到控制当鼠标经过它时。

 

void hgeGUIMenuItem::MouseOver(bool bOver)
    
    
{
    
    
  if(bOver) gui->SetFocus(id);
    
    
}
    
    

 

MouseLButton当左键状态改变时调用。如果控制改变它的状态并希望通知调用者,应该返回true

 

bool hgeGUIMenuItem::MouseLButton(bool bDown)
    
    
{
    
    
  if(!bDown)
    
    
  {
    
    
    offset=4;
    
    
    return true;
    
    
  }
    
    
  else 
    
    
  {
    
    
    hge->Effect_Play(snd);
    
    
    offset=0;
    
    
    return false;
    
    
  }
    
    
}
    
    

 

KeyClick用来通知控制一个键被点击。如果控制改变它的状态并希望通知调用者,应返回true

 

bool hgeGUIMenuItem::KeyClick(int key, int chr)
    
    
{
    
    
  if(key==HGEK_ENTER || key==HGEK_SPACE)
    
    
  {
    
    
    MouseLButton(true);
    
    
    return MouseLButton(false);
    
    
  }
    
    

  
  
   
    
  
  
  return false;
    
    
}
    
    

 

现在我们有通用的控制行为定义了。

使用GUI

这里是简单部分。首先我们需要资源变量:

 

HEFFECT    snd;
    
    
HTEXTURE   tex;
    
    

  
  
   
    
  
  
hgeGUI     *gui;
    
    
hgeFont    *fnt;
    
    
hgeSprite  *spr;
    
    

 

WinMain中,在初始化过程中载入资源:

 

  snd=hge->Effect_Load("menu.wav");
    
    
  tex=hge->Texture_Load("cursor.png");
    
    

  
  
   
    
  
  
  fnt=new hgeFont("font1.fnt");
    
    
  spr=new hgeSprite(tex,0,0,32,32);
    
    

 

现在创建GUI并添加菜单部件。GUI控制在内部处理,你不需要关心。

 

  gui=new hgeGUI();
    
    

  
  
   
    
  
  
  gui->AddCtrl(new hgeGUIMenuItem(
    
    
               1,fnt,snd,400,200,0.0f,"Play"));
    
    
  gui->AddCtrl(new hgeGUIMenuItem(
    
    
               2,fnt,snd,400,240,0.1f,"Options"));
    
    
  gui->AddCtrl(new hgeGUIMenuItem(
    
    
               3,fnt,snd,400,280,0.2f,"Instructions"));
    
    
  gui->AddCtrl(new hgeGUIMenuItem(
    
    
               4,fnt,snd,400,320,0.3f,"Credits"));
    
    
  gui->AddCtrl(new hgeGUIMenuItem(
    
    
               5,fnt,snd,400,360,0.4f,"Exit"));
    
    

 

现在我们设置GUI模式,鼠标图象和默认键盘焦点,然后开始进入动画:

 

  gui->SetNavMode(HGEGUI_UPDOWN | HGEGUI_CYCLED);
    
    
  gui->SetCursor(spr);
    
    
  gui->SetFocus(1);
    
    
  gui->Enter();
    
    

 

现在看看我们如何更新菜单和接收通知。在FrameFunc中我们调用hgeGUI::Update来更新状态,它返回控制的鉴定值。如果所有的控制都完成离开动画,它返回-1。如果没有事情发生返回0

 

  int id;
    
    
  static int lastid=0;
    
    
  float dt=hge->Timer_GetDelta();
    
    

  
  
   
    
  
  
  id=gui->Update(dt);
    
    
  if(id == -1)
    
    
  {
    
    
    switch(lastid)
    
    
    {
    
    
      case 1:
    
    
      case 2:
    
    
      case 3:
    
    
      case 4:
    
    
        gui->SetFocus(1);
    
    
        gui->Enter();
    
    
        break;
    
    

  
  
   
    
  
  
      case 5: return true;
    
    
    }
    
    
  }
    
    
  else if(id) { lastid=id; gui->Leave(); }
    
    

 

RenderFunc中调用hgeGUI::Render来渲染菜单:

 

  hge->Gfx_BeginScene();
    
    
  gui->Render();
    
    
  hge->Gfx_EndScene();
    
    

 

菜单出现并运行。现在来到WinMain。程序结束时删除GUI并释放资源。

 

  delete gui;
    
    
  delete fnt;
    
    
  delete spr;
    
    
  hge->Texture_Free(tex);
    
    
  hge->Effect_Free(snd);
    
    
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值