游戏人工智能实验报告一.docx
《游戏人工智能实验报告一.docx》由会员分享,可在线阅读,更多相关《游戏人工智能实验报告一.docx(22页珍藏版)》请在冰点文库上搜索。
游戏人工智能实验报告一
实验一追逐与拦截
实验报告
一、实验目的
掌握游戏中追逐与拦截的人工智能算法
二、实验仪器
Windows7系统
MicrosoftVisualStudio2015
三、实验原理及过程
//描述追逐与拦截的算法原理
//描述程序实现时的思路包括对每个调用的API进行详细说明
(1)描述追逐与拦截的算法原理:
连续环境中的视线追逐是最简单的追逐算法,但是追逐者的移动不仅有线速度,而且还有角速度。
算法思路就是:
首先根据角速度把方向转到视线方向,然后向目标追过去。
完整追逐/闪躲由三部分组成:
首先,作出追或逃的决策判断。
其次,开始追或逃(本章重点)最后,避开障碍物。
拦截算法的基本原理是可以预测猎物未来的位置,然后直接到那个位置去,让追击者和猎物同时到达同一个位置。
为了找出追击者和猎物能同时到达的点,不仅要考虑他们的移动方向,还要考虑他们的速度。
(2)Main和winmain进行函数的定义。
RigidBody2D类:
进行物体的质量,惯性,关系,坐标,长高宽即外形的定义,用向量表示他们移动的方向。
UpdateSimulation函数对于物体1,2的移动进行反应和控制。
DoCraft2Chase函数对于物体1,2追逐进行判断,DoCraft2Evade函数对于物体1,2躲避进行判断。
DoCraft2InterceptAlt函数对于物体1,2拦截进行判断。
DoAttractCraft2函数判断是否攻击。
四、实验结果
匚h2Demo
五、实验心得(需包括有何不足如何改进)
我认为目前的追逐与拦截的不足之处在于:
本次实验做的是连续环境中的视线追逐与拦截。
相比砖块环境中的追逐与拦截,肯定是要灵活变通很多,但是箭头老要跑到屏幕外面去,这就非常尴尬了。
猎物的速度向量和初始位置向量是固定的,而且靠拢时间的计算是需要相对位移和相对速度的,容易得到两者不相遇的尴尬情况。
如何改进:
计算采用靠拢时间的办法,此外,再想办法让箭头留在屏幕以内,这样视觉感受会比较好。
六、主要代码
main.cpp
#include"main.h"
#include"time.h"
//
/*
Book:
AlforGameDevelopers
Authors:
DavidM.Bourg&GlennSeemann
Example:
Chasingandevadingincontinuousenvironments.Chapter2
*/
//
//GlobalVariables:
intFrameCounter=0;
RigidBody2DCraft1,Craft2;
VectorTarget;
#define
_TIMESTEP
0.001
#define
_TOL1e-10
#define
_FWDTIME10
#define
_THRUSTFACTOR
3
#define
CHASESETUP
true
boolInitialize(void){
Craft1.fMass=10;
Craft1.fInertia=10;
Craft1.fInertiaInverse=1/10;
Craft1.vPosition.x=_WINWIDTH-60;
Craft1.vPosition.y=_WINHEIGHT*0.8;
Craft1.fWidth=10;
Craftl.fLength=20;
Craftl.fHeight=5;
Craftl.fOrientation=135;
Craftl.CD.y=-0.12*Craft1.fLength;Craftl.CD.x=0.0f;//
coordinatesofthebodycenterofdrag
Craftl.CT.y=-0.50*Craft1.fLength;Craft1.CT.x=0.0f;//
coordinatesofthepropellerthrustvector
Craft1.CPT.y=0.5*Craft1.fLength;Craft1.CPT.x=-0.5*Craft1.fWidth;
//coordinatesoftheportbowthruster
Craft1.CST.y=0.5*Craft1.fLength;Craft1.CST.x=0.5*Craft1.fWidth;
//coordinatesofthestarboardbowthruster
Craft1.ProjectedArea=(Craft1.fLength+Craft1.fWidth)*Craftl.fHeight;
Craftl.ThrustForce=_THRUSTFORCE*1;
Craft2.fMass=10;
Craft2.fInertia=10;
Craft2.fInertialnverse=1/10;
if(_CHASESETUP)
{
Craft2.vPosition.x=40;
Craft2.vPosition.y=_WINHEIGHT*0.8;
}else{
Craft2.vPosition.x=Craft1.vPosition.x-Craft1.fLength*8;
Craft2.vPosition.y=Craft1.vPosition.y-Craft1.fLength*4;}
Craft2.fWidth=10;
Craft2.fLength=20;
Craft2.fHeight=5;
if(_CHASESETUP)
Craft2.fOrientation=-135;
else
Craft2.fOrientation=135;
Craft2.CD.y=-0.12*Craft2.fLength;Craft2.CD.x=0.0f;//
coordinatesofthebodycenterofdrag
Craft2.CT.y=-0.50*Craft2.fLength;Craft2.CT.x=0.0f;//
coordinatesofthepropellerthrustvector
Craft2.CPT.y=0.5*Craft2.fLength;Craft2.CPT.x=0.5*Craft2.fWidth;
//coordinatesoftheportbowthruster
Craft2.CST.y=0.5*Craft2.fLength;Craft2.CST.x=-0.5*Craft2.fWidth;
//coordinatesofthestarboardbowthruster
Craft2.ProjectedArea=(Craft2.fLength+Craft2.fWidth)*Craft2.fHeight;
Craft2.ThrustForce=_THRUSTFORCE*_THRUSTFACTOR;
returntrue;
}voidUpdateSimulation(void){
doubledt=_TIMESTEP;
RECTr;
Craft1.SetThrusters(false,false);
if(IsKeyDown(VK_UP))Craft1.ModulateThrust(true);
if(IsKeyDown(VK_DOWN))Craft1.ModulateThrust(false);
if(IsKeyDown(VK_RIGHT))Craft1.SetThrusters(true,false);
if(IsKeyDown(VK_LEFT))Craft1.SetThrusters(false,true);
//Docraft2AI
Craft2.Fa.x=0;
Craft2.Fa.y=0;
Craft2.Pa.x=0;
Craft2.Pa.y=0;
if(BasicChase)
{
DoCraft2Chase();
DoCraft2ModulateThrust();
}
if(BasicEvade)
DoCraft2Evade();
if(InterceptChase)
{
〃DoCraft2lntercept();
〃DoCraft2ModulateThrust();
DoCraft2lnterceptAlt();
}if(PotentialChase)
DoAttractCraft2();
//updatethesimulation
Craftl.UpdateBodyEuler(dt);
Craft2.UpdateBodyEuler(dt);
if(FrameCounter>=_RENDER_FRAME_COUNT){
//updatethedisplayif(!
ShowTrails)ClearBackBuffer();
DrawCraft(Craft1,RGB(0,0,255));
DrawCraft(Craft2,RGB(255,0,0));
RECTr;
r.left=(int)(Target.x-3);
r.top=(int)(Target.y-3);
r.right=(int)(Target.x+3);r.bottom=(int)(Target.y+3);DrawEllipse(&r,1,RGB(0,255,0));
CopyBackBufferToWindow();FrameCounter=0;
}else
FrameCounter++;
if(Craft1.vPosition.x>_WINWIDTH)Craft1.vPosition.x=0;if(Craft1.vPosition.x<0)Craft1.vPosition.x=_WINWIDTH;
if(Craft1.vPosition.y>_WINHEIGHT)Craft1.vPosition.y=0;
if(Craft1.vPosition.y<0)Craft1.vPosition.y=_WINHEIGHT;
if(Craft2.vPosition.x>_WINWIDTH)Craft2.vPosition.x=0;if(Craft2.vPosition.x<0)Craft2.vPosition.x=_WINWIDTH;if(Craft2.vPosition.y>_WINHEIGHT)Craft2.vPosition.y=0;if(Craft2.vPosition.y<0)Craft2.vPosition.y=_WINHEIGHT;
}
voidDrawCraft(RigidBody2Dcraft,COLORREFclr)
{
VectorvList[5];
doublewd,lg;
inti;
Vectorv1;
wd=craft.fWidth;
lg=craft.fLength;
vList[0].y=lg/2;vList[0].x=wd/2;
vList[1].y=-lg/2;vList[1].x=wd/2;
vList[2].y=-lg/2;vList[2].x=-wd/2;
vList[3].y=lg/2;vList[3].x=-wd/2;
vList[4].y=lg/2*1.5;vList[4].x=0;
for(i=0;i<5;i++)
{
v1=VRotate2D(craft.fOrientation,vList[i]);vList[i]=v1+craft.vPosition;
}
DrawLine(vList[0].x,vList[0].y,vList[1].x,vList[1].y,2,clr);
DrawLine(vList[1].x,vList[1].y,vList[2].x,vList[2].y,2,clr);
DrawLine(vList[2].x,vList[2].y,vList[3].x,vList[3].y,2,clr);
DrawLine(vList[3].x,vList[3].y,vList[4].x,vList[4].y,2,clr);
DrawLine(vList[4].x,vList[4].y,vList[0].x,vList[0].y,2,clr);
if(ShowVectors)
{
Vectorv,u;doublef=5;
//Showvelocityvectorsingreen
DrawLine(craft.vPosition.x,craft.vPosition.y,
craft.vPosition.x+craft.vVelocity.x,craft.vPosition.y+craft.vVelocity.y,3,
RGB(0,255,0));
//Showforcevectorsinblack
//thrustvector
v.x=0;
v.y=craft.ThrustForce*f;
v=VRotate2D(craft.fOrientation,v);
u.x=craft.CT.x;
u.y=craft.CT.y;
u=VRotate2D(craft.fOrientation,u);
DrawLine(craft.vPosition.x+u.x,craft.vPosition.y+u.y,craft.vPosition.x+u.x+v.x,craft.vPosition.y+u.y+v.y,1,RGB(0,0,0));
//portsteeringforce
v.x=craft.PThrust.x*f;
v.y=craft.PThrust.y*f;
v=VRotate2D(craft.fOrientation,v);
u.x=craft.CPT.x;
u.y=craft.CPT.y;
u=VRotate2D(craft.fOrientation,u);
DrawLine(craft.vPosition.x+u.x,craft.vPosition.y+u.y,craft.vPosition.x+u.x+v.x,craft.vPosition.y+u.y+v.y,1,RGB(0,0,0));
//stbdsteeringforce
v.x=craft.SThrust.x*f;
v.y=craft.SThrust.y*f;
v=VRotate2D(craft.fOrientation,v);
u.x=craft.CST.x;
u.y=craft.CST.y;
u=VRotate2D(craft.fOrientation,u);
DrawLine(craft.vPosition.x+u.x,craft.vPosition.y+u.y,craft.vPosition.x+u.x+v.x,craft.vPosition.y+u.y+v.y,1,RGB(0,0,0));
//appliedforce
v.x=craft.Fa.x*f;
v.y=craft.Fa.y*f;
v=VRotate2D(craft.fOrientation,v);
u.x=craft.Pa.x;
u.y=craft.Pa.y;
u=VRotate2D(craft.fOrientation,u);
DrawLine(craft.vPosition.x+u.x,craft.vPosition.y+u.y,craft.vPosition.x+u.x+v.x,craft.vPosition.y+u.y+v.y,1,RGB(0,0,0));
}
voidDoCraft2Chase(void)
Vectoru,v;
boolp=false;bools=false;
u=VRotate2D(-Craft2.fOrientation,(Craftl.vPosition-Craft2.vPosition));u.Normalize();
Target=Craft1.vPosition;
if(u.x<-_TOL)p=true;
elseif(u.x>_TOL)s=true;
Craft2.SetThrusters(p,s);
}
voidDoCraft2Evade(void)
{
Vectoru,v;
boolp=false;
bools=false;
u=VRotate2D(-Craft2.fOrientation,(Craft1.vPosition-Craft2.vPosition));u.Normalize();
if(u.x>0)p=true;
elseif(u.x<0)s=true;
Craft2.SetThrusters(p,s);
Target=Craft2.vPosition;}
voidDoCraft2lntercept(void){
Vector
u1,u2,u;
Vector
s1,s2;
Vector
Vr;
double
t1,t2;
Vector
s1unit,s2unit;
boolp=false;bools=false;
Vr=Craftl.vVelocity-Craft2.vVelocity;
s2=GetVelocitylntersection()-Craft2.vPosition;s2unit=s2;
s2unit.Normalize();
u2=VRotate2D(-Craft2.fOrientation,s2);
t2=s2.Magnitude()/(Vr*s2unit);
s1=Craft1.vPosition-Craft2.vPosition;s1unit=s1;
s1unit.Normalize();
u1=VRotate2D(-Craft2.fOrientation,s1);t1=s1.Magnitude()/(Vr*s1unit);
if(t1<0.0)
{
u=u2;
Target=s2+Craft2.vPosition;}elseif(t2<0.0){
u=u1;
Target=s1+Craft2.vPosition;
}elseif(t2{
u=u2;
Target=s2+Craft2.vPosition;}else{
u=u1;
Target=s1+Craft2.vPosition;}u.Normalize();
if(u.x<-_TOL)p=true;
elseif(u.x>_TOL)s=true;
Craft2.SetThrusters(p,s);
}
voidDoCraft2lnterceptAlt(void)
{
Vectoru;
Vector
si,s2,s12;
bool
p=false;
bool
s=false;
double
tClose;
Vector
Vr12;
double
vr;
//turnaroundifwegetaheadoftheprey...s12=Craft1.vPosition-Craft2.vPosition;u=VRotate2D(-Craft2.fOrientation,s12);if(u.y<-_TOL)
{
〃if(GetRandomNumber(0,10,true)<5)p=true;
//else
//s=true;
Craft2.SetThrusters(p,s);
Target=Craft2.vPosition;return;
}
Vr12=Craft1.vVelocity-Craft2.vVelocity;//closingvelocitys12=Craft1.vPosition-Craft2.vPosition;//rangetoclosetClose=s12.Magnitude()/Vr12.Magnitude();//timetoclose
s1=Craft1.vPosition+(Craft1.vVelocity*tClose);Target=s1;
s2=si-Craft2.vPosition;
u=VRotate2D(-Craft2.fOrientation,s2);
u.Normalize();if(u.x<-_TOL)
p=true;
elseif(u.x>_TOL)s=true;
Craft2.SetThrusters(p,s);
}
voidDoAttractCraft2(void)
{
//ApplyLenard-JonespotentialforcetoCraft2Vectorr=Craft2.vPosition-Craft1.vPosition;Vectoru=r;
u.Normalize();
doubleU,A,B,n,m,d;
A=2000;
B=4000;
n=2;
m=3;
d=r.Magnitude()/Craft2.fLength;U=-A/pow(d,n)+B/pow(d,m);
Craft2.Fa=VRotate2D(-Craft2.fOrientation,U*u);
Craft2.Pa.x=0;
Craft2.Pa.y=Craft2.fLength/