HGE tutorial6 - GUI _Project_SH

 

6월 13일 스터디 주제

 

1. GUI

1.1 HGE tutorial 06 - Creating Menus

- 기본 튜토리얼 코드 작성

- hgeGUI 및 hgeGUIObject class 의 사용

 

1.2 외부 UI 라이브러리

- guichan 라이브러리와 CEGUI 라이브러리

- 외부 라이브러리 환경 셋팅

 

=========================================================================================================

  • hgeGUI
    • 유저인터페이스를 만들 수 있게 도와주는 헬퍼클래스
  • hgeGUIObject
    • custom GUI 컨트롤들을 사용할 수 있게 도와주는 추상클래스
    • Default classes : hgeGUIText, hgeGUIButton, hgeGUISlider

# main.cpp

// Copy the files "menu.wav", "font1.fnt", "font1.png",
// "bg.png" and "cursor.png" from the folder "precompiled"
// to the folder with executable file. Also copy hge.dll
// and bass.dll to the same folder.


#include <hge.h>
#include <hgefont.h>
#include <hgegui.h>

#include "menuitem.h"

#include <math.h>


// Pointer to the HGE interface.
// Helper classes require this to work.
HGE *hge=0;

// Some resource handles
HEFFECT                snd;
HTEXTURE            tex;
hgeQuad                quad;

// Pointers to the HGE objects we will use
hgeGUI                *gui;
hgeFont                *fnt;
hgeSprite            *spr;


bool FrameFunc()
{
    float dt=hge->Timer_GetDelta();
    static float t=0.0f;
    float tx,ty;
    int id;
    static int lastid=0;

    // If ESCAPE was pressed, tell the GUI to finish
    if(hge->Input_GetKeyState(HGEK_ESCAPE)) { lastid=5; gui->Leave(); }
    
    // We update the GUI and take an action if
    // one of the menu items was selected
    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(); }

    // Here we update our background animation
    t+=dt;
    tx=50*cosf(t/60);
    ty=50*sinf(t/60);

    quad.v[0].tx=tx;        quad.v[0].ty=ty;
    quad.v[1].tx=tx+800/64; quad.v[1].ty=ty;
    quad.v[2].tx=tx+800/64; quad.v[2].ty=ty+600/64;
    quad.v[3].tx=tx;        quad.v[3].ty=ty+600/64;

    return false;
}


bool RenderFunc()
{
    // Render graphics
    hge->Gfx_BeginScene();
    hge->Gfx_RenderQuad(&quad);
    gui->Render();
    fnt->SetColor(0xFFFFFFFF);
    fnt->printf(5, 5, HGETEXT_LEFT, "dt:%.3f\nFPS:%d", hge->Timer_GetDelta(), hge->Timer_GetFPS());
    hge->Gfx_EndScene();

    return false;
}


