1127人阅读 评论(0)

# 移动模式

## 标准移动模式算法

//例3-1：控制指令数据结构

ControlData
{
double turnRight;
double turnLeft;
double stepForward;
double stepBackward;
};

//例3-2：模式的初始化

Pattern[0].turnRight=0;
Pattern[0].turnLeft=0;
Pattern[0].stepForward=2;
Pattern[0].stepBackward=0;

Pattern[1].turnRight=0;
Pattern[1].turnLeft=0;
Pattern[1].stepForward=2;
Pattern[1].stepBackward=0;

Pattern[2].turnRight=10;
Pattern[2].turnLeft=0;
Pattern[2].stepForward=0;
Pattern[2].stepBackward=0;

Pattern[3].turnRight=10;
Pattern[3].turnLeft=0;
Pattern[3].stepForward=0;
Pattern[3].stepBackward=0;

Pattern[4].turnRight=0;
Pattern[4].turnLeft=0;
Pattern[4].stepForward=2;
Pattern[4].stepBackward=0;

Pattern[5].turnRight=0;
Pattern[5].turnLeft=0;
Pattern[5].stepForward=2;
Pattern[5].stepBackward=0;

Pattern[6].turnRight=0;
Pattern[6].turnLeft=10;
Pattern[6].stepForward=0;
Pattern[6].stepBackward=0;
…

//例3-3：运行模式数组

void GameLoop(void)
{
…
Object.orientation += Pattern[CurrentIndex].turnRight;
Object.orientation -= Pattern[CurrentIndex].turnLeft;
Objetct.x += Pattern[CurrentIndex].stepForward;
Object.x -= Pattern[CurrentIndex].stepBackward;

CurrentIndex++;
…
}

## 砖块环境中的移动模式

//例3-4：初始化路径数组

void InitializePathArrays(void)
{
int i;
for(i=0;i<kMaxPathLength;i++)
{
pathRow[i]=-1;
pathCol[i]=-1;
}
}

//例3-5：修改后的 Bresenham 视线追踪算法，用于计算线段

void ai_Entity::BuildPathSegment(void)
{
int i;
int nextCol=col;
int nextRow=row;
int deltaRow=endRow-row;
int deltaCol=endCol-col;
int stepCol;
int stepRow;
int currentStep;
int fraction;
int i;

for(i=0;i<kMaxPathLength;i++)
{
if((pathRow[i]== -1) && (pathCol[i]== 1))
{
currentStep=i;
break;
}
}
if(deltaRow<0)
stepRow=-1;
else
stepRow=1;
if(deltaCol<0)
stepCol=-1;
else
stepCol=1;
deltaRow=abs(deltaRow*2);
deltaCol=abs(deltaCol*2);

pathRow[currentStep]=nextRow;
pathCol[currentStep]=nextCol;
currentStep++;
if(currentStep >= kMaxPathLength)
return;
if(deltaCol>deltaRow)
{
fraction=deltaRow*2-deltaCol;
while(nextCol != endCol)
{
if(fraction >= 0)
{
nextRow += stepRow;
fraction =fraction-deltaCol;
}
nextCol=nextCol+stepCol;
fraction=fraction+deltaRow;
pathRow[currentStep]=nextRow;
pathCol[currentStep]=nextCol;
currentStep++;
if(currentStep >= kMaxPathLength)
return;
}
}
else
{
fraction=deltaCol*2-deltaRow;
while(nextRow!=endRow)
{
if(fraction>=0)
{
nextCol=nextCol+stepCol;
fraction=fraction-deltaRow;
}
nextRow=nextRow+stepRow;
fraction=fraction+deltaCol;
pathRow[currentStep]=nextRow;
pathCol[currentStep]=nextCol;
currentStep++;
if(currentStep >= kMaxPathLength)
return;
}
}
}

//例3-6：矩形模式

entityList[1].InitializePathArrays();
entityList[1].BuildPathSegment(10,3,18,3);
entityList[1].BuildPathSegment(18,3,18,12);
entityList[1].BuildPathSegment(18,12,10,12);
entityList[1].BuildPathSegment(10,12,10,3);
entityList[1].NormalizePattern();
entityList[1].patternRowOffset=5;
entityList[1].patternColOffset=2;

//例3-7：标准化函数

