HGE引擎 - 绘制,声音,碰撞处理
原帖地址:http://blog.csdn.net/i_dovelemon/article/details/8818037
另外,年代久远,该引擎官网早已上不去了!!!
1.库的安装和下载
从官网上http://hge.relishgames.com/上可以下载到最新的HGE游戏引擎,此游戏引擎是完全免费开源的。在此感谢此引擎的编写者,感谢他的无私奉献。本教程是入门的教程,可是在此也并不介绍如何配置环境,这些操作网上琳琅满目,读者可自行上网收索
2.HGE实例
#include<hge.h>
#pragma comment(lib,"hge.lib")
Q:为什么要导入这个lib?不是在配置里面添加了吗?
A:由于不可知的原因,在VC6.0中配置时,加入了lib之后,所有其他的函数都可以使用,只有hgeCreate函数总是提示“无法解析的外部符号”。而这个函数是创建HE游戏引擎的函数,可谓是巨头函数,这个函数不能用,那整个程序就Game Over了。所以在用代码导入这个lib之后,就可以使用了。
//定义全局变量
HGE * hge = NULL ;
hgeQuad quad ; //用于保存绘图的顶点,纹理,和混色的函数
Q:hgeQuad结构是什么?
A:查看HEG的官网,上面解释说这个结构是跟绘图有关的结构。如果要绘图,就需要有这个结构存在。以下是这个结构的详细定义:
struct hgeQuad
{
hgeVertex v[4] ;
HTEXTURE tex ;
int blend ;
};
上面结构中的几个成员分别是hgeVertex顶点结构,用于保存顶点的信息;第二个是HTEXTURE结构的数据,此结构是纹理的句柄;blend表示混色模式。
HEFFECT snd ; //保存音效的句柄
float x = 100.0f , y = 100.0f ;
float dx = 0.0f , dy = 0.0f ;
const float speed = 90 ;
const float friction = 0.98f ;
//定义播放音效的函数
void boom()
{
int pan = int((x-400)/4);
float pitch = (dx*dx+dy*dy)*0.0005f + 0.2f ;
hge->Effect_PlayEx(snd,100,pan,pitch); //snd是音频资源的句柄,100表示声音大小,pan表示左右声道,pitch表示播放频率
}
Q:Effect_PlayEx函数是什么用处?
A:Effect_PlayEx函数,用于播放指定的音效文件,同时可以根据后面的几个参数来进行声音,声道,播放频率的改变。
//定义帧回调函数
bool FrameFunc()
{
float dt = hge->Timer_GetDelta(); //获取自上次调用此函数到此次调用此函数的时间间隔
if(hge->Input_GetKeyState(HGEK_ESCAPE))
return true ;
//根据不同的按键,使用速度和延迟时间来修正位置
if(hge->Input_GetKeyState(HGEK_LEFT))
dx-=speed*dt ;
if(hge->Input_GetKeyState(HGEK_RIGHT))
dx+=speed*dt ;
if(hge->Input_GetKeyState(HGEK_UP))
dy-=speed*dt ;
if(hge->Input_GetKeyState(HGEK_DOWN))
dy+=speed*dt ;
//做一些运动的计算
dx*=friction;
dy*=friction;
x+=dx;
y+=dy;
if(x>784)
{
x=784-(x-784);
dx=-dx;
boom();
}
if(x<16)
{
x=16+16-x;
dx=-dx;
boom();
}
if(y>584)
{
y=584-(y-584);
dy=-dy;
boom();
}
if(y<16)
{
y=16+16-y;
dy=-dy;
boom();
}
//配置hgeQuad结构中的顶点
quad.v[0].x=x-16;
quad.v[0].y=y-16;
quad.v[1].x=x+16;
quad.v[1].y=y-16;
quad.v[2].x=x+16;
quad.v[2].y=y+16;
quad.v[3].x=x-16;
quad.v[3].y=y+16;
return false ;
}
Q:什么是帧回调函数?有什么用处?
A:这个帧回调函数是用来表示游戏逻辑的地方,会在后面的代码中设置这个函数被调用的频率,一般以每秒多少次表示。在这个函数中,我们就可以进行游戏逻辑的编写,注意此函数在返回true的情况下,游戏的逻辑将结束,而在返回false的情况下只是代表此次的函数调用结束了,并不是游戏的逻辑结束了(以后不会再被调用,称为逻辑结束)。
Q:这里的计算问题是什么进行计算的?
A:通过分析代码发现了这里的计算是以圆球图案的中心来进行计算的,以全局变量x,y表示圆球图案中心的坐标。然后使用dx,和dy表示在一次帧回调函数调用中,圆球图案中心移动的距离。当明白了这点之后,剩下的计算部分就比较简单了。以dx,dy表示圆球中心坐标的改变,正的代表向右或下进行移动,负的代表向左和右进行移动。dt表示离上次调用的时间间隔,根据设置的FPS值,计算出这个值应该是1/100=0.01秒,调试发现dt值确实等于这个。而在我们按下了一个或者多个按键的时候,就可以通过speed*dt来修正dx,dy的值。注意这里的一个比较巧妙的设计,作者在定义全句变量的时候定义了一个名为friction(摩擦力)的全局变量,由于这个变量小于1,所以使用dx*=friction,dy*=friction,来进行计算的话,在dx,dy保持不变的情况下就会慢慢的变小,直至变为0,这就导致了游戏中圆球团在后来慢慢的变成的静止不动的效果。至于碰撞的处理就根据游戏界面的大小简单的使用返回距离来表示碰撞。
//定义重绘函数,每次绘图时,调用此函数
bool ReDraw()
{
hge->Gfx_BeginScene(); //开始绘图
hge->Gfx_Clear(0); //清空背景
hge->Gfx_RenderQuad(&quad); //重绘图片
hge->Gfx_EndScene(); //结束绘图
return false ;
}
Q:重绘函数的作用是什么?
A:重绘函数是在窗口需要重绘的时候进行调用的。和帧回调函数差不多,也是一种回调函数。在这个函数里面通过调用Gfx_BeginScene来开始绘制,使用Gfx_RenderQuad()函数来绘制一个hgeQuad结构中的物体。Gfx_Clear(0)函数可以清空游戏的背景,然后进行重绘。Gfx_EndScene函数会结束绘制,并且更新窗口。
Q:Gfx_Clear是带参数的函数,它有哪些参数?分别表示什么?
A:Gfx_Clear函数中带一个DWORD的参数,其中表示的是用指定的ARGB颜色来清除窗口,如果参数为0就表示用黑色来清除窗口。
//定义WinMain函数
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
hge = hgeCreate(HGE_VERSION); //创建HGE
//设置状态属性
hge->System_SetState(HGE_FRAMEFUNC,FrameFunc); //设置帧回调函数
hge->System_SetState(HGE_WINDOWED,true); //设置是否全屏
hge->System_SetState(HGE_USESOUND,true); //是否使用音乐
Tip:注意这里,如果我们要加载音效的话,这里就需要设置为true
hge->System_SetState(HGE_TITLE,"My First HGE Window -by XJ"); //设置标题栏
hge->System_SetState(HGE_LOGFILE,"log.txt"); //设置日志文件
hge->System_SetState(HGE_RENDERFUNC,ReDraw); //设置重绘函数
hge->System_SetState(HGE_FPS,100); //设置每秒FrameFunc调用的次数
hge->System_SetState(HGE_SCREENWIDTH,800); //设置屏幕宽度
hge->System_SetState(HGE_SCREENHEIGHT,600); //设置屏幕高度
hge->System_SetState(HGE_SCREENBPP,32); //设置像素位数为32bit/pix
if(hge->System_Initiate()) //初始化hge
{
snd = hge->Effect_Load("menu.wav"); //加载音效
quad.tex =hge->Texture_Load("particles.png"); //加载纹理图片进行贴图
Q:为什么要在这里加载?在其他地方可以不?
A:经过试验表明,如果在没有调用System_Initiate函数之前调用资源加载的函数,调用会失败,这里需要在以后注意,只有在初始化之后,我们才能够调用加载资源的函数。
quad.blend = BLEND_ALPHAADD | BLEND_COLORMUL | BLEND_ZWRITE ; //设置混色模式
Q:混色到底要如何使用?混色的参数要如何设置才能达到自己想要的效果?
A:???
if(!snd || !quad.tex)
{
// If one of the data files is not found, display
// an error message and shutdown.
MessageBox(NULL, "Can't load MENU.WAV or PARTICLES.PNG", "Error", MB_OK | MB_ICONERROR | MB_APPLMODAL);
hge->System_Shutdown();
hge->Release();
return 0;
}
for(int i = 0 ; i < 4 ; i ++)
{
quad.v[i].z = 0.5f ; //设置Z序
quad.v[i].col = 0xFFFFA000 ; //设置顶点颜色
}
Q:什么是顶点的Z序?
A:Z序就是从屏幕里到外的一个轴,一般用来显示立体的效果时需要使用它。而在上面由于同一的都是0.5所以没有看出什么效果,如果修改下,将这四个顶点的Z序改变成不一的,看看情况如何?通过实验发现,不管将Z序的值设置为多少,对于游戏的显示来说,没有任何改变。查询官网上的资料,说了如果Z-BUFFER没有启动的话,Z-order的值会被忽略掉,这里可能就是因为没有启用Z-BUFFER。
Q:如何使用ARGB颜色?前面的A值表示什么?
A:前面的A值表示的是颜色的透明度是多少。这个透明度是用来在混合的时候发生作用的,如果不进行混合,那么指定任何值都没有关系。但是一旦进行混合,我们就需要注意这个A值所代表的意思。白色(FF)表示的是当前这个颜色没有透明度,而黑色(00)表示的是当前这个衍射全透明,而介于两者之间的就是在混合的时候,将这种颜色设置为半透明状态。而在进行混合时A值起到什么作用一般根据混合的模式不同,A的作用也会不同。
//设置纹理的位置
quad.v[0].tx=96.0/128.0 ; quad.v[0].ty=64.0/128.0 ;
quad.v[1].tx=128.0/128.0; quad.v[1].ty=64.0/128.0 ;
quad.v[2].tx=128.0/128.0; quad.v[2].ty=96.0/128.0 ;
quad.v[3].tx=96.0/128.0 ; quad.v[3].ty=96.0/128.0 ;
Q:纹理的坐标是什么意思?为什么要这么计算?
A:在hgeVertex结构中含有两个float参数,表示的是纹理的坐标,范围在0.0-1.0之间。要想了解如何定位这个纹理坐标我们来看下资源文件中的particles.png图片。
从图片中我们可以看出在资源文件中存在着很多的图案,为什么此实例中没有看到其他的图案了?答案就在于顶点结构中的两个纹理坐标。
我们知道hgeQuad中加载了一个纹理,同时保存了4点的hgeVertex结构。接下来我们看看hgeVertex结构
struct hgeVertex
{
float x , y ; //顶点坐标
float z ; //Z序坐标
DWORD col ; //顶点颜色
float tx , ty ; //顶点在纹理上的坐标
};
注意看最后两个参数,tx,ty。它们表示的是所定义的顶点在纹理中的坐标。即这个顶点与纹理图片中的哪个点相对应,而第一,二个参数的意思是这个顶点在显示区域的位置坐标。比如上面代码中设置的纹理坐标,从图片中分析可以知道v[0]与纹理中的(96,64)绑定在一起,v[1]与纹理中的(128,64)绑定在一起,v[2]与纹理中的(128,96)绑定在一起,v[3]与纹理中的(96,96)绑定在一起。由于纹理坐标的范围是在0.0-1.0之间,所以这些坐标点分别除上了像图片的宽度或者高度128,来计算比例。这样四个点就分别对应于纹理中的包含圆球图案的矩形的四个点,也就是说在调用Gfx_RenderQuad的时候,就会根据顶点结构中的x,y坐标绘制这个4个顶点,然后在贴上这四个顶点所绑定的图案,这就导致了为什么在程序中引入的是整张图片,而在游戏中只出现了一个圆球图案的情况。细心的读者可能注意到了,在定义纹理坐标时,这四个顶点的顺序不是任意的,而是按照顺时针旋转的方向来定义这四个顶点的,这里需要注意。
hge->System_Start(); //开始帧回调函数的执行
Q: 为什么调用System_Start之后就将资源释放掉?
A: 在官网有这样一段话,“Now we're ready to start the game loop with the System_Start function. When the frame function returns trueand the game loop is finished we should free the loaded texture and the sound effect:”
这句话的意思是说我们调用System_Start来开始游戏的循环。循环包括图形图像的绘制,音效的播放,游戏的逻辑和按键的判断等等。当帧回调函数返回true的是偶,System_Start才会返回。所以System_Start返回了就代表游戏结束了,我们需要将游戏中使用的全部资源都释放掉。
hge->Texture_Free(quad.tex); //释放纹理资源
hge->Effect_Free(snd); //释放音效资源
}
else
{
MessageBox(NULL,hge->System_GetErrorMessage(),"Error",MB_OK | MB_ICONERROR);
}
hge->System_Shutdown();
Tip:注意先要关闭,然后在释放。
hge->Release();
return 0 ;
}
Q:关于Z序Z-BUFFER的开启有什么作用?如何使用?
A:这个问题,期待官网上后续的教程可以有效的演示如何进行操作。
以下是程序的完整代码:
#include<hge.h>
#pragma comment(lib,"hge.lib")
//定义全局变量
HGE * hge = NULL ;
hgeQuad quad ; //用于保存绘图的顶点,纹理,和混色的函数
HEFFECT snd ; //保存音效的句柄
float x = 100.0f , y = 100.0f ;
float dx = 0.0f , dy = 0.0f ;
const float speed = 90 ;
const float friction = 0.98f ;
//定义播放音效的函数
void boom()
{
int pan = int((x-400)/4);
float pitch = (dx*dx+dy*dy)*0.0005f + 0.2f ;
hge->Effect_PlayEx(snd,100,pan,pitch); //snd是音频资源的句柄,100表示声音大小,pan表示左右声道,pitch表示播放频率
}
//定义帧回调函数
bool FrameFunc()
{
float dt = hge->Timer_GetDelta(); //获取自上次调用此函数到此次调用此函数的时间间隔
if(hge->Input_GetKeyState(HGEK_ESCAPE))
return true ;
//根据不同的按键,使用速度和延迟时间来修正位置
if(hge->Input_GetKeyState(HGEK_LEFT))
dx-=speed*dt ;
if(hge->Input_GetKeyState(HGEK_RIGHT))
dx+=speed*dt ;
if(hge->Input_GetKeyState(HGEK_UP))
dy-=speed*dt ;
if(hge->Input_GetKeyState(HGEK_DOWN))
dy+=speed*dt ;
//做一些运动的计算
dx*=friction;
dy*=friction;
x+=dx;
y+=dy;
if(x>784)
{
x=784-(x-784);
dx=-dx;
boom();
}
if(x<16)
{
x=16+16-x;
dx=-dx;
boom();
}
if(y>584)
{
y=584-(y-584);
dy=-dy;
boom();
}
if(y<16)
{
y=16+16-y;
dy=-dy;
boom();
}
//配置hgeQuad结构中的顶点
quad.v[0].x=x-16;
quad.v[0].y=y-16;
quad.v[1].x=x+16;
quad.v[1].y=y-16;
quad.v[2].x=x+16;
quad.v[2].y=y+16;
quad.v[3].x=x-16;
quad.v[3].y=y+16;
return false ;
}
//定义重绘函数,每次绘图时,调用此函数
bool ReDraw()
{
hge->Gfx_BeginScene(); //开始绘图
hge->Gfx_Clear(0); //清空背景
hge->Gfx_RenderQuad(&quad); //重绘图片
hge->Gfx_EndScene(); //结束绘图
return false ;
}
//定义WinMain函数
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
hge = hgeCreate(HGE_VERSION); //创建HGE
//设置状态属性
hge->System_SetState(HGE_FRAMEFUNC,FrameFunc); //设置帧回调函数
hge->System_SetState(HGE_WINDOWED,true); //设置是否全屏
hge->System_SetState(HGE_USESOUND,true); //是否使用音乐
hge->System_SetState(HGE_TITLE,"My First HGE Window -by XJ"); //设置标题栏
hge->System_SetState(HGE_LOGFILE,"log.txt"); //设置日志文件
hge->System_SetState(HGE_RENDERFUNC,ReDraw); //设置重绘函数
hge->System_SetState(HGE_FPS,100); //设置每秒FrameFunc调用的次数
hge->System_SetState(HGE_SCREENWIDTH,800); //设置屏幕宽度
hge->System_SetState(HGE_SCREENHEIGHT,600); //设置屏幕高度
hge->System_SetState(HGE_SCREENBPP,32); //设置像素位数为32bit/pix
if(hge->System_Initiate()) //初始化hge
{
snd = hge->Effect_Load("menu.wav"); //加载音效
quad.tex =hge->Texture_Load("particles.png"); //加载纹理图片进行贴图
quad.blend = BLEND_ALPHAADD | BLEND_COLORMUL | BLEND_ZWRITE ; //设置混色模式
if(!snd || !quad.tex)
{
// If one of the data files is not found, display
// an error message and shutdown.
MessageBox(NULL, "Can't load MENU.WAV or PARTICLES.PNG", "Error", MB_OK | MB_ICONERROR | MB_APPLMODAL);
hge->System_Shutdown();
hge->Release();
return 0;
}
for(int i = 0 ; i < 4 ; i ++)
{
quad.v[i].z = 0.5f ; //设置Z序
quad.v[i].col = 0xFFFFA000 ; //设置顶点颜色
}
//设置纹理坐标的位置
quad.v[0].tx=96.0/128.0 ; quad.v[0].ty=64.0/128.0 ;
quad.v[1].tx=128.0/128.0; quad.v[1].ty=64.0/128.0 ;
quad.v[2].tx=128.0/128.0; quad.v[2].ty=96.0/128.0 ;
quad.v[3].tx=96.0/128.0 ; quad.v[3].ty=96.0/128.0 ;
hge->System_Start(); //开始帧回调函数的执行
hge->Texture_Free(quad.tex); //释放纹理资源
hge->Effect_Free(snd); //释放音效资源
}
else
{
MessageBox(NULL,hge->System_GetErrorMessage(),"Error",MB_OK | MB_ICONERROR);
}
hge->System_Shutdown();
hge->Release();
return 0 ;
}
HGE引擎 - 绘制,声音,碰撞处理的更多相关文章
- C++多小球非对心弹性碰撞(HGE引擎)
程序是一个月前完成的,之前一直没正儿八经的来整理下这个程序,感觉比较简单,不过即使简单的东西也要跟大家分享下. 源码下载:http://download.csdn.net/detail/y851716 ...
- hge引擎示例教程cmake项目
hge引擎的示例代码在vs2017不能很好的运行,需要调不少东西,所以我将其重新整理成cmake的项目. 所有示例均在vs2017 msvc 下测试可以正常运行. 由于缺少libhgehelp.a所以 ...
- HGE引擎之hgeSprite
一.hgeSprite类 hgeSprite是一个精灵实体的HGE帮助类. 1.构造函数 创建和初始化一个hgeSprite对象. hgeSprite(HTEXTURE tex, float x, f ...
- Android之使用AchartEngineActivity引擎绘制柱状图、曲线图
1.简介 AChartEngine(简称ACE)是Google的一个开源图表库(for Android).它功能强大,支持散点图.折线 .关于里面类的具体使用,请下载响应的文档说明(主页上有). 2. ...
- 白鹭引擎 - 绘制圆形的进度条 ( graphics )
class Main extends egret.DisplayObjectContainer { /** * Main 类构造器, 初始化的时候自动执行, ( 子类的构造函数必须调用父类的构造函数 ...
- HGE引擎改进——2014/3/4
2014/3/4 更新 1.提升资源包管理效率 2.Show库整合.目前Show库有Picture.Frame.Animation和Particle类,以及PictureData和ParticleSy ...
- HGE引擎改进——2014/2/18 和 2014/2/27
2014/2/18 更新 hgehelper库:增加hgeSkeleton类,该类用于播放骨骼动画 增加工具骨骼动画编辑器(AnimationEd),该工具用于骨骼动画的编辑 2014/2/27 更新 ...
- HGE引擎改进——2014/1/27
2014/1/27 更新 hge库: 1.增加回调函数procResizeFunc(),这个函数会在窗口大小改变时调用,不是必要函数 2.修复LOG信息显示为乱码的错误 项目主页:https://co ...
- HGE引擎改进
基于HGEDX9版本修改. hge库: 1.全UNICODE化 2.增加时间模块:Timer_StartTick(),Timer_NowTick()等六个函数 3.增加服从正态分布的随机数生成函数:R ...
随机推荐
- hdu1114
完全背包的水题,不过今天才学动态规划,就这样啦……hahahah!!! 完全背包跟普通背包的区别是普通背包从后往前循环,以防止被替换 完全背包是从前往后循环,后面的状态会跟着之前状态的改变而改变…… ...
- Swift - 数组排序方法(附样例)
下面通过一个样例演示如何对数组元素进行排序.数组内为自定义用户对象,最终要实现按用户名排序,数据如下: 1 2 3 4 var userList = [UserInfo]() userList.app ...
- Swift - 文本输入框内容改变时响应,并获取最新内容
1,问题描述 有时我们开发的时候需要先把“确认”按钮初始设置为不可用,当文本框中输入文字以后,再将输入按钮变为可用. 2,实现原理 (1)要检测文本框内容的变化,我们需要让新界面的Controller ...
- android解析xml一直报错org.xmlpull.v1.XmlPullParserException
错误: org.xmlpull.v1.XmlPullParserException: Unexpected token (position:TEXT @1:2 injava.io.String ...
- ListCtrl控件着色
最近在写一款山寨的反病毒软件,大致功能已经实现,还有一些细小的环节需要细化. 其中,在界面编程中,就用到了给ListCtrl控件着色,查看了网上一些文章,终于实现了. 其实说白了,原理很简单,就是Li ...
- 怎样高速正确的安装 Ruby, Rails 执行环境
对于新入门的开发人员,怎样安装 Ruby, Ruby Gems 和 Rails 的执行环境可能会是个问题,本页主要介绍怎样用一条靠谱的路子高速安装 Ruby 开发环境. 次安装方法相同适用于产品环境! ...
- 链栈之C++实现
链栈是借用单链表实现的栈.其不同于顺序栈之处在于: 1.链栈的空间是程序运行期间根据需要动态分配的,机器内存是它的上限.而顺序栈则是 静态分配内存的. 2.链栈动态分配内存的特性使得它一般无需考虑栈溢 ...
- c#Enum的用法
public enum ResType { Role = 0, Dept = 1, Group = 2, Site = 3, Org = 4, Sub=8 } 这里定义了一个enum ResTy ...
- java.util.zip - Recreating directory structure(转)
include my own version for your reference. We use this one to zip up photos to download so it works ...
- 96 Stocks APIs: Bloomberg, NASDAQ and E*TRADE
Our API directory now includes 96 stocks APIs. The newest is the Eurex VALUES API. The most popula ...