前几天在图书馆借了一本《游戏程序设计概论》,发现这本书还不错,对游戏有个大概的介绍。学了里面的四方向等高线寻路算法后,把它改成了八方向。大概原理是,从目的点开始向周围一步一步扩展,知道遇到起始点为止。用到了两个队列,一个作为源,一个作为目的。先把目的点放入源队列,在将目的点向八个方向扩展,并放入目的队列,然后交换源与目的,再将源队列中的点向周围扩展,并放入目的队列,如此循环,知道遇到起始点。标记好后,从起始点开始寻找最短路径。
程序代码:
#include <windows.H>
#include <stdio.h>
#include "Queue.h"
#define D_MapWidth 15
#define D_MapHeight 13
#define D_MapSize (D_MapWidth*D_MapHeight)
// 地图数据 15 X 13
// 0 : 不可移动的区域, 1 : 可移动区域.
// 起始坐标 [12,10], 目的坐标 [1,1]
int MapData[D_MapHeight*D_MapWidth] = {
1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,
1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,
1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,
1,1,1,0,0,1,1,1,1,1,0,1,1,1,1,
1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,
1,1,1,1,1,1,1,0,0,0,1,1,1,1,0,
0,1,1,1,1,1,1,0,0,1,1,1,1,0,0,
0,1,1,1,1,1,0,0,1,1,1,1,0,0,0,
0,0,1,1,1,0,0,1,1,1,0,0,0,0,0,
0,0,0,1,0,0,0,1,1,1,0,1,1,1,1,
0,0,0,0,0,1,1,1,1,1,0,1,1,1,0,
0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,
0,0,0,0,1,1,1,1,1,1,1,0,0,0,0 };
int BackupMap[D_MapHeight*D_MapWidth];
int Path[D_MapHeight*D_MapWidth];
int CountOfPath = 0;
void QuickMapping ( int Posi_Target, int Posi_Start );
void PathRecorder( int StartPosi, int TargetPosi );
int GetStep ( int Position, int &StepNo );
void ShowPath ( void );
///
int main(int argc, char* argv[])
{
int Posi_Start = (10*D_MapWidth) + 12;
int Posi_Target = (1*D_MapWidth) + 1;
bool Found = false;
int Step = 1;
int MapSize = D_MapSize;
memset ( BackupMap, 0, sizeof(int) * MapSize );
// 由目的点开始绘制"等高线"
QuickMapping ( Posi_Target, Posi_Start );
// 显示结果
for ( int loopy=0 ; loopy<D_MapHeight ; loopy++ )
{
for ( int loopx=0 ; loopx<D_MapWidth ; loopx++ )
{
printf( " %02d", BackupMap[(loopy*D_MapWidth)+loopx] );
}
printf("/n");
}
// 计算路径
PathRecorder( Posi_Start, Posi_Target );
// 显示路径
ShowPath();
getchar();
return 0;
}
///
void QuickMapping ( int Posi_Target, int Posi_Start )
{
clQueue RecA, RecB, *SrcPointer, *DesPointer;
int StepNo = 1,
Position,
MapSize = D_MapWidth * D_MapHeight,
CurrentPosi,
QueueSize;
// 计算队列所需的容量, 并重新定义队列的大小.
QueueSize = (D_MapWidth+D_MapHeight)*2;
RecA.Resize ( QueueSize );
RecB.Resize ( QueueSize );
// 初始队列的功能.