skip to main |skip to sidebar

2007-12-23

[AI]高级人工智能(1)——回避障碍物

效果:

在连续动作环境(不是Tile Based 环境)中,回避障碍物是很复杂。因为不像 Tile Based 环境,"点"在理论上有无限多,很难准确地判断。

但不是没有办法的,回避障碍物可以使用 Lenard-Jones potential 函数

它的方程为:

[U = -A/pow(r,n) + B/pow(r,m)]

n、m 为不同常量时的曲线为:

[Graph]

Lenard-Jones potential 函数是物理中的一个函数,他表示分子间的引力与斥力的势能。U 为原子间的势能,它与原子间的距离 r 成反比。AB 就像 mn 一样,是常量,其中 -A/pow(r,n) 表示引力部分,B/pow(r,m) 表示斥力部分。在 r 很小时会产生斥力,当 r 很大时会产生引力。参数 mn 控制曲线的斜率,AB 控制力的强度。

如果在游戏中,把障碍物与人物看成原子的话,就可以使用 Lenard-Jones potential 函数来实现回避障碍物。当十分接近时,会产生很大的斥力,再把 A 设为0,使引力始终为0这样回避障碍物就实现了。

核心代码:

var vo:Vector2d = new Vector2d();//障碍物的坐标
var vp:Vector2d = new Vector2d().reset(player);//人物的坐标
var r:Vector2d = new Vector2d();//人物与障碍物的差
var u:Vector2d = new Vector2d();
var dv:Vector2d = new Vector2d();
var B:Number = 20;//函数的 B 常量
for each(var i:Obstacle in obstaclesList) {
vo.reset(i);//vo = (i.x, i.y)
r.sub(vp, vo);//r = vp - vo
if(r.length >40) {//当 距离>40 时不判断,直接返回。
continue;
}
u.reset(r);//u = r
u.normalize();//把 u 设为单位向量
var d:Number = r.length/i.r;//d = |r| / i.r (i.r为障碍物的半径)
var U:Number = B/Math.pow(d,2.5);//A = 0,n = 1,m = 2.5
u.scaleTo(U);//u *= U
dv.add(player.v, u);//dv = player.v + u (player.v为人物的速度)
dv.length = 5//|dv| = 5
player.v.reset(dv);//player.v = dv
}

源码下载:AI_Avoid.rar

参考文献:AI for Game Developers

[AI for Game Developers]

没有评论: