1 /*
2 ** Haaf's Game Engine 1.8
3 ** Copyright (C) 2003-2007, Relish Games
4 ** hge.relishgames.com
5 **
6 ** hge_tut02 - Using input, sound and rendering
7 */
8
9
10 // 请从 "precompiled"文件夹下复制"particles.png"和"menu.wav"
11 // 到程序文件夹下.当然hge.dll和bass.dll也是需要复制的.
12
13 #include <hge.h>
14 #pragma comment(lib,"hge.lib")
15 HGE *hge=0;
16
17 // 四边形是HGE中用于渲染的基本元素(图元)
18 // 四边形有四个顶点,按顺时针方向分别标记为0,1,2,3
19 hgeQuad quad;
20
21 // 音效句柄
22 HEFFECT snd;
23
24 // 一些和程序运行有关的变量和常量
25 float x=100.0f, y=100.0f;
26 float dx=0.0f, dy=0.0f;
27
28 const float speed=90;
29 const float friction=0.98f;
30
31 // 这个函数根据图元位置和速度播放音效
32 void boom()
33 {
34 int pan=int((x-400)/4);
35 float pitch=(dx*dx+dy*dy)*0.0005f+0.2f;
36 hge->Effect_PlayEx(snd,100,pan,pitch);
37 }
38
39 bool FrameFunc()
40 {
41 // 获取上一帧到这一帧的时间.
42 // 用这个时间来计时有利于在不同的机器条件和视频模式下得到同样的结果
43 float dt=hge->Timer_GetDelta();
44
45 // 检查按键
46 if (hge->Input_GetKeyState(HGEK_ESCAPE)) return true;
47 if (hge->Input_GetKeyState(HGEK_LEFT)) dx-=speed*dt;
48 if (hge->Input_GetKeyState(HGEK_RIGHT)) dx+=speed*dt;
49 if (hge->Input_GetKeyState(HGEK_UP)) dy-=speed*dt;
50 if (hge->Input_GetKeyState(HGEK_DOWN)) dy+=speed*dt;
51
52 // 做一些运动计算和碰撞判断
53 dx*=friction; dy*=friction; x+=dx; y+=dy;
54 if(x>784) {x=784-(x-784);dx=-dx;boom();}
55 if(x<16) {x=16+16-x;dx=-dx;boom();}
56 if(y>584) {y=584-(y-584);dy=-dy;boom();}
57 if(y<16) {y=16+16-y;dy=-dy;boom();}
58
59 // 设置图元的屏幕坐标(x,y)
60 quad.v[0].x=x-16; quad.v[0].y=y-16;
61 quad.v[1].x=x+16; quad.v[1].y=y-16;
62 quad.v[2].x=x+16; quad.v[2].y=y+16;
63 quad.v[3].x=x-16; quad.v[3].y=y+16;
64
65 // 继续循环
66 return false;
67 }
68
69 // 这个函数将会在屏幕需要被重绘的时候被HGE引擎调用
70 // 在这里写一些渲染屏幕的代码,这是上一个教程中没有的函数
71 // 因为上一个教程不需要进行渲染工作
72 bool RenderFunc()
73 {
74 // 开始渲染图元.
75 // 这个函数必须在实际渲染之前被调用,
76 // 以初始化渲染环境
77 hge->Gfx_BeginScene();
78
79 // 用黑色填充屏幕
80 // 在渲染之前做这一步的目的在于避免这一次的渲染
81 // 和上一次的渲染的颜色产生重叠
82 hge->Gfx_Clear(0);
83
84 // 渲染图元.
85 // 这一个函数已经足够满足我们现在的需求
86 hge->Gfx_RenderQuad(&quad);
87
88 // 结束渲染以及更新屏幕
89 // 这个函数和Gfx_BeginScene()函数对称出现
90 // 两个函数中间则为实际的渲染代码
91 hge->Gfx_EndScene();
92
93 // 渲染函数总是返回false
94 return false;
95 }
96
97
98 int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
99 {
100 // 获得HGE接口
101 hge = hgeCreate(HGE_VERSION);
102
103 // 设置log文件, 帧函数, 渲染函数以及窗口标题
104 hge->System_SetState(HGE_LOGFILE, "hge_tut02.log");
105 hge->System_SetState(HGE_FRAMEFUNC, FrameFunc);
106 hge->System_SetState(HGE_RENDERFUNC, RenderFunc);
107 hge->System_SetState(HGE_TITLE, "HGE Tutorial 02 - Using input, sound and rendering");
108
109 // 设置视频模式
110 hge->System_SetState(HGE_WINDOWED, true);
111 hge->System_SetState(HGE_SCREENWIDTH, 800);
112 hge->System_SetState(HGE_SCREENHEIGHT, 600);
113 hge->System_SetState(HGE_SCREENBPP, 32);
114
115 if(hge->System_Initiate())
116 {
117 // 加载声音和纹理
118 snd=hge->Effect_Load("menu.wav");
119 quad.tex=hge->Texture_Load("particles.png");
120 if(!snd || !quad.tex)
121 {
122 // 声音和纹理只要有一个没加载成功,
123 // 就显示一个错误消息然后退出程序
124 MessageBox(NULL, "Can't load MENU.WAV or PARTICLES.PNG", "Error", MB_OK | MB_ICONERROR | MB_APPLMODAL);
125 hge->System_Shutdown();
126 hge->Release();
127 return 0;
128 }
129
130 // 设置图元在渲染中的融合特性
131 quad.blend=BLEND_ALPHAADD | BLEND_COLORMUL | BLEND_ZWRITE;
132
133 for(int i=0;i<4;i++)
134 {
135 // 设置顶点的z坐标
136 quad.v[i].z=0.5f;
137 // 设置颜色,颜色值使用X8R8G8B8的格式
138 quad.v[i].col=0xFFFFA000;
139 }
140
141 // 设置图元的纹理坐标(tx,ty),注意和图元的屏幕坐标的区别.
142 // 0.0,0.0 表示纹理左上角,
143 // 1.0,1.0 表示纹理右下角.
144 quad.v[0].tx=96.0/128.0; quad.v[0].ty=64.0/128.0;
145 quad.v[1].tx=128.0/128.0; quad.v[1].ty=64.0/128.0;
146 quad.v[2].tx=128.0/128.0; quad.v[2].ty=96.0/128.0;
147 quad.v[3].tx=96.0/128.0; quad.v[3].ty=96.0/128.0;
148
149 // 会在这里执行循环,上一教程中已经说明了.
150 hge->System_Start();
151
152 // 释放纹理和音效
153 hge->Texture_Free(quad.tex);
154 hge->Effect_Free(snd);
155 }
156 else MessageBox(NULL, hge->System_GetErrorMessage(), "Error", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
157
158 // 最后的清理以及退出
159 hge->System_Shutdown();
160 hge->Release();
161 return 0;
162 }