int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    hge = hgeCreate(HGE_VERSION);

    hge->System_SetState(HGE_LOGFILE, "hge_tut06.log");
    hge->System_SetState(HGE_FRAMEFUNC, FrameFunc);
    hge->System_SetState(HGE_RENDERFUNC, RenderFunc);
    hge->System_SetState(HGE_TITLE, "HGE Tutorial 06 - Creating menus");
    hge->System_SetState(HGE_WINDOWED, true);
    hge->System_SetState(HGE_SCREENWIDTH, 800);
    hge->System_SetState(HGE_SCREENHEIGHT, 600);
    hge->System_SetState(HGE_SCREENBPP, 32);

    if(hge->System_Initiate())
    {

        // Load sound and textures
        quad.tex=hge->Texture_Load("bg.png");
        tex=hge->Texture_Load("cursor.png");
        snd=hge->Effect_Load("menu.wav");
        if(!quad.tex || !tex || !snd)
        {
            // If one of the data files is not found, display
            // an error message and shutdown.
            MessageBox(NULL, "Can't load BG.PNG, CURSOR.PNG or MENU.WAV", "Error", MB_OK | MB_ICONERROR | MB_APPLMODAL);
            hge->System_Shutdown();
            hge->Release();
            return 0;
        }

        // Set up the quad we will use for background animation
        quad.blend=BLEND_ALPHABLEND | BLEND_COLORMUL | BLEND_NOZWRITE;

        for(int i=0;i<4;i++)
        {
            // Set up z-coordinate of vertices
            quad.v[i].z=0.5f;
            // Set up color. The format of DWORD col is 0xAARRGGBB
            quad.v[i].col=0xFFFFFFFF;
        }

        quad.v[0].x=0; quad.v[0].y=0; 
        quad.v[1].x=800; quad.v[1].y=0; 
        quad.v[2].x=800; quad.v[2].y=600; 
        quad.v[3].x=0; quad.v[3].y=600; 


        // Load the font, create the cursor sprite
        fnt=new hgeFont("font1.fnt");
        spr=new hgeSprite(tex,0,0,32,32);

        // Create and initialize the 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->SetNavMode(HGEGUI_UPDOWN | HGEGUI_CYCLED);
        gui->SetCursor(spr);
        gui->SetFocus(1);
        gui->Enter();

        // Let's rock now!
        hge->System_Start();

        // Delete created objects and free loaded resources
        delete gui;
        delete fnt;
        delete spr;
        hge->Effect_Free(snd);
        hge->Texture_Free(tex);
        hge->Texture_Free(quad.tex);
    }

    // Clean up and shutdown
    hge->System_Shutdown();
    hge->Release();
    return 0;
}


# menuitem.cpp

// In menuitem.cpp/h we define the
// behaviour of our custom GUI control

#include "menuitem.h"

// This is a GUI control constructor,
// we should initialize all the variables here
hgeGUIMenuItem::hgeGUIMenuItem(int _id, hgeFont *_fnt, HEFFECT _snd, float _x, float _y, float _delay, char *_title)
{
    float w;
    
    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;

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

// This method is called when the control should be rendered
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);
}

// This method is called each frame,
// we should update the animation here
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;
        }
    }
}

// This method is called when the GUI
// is about to appear on the screen
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;
}

// This method is called when the GUI
// is about to disappear from the screen
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;
}

// This method is called to test whether the control
// have finished it's Enter/Leave animation
bool hgeGUIMenuItem::IsDone()
{
    if(timer2==-1.0f) return true;
    else return false;
}

// This method is called when the control
// receives or loses keyboard input 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;
}

// This method is called to notify the control
// that the mouse cursor has entered or left it's area
void hgeGUIMenuItem::MouseOver(bool bOver)
{
    if(bOver) gui->SetFocus(id);
}

// This method is called to notify the control
// that the left mouse button state has changed.
// If it returns true - the caller will receive
// the control's ID
bool hgeGUIMenuItem::MouseLButton(bool bDown)
{
    if(!bDown)
    {
        offset=4;
        return true;
    }
    else 
    {
        hge->Effect_Play(snd);
        offset=0;
        return false;
    }
}

// This method is called to notify the
// control that a key has been clicked.
// If it returns true - the caller will
// receive the control's ID
bool hgeGUIMenuItem::KeyClick(int key, int chr)
{
    if(key==HGEK_ENTER || key==HGEK_SPACE)
    {
        MouseLButton(true);
        return MouseLButton(false);
    }

    return false;
}


# menuitem.h

 
#include <hge.h>
#include <hgegui.h>
#include <hgefont.h>
#include <hgecolor.h>


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, sshadow, dshadow;
    hgeColor    color, shadow;
    float        soffset, doffset, offset;
    float        timer, timer2;
};


  • guichan 라이브러리 환경설정
    • guichan 파일 다운
    • 압축푼 후 컴파일
      • guichan.lib, guichan_widget.lib, guichan_hge.lib 생성
    • 예제파일 테스트
      • hge.hpp, widgets.hpp, hgewidgets.cpp

K-37.jpg 

Share
이 글과 관련된 글
  1. [2010/05/26] [HGE] 설치방법 by Kaiserin李 (1053)
  2. [2010/05/26] [HGE] 2D 게임엔진 - HGE by Kaiserin李 (1375)
TAG

Leave Comments


profileThings don't always turn out that way_ 

Recent Post

Recent Trackback


T-NAVI