首页 > 代码库 > Understanding Steering Behaviors:Flee and Arrival(行为控制-逃离和抵达)

Understanding Steering Behaviors:Flee and Arrival(行为控制-逃离和抵达)

原文链接:http://gamedevelopment.tutsplus.com/tutorials/understanding-steering-behaviors-flee-and-arrival--gamedev-1303


跑开

在前面介绍的寻找行为中,我们介绍了一种基于两个向量力来将人物推向目标的行为方式:预期速度和控制力

desired_velocity = normalize(target - position) * max_velocity ;

steering = desired_velocity - velocity ;

在上面说的desired_velocity是从人物直接指向目标的。我们只要简单的将目标点减去人物的点就能够得到这个速度。

而在本节中,同样的,我们也需要使用这样的两个力,但是,我们却是使用这两个力来避免物体移动到目标那里去。

我们现在计算新的desired_velocity,这个速度想在用人物的位置减去目标的位置,这样得到的desired_velocity方向就和上面介绍的行为方式的方向是相反的


我们同样的来用代码来阐释这个概念:

desired_velocity = normalize(position - target) * max_velocity

steering = desired_velocity - velocity


上面计算出来的desired_velocity表示了最容易逃离的路线。而产生的steering控制力将会使的物体丢弃原有的移动路径,而迫使它向desired_velocity靠近。

我们可以将逃离行为和寻找行为联系在一起:

flee_desired_velocity = -seek_desired_velocity

换句话说,一个向量是另外一个向量的反向向量。


增加逃离力

当我们计算出来了逃离的力之后,我们就必须将这个力添加到人物的速度向量上面去。由于这个力是将物体推向目标相反的方向上去,所以,每一帧物体都会向逃离目标的方向去移动,自然而然就产生了一条逃离路径了。

如何增加逃离力,和前面介绍的seek行为是一样的累积方法。

上面的算法是一直的逃离,我们可以添加一个熟悉来控制,如果距离目标有一段距离之后就不再进行逃离。


抵达

寻找行为使的物体向一个指定的目标移动。当到达这个目标之后,物体会在目标附近来回不断的乱动,也就是说会穿过目标地点。而抵达行为就是控制人物不要穿过这个目标点,在当人物慢慢的接近目标点的时候,速度会慢慢的下降,直到最后在目的地点停止下来。


这个行为由两个部分控制。当人物远离目标地点的时候,就像原来的seek行为一样。


当人物距离目标地点很近的时候,在减速区域的时候,我们就慢慢的让人物减速下来:

当人物进入这个圆圈的时候,它就会慢慢的减速下来。


减速

当人物进入了减速区域的时候,它的速度就会线性的慢慢的减下来。这样的效果可以通过简单的增加一个新的控制力到人物的速度向量上来就可以做到。当这个方法最终增加的速度变成0的时候,那么就表示将没有任何的速度添加到这个人物的位置上:

<span style="font-family:Microsoft YaHei;">// If (velocity + steering) equals zero, then there is no movement
velocity = truncate(velocity + steering, max_speed)
position = position + velocity
 
function truncate(vector:Vector3D, max:Number) :void {
    var i :Number;
    i = max / vector.length;
    i = i < 1.0 ? i : 1.0;
    vector.scaleBy(i);
}</span>
为了保证人物会慢慢的减速下来,我们不能立即的将人物的速度变成0.我们可以通过人物现在距离目标的地点和减速区域的半径来判断应该对人物现有的速度做多少的变化,从而能够很平滑的实现减速效果:

<span style="font-family:Microsoft YaHei;">// Calculate the desired velocity
desired_velocity = position - target
distance = length(desired_velocity)
 
// Check the distance to detect whether the character
// is inside the slowing area
if (distance < slowingRadius) {
    // Inside the slowing area
    desired_velocity = normalize(desired_velocity) * max_velocity * (distance / slowingRadius)
} else {
    // Outside the slowing area.
    desired_velocity = normalize(desired_velocity) * max_velocity
}
 
// Set the steering based on this
steering = desired_velocity - velocity</span>

如果人物距离目标地点的距离远远的大于slowRadious,那么就意味着这个人物距离目标地点非常的远,所以,我们只要简单的使用寻找行为来寻找目标点即可,并且保持速度不变。


如果他们之间的距离比slowRadious要小的时候,这就意味着,人物抵达了减速区域,所以现在我们需要将它进行减速。


distanc/slowRadious 的值在减速区域中将会从0到1不等。这样的线性变化就会使得人物的移动速度慢慢的呈线性减速下来。

正如前面介绍的那样,这个移动方式将会像下面这样进行表示:

<span style="font-family:Microsoft YaHei;">steering = desired_velocity - velocity
velocity = truncate (velocity + steering , max_speed)
position = position + velocity</span>


如果预期速度最后降低到0的时候,那么控制力的大小就会变成-velocity。所以,把这个行为力加到速度上的时候,就会导致人物最终移动的速度变成了0,停止下来了。



结论

逃离行为使的人物远离目标地点,而抵达行为使得人物在抵达地点时停止下来。这样行为都是可以在一定程度上进行组合从而做成类似于跟随,逃离这样的行为。