1 /*
2 ** Haaf's Game Engine 1.7
3 ** Copyright (C) 2003-2007, Relish Games
4 ** hge.relishgames.com
5 **
6 ** Tutorial 06 - Creating menus
7 */
8
9 // 文件名:menuitem.h,自定义控件类的声明
10
11 #include <hge.h>
12 #include <hgegui.h>
13 #include <hgefont.h>
14 #include <hgecolor.h>
15 #pragma comment(lib,"hge.lib")
16 #pragma comment(lib,"hgehelp.lib")
17
18 //这个类继承自HGE的hgeGUIObject类
19 //用于实现自定义的控件,本例中实现的实际上是按钮控件
20 class hgeGUIMenuItem : public hgeGUIObject
21 {
22 public:
23 hgeGUIMenuItem(int id, hgeFont *fnt, HEFFECT snd, float x, float y, float delay, char *title);
24
25 virtual void Render();
26 virtual void Update(float dt);
27
28 virtual void Enter();
29 virtual void Leave();
30 virtual bool IsDone();
31 virtual void Focus(bool bFocused);
32 virtual void MouseOver(bool bOver);
33
34 virtual bool MouseLButton(bool bDown);
35 virtual bool KeyClick(int key, int chr);
36
37 private:
38 hgeFont *fnt;
39 HEFFECT snd;
40 float delay;
41 char *title;
42
43 hgeColor scolor, dcolor, scolor2, dcolor2, sshadow, dshadow;
44 hgeColor color, shadow;
45 float soffset, doffset, offset;
46 float timer, timer2;
47 };
1 /*
2 ** Haaf's Game Engine 1.7
3 ** Copyright (C) 2003-2007, Relish Games
4 ** hge.relishgames.com
5 **
6 ** Tutorial 06 - Creating menus
7 */
8
9 // 文件名:menuitem.cpp,自定义空间类的实现
10
11 #include "menuitem.h"
12
13 // 这个函数是GUI控件构造器,
14 // 在这个函数中初始化所有的变量
15 hgeGUIMenuItem::hgeGUIMenuItem(int _id, hgeFont *_fnt, HEFFECT _snd, float _x, float _y, float _delay, char *_title)
16 {
17 float w;
18
19 id=_id;
20 fnt=_fnt;
21 snd=_snd;
22 delay=_delay;
23 title=_title;
24
25 color.SetHWColor(0xFFFFE060);
26 shadow.SetHWColor(0x30000000);
27 offset=0.0f;
28 timer=-1.0f;
29 timer2=-1.0f;
30
31 bStatic=false;
32 bVisible=true;
33 bEnabled=true;
34
35 w=fnt->GetStringWidth(title);
36 rect.Set(_x-w/2, _y, _x+w/2, _y+fnt->GetHeight());
37 }
38
39 // 这个函数在控件需要被绘制的时候调用
40 // 由于是按钮控件,所以仅仅绘制了按钮的文本而已
41 void hgeGUIMenuItem::Render()
42 {
43 fnt->SetColor(shadow.GetHWColor());
44 fnt->Render(rect.x1+offset+3, rect.y1+3, HGETEXT_LEFT, title);
45 fnt->SetColor(color.GetHWColor());
46 fnt->Render(rect.x1-offset, rect.y1-offset, HGETEXT_LEFT, title);
47 }
48
49 // 这个函数每帧都被调用一次(在Render函数之前),
50 // 在这个函数中更新控件的动画效果
51 void hgeGUIMenuItem::Update(float dt)
52 {
53 if(timer2 != -1.0f)
54 {
55 timer2+=dt;
56 if(timer2 >= delay+0.1f)
57 {
58 color=scolor2+dcolor2;
59 shadow=sshadow+dshadow;
60 offset=0.0f;
61 timer2=-1.0f;
62 }
63 else
64 {
65 if(timer2 < delay) { color=scolor2; shadow=sshadow; }
66 else { color=scolor2+dcolor2*(timer2-delay)*10; shadow=sshadow+dshadow*(timer2-delay)*10; }
67 }
68 }
69 else if(timer != -1.0f)
70 {
71 timer+=dt;
72 if(timer >= 0.2f)
73 {
74 color=scolor+dcolor;
75 offset=soffset+doffset;
76 timer=-1.0f;
77 }
78 else
79 {
80 color=scolor+dcolor*timer*5;
81 offset=soffset+doffset*timer*5;
82 }
83 }
84 }
85
86 // 这个函数在控件显示在屏幕上的时候被调用
87 void hgeGUIMenuItem::Enter()
88 {
89 hgeColor tcolor2;
90
91 scolor2.SetHWColor(0x00FFE060);
92 tcolor2.SetHWColor(0xFFFFE060);
93 dcolor2=tcolor2-scolor2;
94
95 sshadow.SetHWColor(0x00000000);
96 tcolor2.SetHWColor(0x30000000);
97 dshadow=tcolor2-sshadow;
98
99 timer2=0.0f;
100 }
101
102 // 这个函数在控件从屏幕上移除的时候被调用
103 void hgeGUIMenuItem::Leave()
104 {
105 hgeColor tcolor2;
106
107 scolor2.SetHWColor(0xFFFFE060);
108 tcolor2.SetHWColor(0x00FFE060);
109 dcolor2=tcolor2-scolor2;
110
111 sshadow.SetHWColor(0x30000000);
112 tcolor2.SetHWColor(0x00000000);
113 dshadow=tcolor2-sshadow;
114
115 timer2=0.0f;
116 }
117
118 // 这个函数用于测试控件是否完成一次出现和移除的动作
119 bool hgeGUIMenuItem::IsDone()
120 {
121 if(timer2==-1.0f) return true;
122 else return false;
123 }
124
125 // 这个函数在控件得到和失去键盘输入焦点的时候被调用
126 void hgeGUIMenuItem::Focus(bool bFocused)
127 {
128 hgeColor tcolor;
129
130 if(bFocused)
131 {
132 hge->Effect_Play(snd);
133 scolor.SetHWColor(0xFFFFE060);
134 tcolor.SetHWColor(0xFFFFFFFF);
135 soffset=0;
136 doffset=4;
137 }
138 else
139 {
140 scolor.SetHWColor(0xFFFFFFFF);
141 tcolor.SetHWColor(0xFFFFE060);
142 soffset=4;
143 doffset=-4;
144 }
145
146 dcolor=tcolor-scolor;
147 timer=0.0f;
148 }
149
150 // 这个函数在鼠标移动到控件上的时候被调用
151 // 此处仅仅当鼠标移到控件上的时候设置焦点到当前控件上
152 void hgeGUIMenuItem::MouseOver(bool bOver)
153 {
154 if(bOver) gui->SetFocus(id);
155 }
156
157 // 这个函数在鼠标左键按下或者弹起的时候被调用
158 // 参数bDown为true表示按下,为false表示弹起
159 // 如果返回true,那么调用者将得到控件的ID
160 // 此处设置为当按钮按下的时候播放音效,并返回false,否则返回true
161 bool hgeGUIMenuItem::MouseLButton(bool bDown)
162 {
163 if(!bDown)
164 {
165 offset=4;
166 return true;
167 }
168 else
169 {
170 hge->Effect_Play(snd);
171 offset=0;
172 return false;
173 }
174 }
175
176 // 这个函数在一个按键被单击的时候被调用
177 // 如果返回true,那么调用者将得到控件的ID
178 // 这里设置为当按下ENTER键和SPACE键的时候也当做按下了左键
179 bool hgeGUIMenuItem::KeyClick(int key, int chr)
180 {
181 if(key==HGEK_ENTER || key==HGEK_SPACE)
182 {
183 MouseLButton(true);
184 return MouseLButton(false);
185 }
186
187 return false;
188 }
1 /*
2 ** Haaf's Game Engine 1.8
3 ** Copyright (C) 2003-2007, Relish Games
4 ** hge.relishgames.com
5 **
6 ** hge_tut06 - Creating menus
7 */
8
9
10 // 复制"menu.wav","font1.fnt","font1.png","bg.png","cursor.png"
11
12 #include "menuitem.h"
13 #include <math.h>
14
15
16
17 HGE *hge=0;
18
19
20 HEFFECT snd;
21 HTEXTURE tex;
22 hgeQuad quad;
23
24 //一些HGE对象
25 hgeGUI *gui;
26 hgeFont *fnt;
27 hgeSprite *spr;
28
29
30 bool FrameFunc()
31 {
32 float dt=hge->Timer_GetDelta();
33 static float t=0.0f;
34 float tx,ty;
35 int id;
36 static int lastid=0;
37
38 // 按下ESC键就退出
39 if(hge->Input_GetKeyState(HGEK_ESCAPE)) { lastid=5; gui->Leave(); }
40
41 // 如果一个按钮被选择,我们就更新GUI
42 id=gui->Update(dt);
43 if(id == -1)
44 {
45 switch(lastid)
46 {
47 case 1:
48 case 2:
49 case 3:
50 case 4:
51 gui->SetFocus(1);
52 gui->Enter();
53 break;
54
55 case 5: return true;
56 }
57 }
58 else if(id) { lastid=id; gui->Leave(); }
59
60 // 这里更新背景动画
61 t+=dt;
62 tx=50*cosf(t/60);
63 ty=50*sinf(t/60);
64
65 quad.v[0].tx=tx; quad.v[0].ty=ty;
66 quad.v[1].tx=tx+800/64; quad.v[1].ty=ty;
67 quad.v[2].tx=tx+800/64; quad.v[2].ty=ty+600/64;
68 quad.v[3].tx=tx; quad.v[3].ty=ty+600/64;
69
70 return false;
71 }
72
73
74 bool RenderFunc()
75 {
76 // 绘制图像
77 hge->Gfx_BeginScene();
78 hge->Gfx_RenderQuad(&quad);
79 gui->Render();
80 fnt->SetColor(0xFFFFFFFF);
81 fnt->printf(5, 5, HGETEXT_LEFT, "dt:%.3f\nFPS:%d", hge->Timer_GetDelta(), hge->Timer_GetFPS());
82 hge->Gfx_EndScene();
83
84 return false;
85 }
86
87
88 int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
89 {
90 hge = hgeCreate(HGE_VERSION);
91
92 hge->System_SetState(HGE_LOGFILE, "hge_tut06.log");
93 hge->System_SetState(HGE_FRAMEFUNC, FrameFunc);
94 hge->System_SetState(HGE_RENDERFUNC, RenderFunc);
95 hge->System_SetState(HGE_TITLE, "HGE Tutorial 06 - Creating menus");
96 hge->System_SetState(HGE_WINDOWED, true);
97 hge->System_SetState(HGE_SCREENWIDTH, 800);
98 hge->System_SetState(HGE_SCREENHEIGHT, 600);
99 hge->System_SetState(HGE_SCREENBPP, 32);
100
101 if(hge->System_Initiate())
102 {
103
104 // 加载声音和纹理
105 quad.tex=hge->Texture_Load("bg.png");
106 tex=hge->Texture_Load("cursor.png");
107 snd=hge->Effect_Load("menu.wav");
108 if(!quad.tex || !tex || !snd)
109 {
110 MessageBox(NULL, "Can't load BG.PNG, CURSOR.PNG or MENU.WAV", "Error", MB_OK | MB_ICONERROR | MB_APPLMODAL);
111 hge->System_Shutdown();
112 hge->Release();
113 return 0;
114 }
115
116 // 设置四边形(用于绘制窗口的背景)的融合模式
117 quad.blend=BLEND_ALPHABLEND | BLEND_COLORMUL | BLEND_NOZWRITE;
118
119 for(int i=0;i<4;i++)
120 {
121 // 设置顶点Z序
122 quad.v[i].z=0.5f;
123 // 设置颜色,格式为0xAARRGGBB,各种中的最前面两个AA表示透明度
124 quad.v[i].col=0xFFFFFFFF;
125 }
126
127 quad.v[0].x=0; quad.v[0].y=0;
128 quad.v[1].x=800; quad.v[1].y=0;
129 quad.v[2].x=800; quad.v[2].y=600;
130 quad.v[3].x=0; quad.v[3].y=600;
131
132
133 // 加载字体,创建鼠标的精灵
134 fnt=new hgeFont("font1.fnt");
135 spr=new hgeSprite(tex,0,0,32,32);
136
137 // 创建并初始化GUI
138 gui=new hgeGUI();
139
140 gui->AddCtrl(new hgeGUIMenuItem(1,fnt,snd,400,200,0.0f,"Play"));
141 gui->AddCtrl(new hgeGUIMenuItem(2,fnt,snd,400,240,0.1f,"Options"));
142 gui->AddCtrl(new hgeGUIMenuItem(3,fnt,snd,400,280,0.2f,"Instructions"));
143 gui->AddCtrl(new hgeGUIMenuItem(4,fnt,snd,400,320,0.3f,"Credits"));
144 gui->AddCtrl(new hgeGUIMenuItem(5,fnt,snd,400,360,0.4f,"Exit"));
145
146 gui->SetNavMode(HGEGUI_UPDOWN | HGEGUI_CYCLED);
147 gui->SetCursor(spr);
148 gui->SetFocus(1);
149 gui->Enter();
150
151 hge->System_Start();
152
153 //此处是要删除gui即可,这个类的析构函数会自动删除添加进的控件.
154 delete gui;
155 delete fnt;
156 delete spr;
157 hge->Effect_Free(snd);
158 hge->Texture_Free(tex);
159 hge->Texture_Free(quad.tex);
160 }
161
162 hge->System_Shutdown();
163 hge->Release();
164 return 0;
165 }