很多时候,比如我们玩网络游戏,单机尤其是RPG(Role Playing Game角色扮演)类,经常见到自动寻路
的功能,只要点一下目标坐标或给定一个位置,角色就傻乎乎冲过去了……
平面的寻路似乎很简单,其实还是很有难度的,最直接的证据就是走迷宫游戏,直接让很多人晕倒,很多
头猪口吐白沫。我要发布的这个组件,主要是基于A星算法,不过允许你设置是否能走对角线(在实际应用
中,推箱子一类的游戏是不能走对角线的),此外,像http组件,大侠加入了一些大幅提升运算性能的元素
如:
极速内存填充函数;
内存预申请机制;
字节组比较(用3条指令判断4个字符,一般要用到13条);
等等……
关于http组件,该组件是用于获取网页html源码,链接提取/识别的快速、绿色的组件,将在以后发布,呵呵。
下面主要介绍一下急速内存填充,内存预申请和A星算法。
1.急速内存填充
这个主要从3D开发中学来的,虽然现在很多64位的CPU,不过基本还是能100%兼容32位的指令,通常来
说,C/C++填充内存是用memset函数(ZeroMemory一样的),该函数将寻址指针指向的内存,填充一个字节
或一个长整型,然后指针下移,消耗的CPU时间是很那个的,我们的函数如下
//急速填充16bits区域 inline void fnShortFillEx(void *p, USHORT val, int n) { //begin asm _asm{ mov edi, p ;edi points to ptr mov ecx, n ;count mov ax, val ;16bits rep stosw ;loop } //end asm } //急速填充32bits区域 inline void fnLongFillEx(void *p, UINT val, int n) { //begin asm _asm{ mov edi, p ;edi points to ptr mov ecx, n ;count mov eax, val ;32bits rep stosd ;loop } //end asm }
可以发现,填充16或32位内存块,只有少少几条指令,后面的rep指令会重复执行,不过仍然比循环或跳转
少得多,inline是内联函数,省去函数调用的堆栈操作等……
2.内存预申请
其实很简单,我们在动态数组的时候,会使用动态内存申请,如VB6的Redim,C/C++的realloc函数。这些
函数虽然写代码可能只有一行,但是跟踪进去会发现里面还有乾坤,又是一番天地啊!
为了避免每添加一个元素,就执行一堆指令,我们先把可能需要的内存一次申请下来,如寻路要判断各个点的
参数,这是有限制的,如256X256的平面,最多有65536个点,一般很少有那么大面积的寻路,除了大型的游
戏,而把他们都申请下来才240K字节(按一个点一个32长整型计算),之后的就没必要说了……
3.A星算法
A星算法是启发性算法,为了到达目的地,我们从起点出发,把该点周围可通过的点标定(打开状态),关闭该
点,选择所有打开的点中,与终点距离最近的点,打开其周围所有可通过且未关闭的点……
每次打开新的点,就保留其上级点的坐标,用于到达终点后反追得到路径。反复运行直到坐标与终点相同或
找不到打开的点(苏武说:通个屁!)
在计算与目标距离时,我们要避免浮点运算(小数运算很久),我们用水平距离加上垂直距离代替他们的差的平
方的开平方,因为我们只要比较大小,we不是得到精确的值(差的平方跟差是对应关系,可以思考下)。
运行效果:
不好意思,GetTickCount的精度有限,所以显示了0毫秒,我也不想啊,电脑配置太恶心,不放发给大家一起恶心一下
硬盘转速鬼快,我总感觉双击第二击没点,界面就出来了,2000G的硬盘*3个
8个Intel 赛扬 双核 3GHz主频的CPU
不过不好意思,内存才8G……
这个包包的下载地址,请大家关注阿叔的csdn下载空间,谢谢……