void ai_Entity::NormalizePattern(void)
{
int i;
int rowOrigin=pathRow[0];
int colOrigin=pathCol[0];
for(i=0;i< kMaxPathLength;i++)
{
if((pathRow[i]==-1) && (pathCol[i]==-1))
{
pathSize=i-1;
break;
}
}
for(i=0;i<pathSize;i++)
{
pathRow[i]=pathRow[i]-rowOrigin;
pathCol[i]=pathCol[i]-colOrigin;
}
}

//例3-8：简单巡逻模式

entityList[1].InitializePathArrays();
entityList[1].BuildPathSegment(10,3,18,3);
entityList[1].BuildPathSegment(18,3,10,3);
entityList[1].NormalizePattern();
entityList[1].patternRowOffset=5;
entityList[1].patternColOffset=2;

//例3-9：复杂巡逻模式

entityList[1].BuildPathSegment(4,2,4,11);
entityList[1].BuildPathSegment(4,11,2,24);
entityList[1].BuildPathSegment(2,24,13,27);
entityList[1].BuildPathSegment(13,27,16,24);
entityList[1].BuildPathSegment(16,24,13,17);
entityList[1].BuildPathSegment(13,17,13,13);
entityList[1].BuildPathSegment(13,13,17,5);
entityList[1].BuildPathSegment(17,5,4,2);
entityList[1].NormalizePattern();
entityList[1].patternRowOffset=5;
entityList[1].patternColOffset=2;

例3-10：模式矩阵的初始化

for(i=0;i<kMaxRows;i++)
{
for(j=0;j<kMaxCols;j++)
pattern[i][j]=0;
}

//例3-11：建立模式

BuildPatternSegment(3,2,16,2);
BuildPatternSegment(16,2,16,11);
BuildPatternSegment(16,11,9,11);
BuildPatternSegment(9,11,9,2);
BuildPatternSegment(9.2.3.6);
BuildPatternSegment(3,6,3,2);

//例3-12：沿着模式矩阵走

void ai_Entity::FollowPattern(void)
{
int i,j;
int possibleRowPath[8]={0,0,0,0,0,0,0,0};
int possibleColPath[8]={0,0,0,0,0,0,0,0};
int rowOffset[8]={-1,-1,-1,0,0,1,1,1};
int colOffset[8]={-1,0,1,-1,1,-1,0,1};

j=0;
for(i=0;i<8;i++)
{
if(pattern[row+rowOffset[i]][col+colOffset[i]]==1)
{
if(!((row+rowOffset[i])==previousRow) && ((col+colOffset[i])==previousCol)))
{
possibleRowPath[j]=row+rowOffset[i];
possibleColPath[j]=col+colOffset[i];
j++;
}
}
}
i=Rnd(0,j-1);
previousRow=row;
previousCol=col;

row=possibleRowPath[i];
col=possibleColPath[i];
}

## 仿真物理环境中的移动模式

### 控制结构

//例3-13：移动模式控制 数据结构体

struct ControlData
{
bool PThrusterActive;
bool SThrusterActive;
double dPositionLimit;
bool LimitPositionChange;
}

dPositionLimit 存储的是这组指令运行前，相对于载具位置要移动的距离。如果 LimitHeadingChange 设为 true，则每轮仿真循环中，载具的相对位置会和 dPositionChange 来比较，以决定是否要从模式数组中取出下一组指令。

//例3-14：记录状态改变的结构体

struct StateChangeData
{
Vector InitialPosition;
double dPosition;
int CurrentControlID;
}

### 定义模式

//例3-15：模式数组声明

#define _PATROL_ARRAY_SIZE 8
#define _ZIGZAG_ARRAY_SIZE 4

ControlData PatrolPattern[_PATROL_ARRAY_SIZE];
ControlData ZigZagPattern[_ZIGZAG_ARRAY_SIZE];

StateChangeData PatternTracking;

//例3-16：方形巡逻模式初始化

PatrolPattern[0].LimitPositionChange=true;
PatrolPattern[0].dPositionLimit=200;
PatrolPattern[0].PThrusterActive=false;
PatrolPattern[0].SThrusterActive=false;

PatrolPattern[1].LimitPositionChange=false;
PatrolPattern[1].dPositionLimit=0;
PatrolPattern[1].PThrusterActive=true;
PatrolPattern[1].SThrusterActive=false;

PatrolPattern[2].LimitPositionChange=true;
PatrolPattern[2].dPositionLimit=200;
PatrolPattern[2].PThrusterActive=false;
PatrolPattern[2].SThrusterActive=false;

PatrolPattern[3].LimitPositionChange=false;
PatrolPattern[3].dPositionLimit=0;
PatrolPattern[3].PThrusterActive=true;
PatrolPattern[3].SThrusterActive=false;

PatrolPattern[4].LimitPositionChange=true;
PatrolPattern[4].dPositionLimit=200;
PatrolPattern[4].PThrusterActive=false;
PatrolPattern[4].SThrusterActive=false;

PatrolPattern[5].LimitPositionChange=false;
PatrolPattern[5].dPositionLimit=0;
PatrolPattern[5].PThrusterActive=true;
PatrolPattern[5].SThrusterActive=false;

PatrolPattern[6].LimitPositionChange=true;
PatrolPattern[6].dPositionLimit=200;
PatrolPattern[6].PThrusterActive=false;
PatrolPattern[6].SThrusterActive=false;

PatrolPattern[7].LimitPositionChange=false;
PatrolPattern[7].dPositionLimit=0;
PatrolPattern[7].PThrusterActive=true;
PatrolPattern[7].SThrusterActive=false;
//例3-17：蛇形模式初始化

ZigZagPattern[0].LimitPositionChange=true;
ZigZagPattern[0].dPositionLimit=100;
ZigZagPattern[0].PThrusterActive=false;
ZigZagPattern[0].SThrusterActive=false;

ZigZagPattern[1].LimitPositionChange=false;
ZigZagPattern[1].dPositionLimit=0;
ZigZagPattern[1].PThrusterActive=true;
ZigZagPattern[1].SThrusterActive=false;

ZigZagPattern[2].LimitPositionChange=true;
ZigZagPattern[2].dPositionLimit=100;
ZigZagPattern[2].PThrusterActive=false;
ZigZagPattern[2].SThrusterActive=false;

ZigZagPattern[3].LimitPositionChange=false;
ZigZagPattern[3].dPositionLimit=0;
ZigZagPattern[3].PThrusterActive=true;
ZigZagPattern[3].SThrusterActive=false;

### 执行模式

//例3-18： InitializePatternTracking()函数

void  InitializePatternTracking()
{
PatternTracking.CurrentControlID=0;
PatternTracking.dPosition=0;

PatternTracking.InitialPosition=Craft2.vPosition;
}

//例3-19：UpdateSimulation()

{
…

if(Patrol)
{
if(!DoPattern(PatrolPattern,_PATROL_ARRAY_SIZE))
InitializePatternTracking();
}
if(ZigZag)
{
if(!DoPattern(ZigZagPattern,_ZIGZAG_ARRAY_SIZE))
InitializePatternTracking();
}

…

Craft2.UpdateBodyEuler(dt);

…
}

### DoPattern 函数

//例3-20：DoPattern()

bool DoPattern(ControlData *pPattern,int size)
{
int i=PatternTracking.CurrentControlID;
Vector u;

//检查模式数组中的下一组指令是否需要取出
{
InitializePatternTracking();
i++;
PatternTracking.CurrentControlID=i;
if(PatternTracking.CurrentControlID >= size)
return false;
}

//计算这组指令开始运行后方向上的改变
u=Craft2.vVelocity;
u.Normalize();
double P;

//计算这组指令开始运行后位置上的改变
u=Craft2.vPosition-PatternTracking.InitialPosition;
PatternTracking.dPosition=u.Magnitude();

//求出转向力系数
double f;
{
}
else
f=1;
if(f<0.05)
f=0.05;

//依照当前这组指令的赋值施加转向力
Craft2.SetThrusters(pPattern[i].PThrusterActive,pPattern[i].SThrusterActive,f);
return true;
}

DoPattern( ) 函数所做的第一件事是复制模式数组当前索引值 CurrentControlID 到一个临时变量 i 中以备后用。

### 代码下载

http://pan.baidu.com/s/1hswySRi

个人资料
等级：
访问量： 27万+
积分： 3436
排名： 1万+
关于我

现在还处于探索世界的阶段，学的比较杂。关注游戏编程，以及要开始准备考研了，所以有些专业课也会写上来。

这学期课很多，平衡课业和空闲。未完成的系列文章会慢慢更新的。

“每天都要保持前进，我势必要有强劲的实力，再跟全新的自己问好”

博客专栏
 游戏编程入门 文章：22篇 阅读：28078 计算机图形学 文章：13篇 阅读：33194 数据结构 文章：12篇 阅读：15222 游戏开发中的人工智能 文章：15篇 阅读：18328