五.追捕行为 追捕行为实际是寻找行为的一种(这句话好耳熟啊,哈哈,上一章里就说过了).
5.1 目的
计算追逐对象的未来目标,实现有效的追捕
5.2 实现
计算目标的”未来位置”,机车先发制人,在”未来目标”等着目标.
5.3 讨论
关于追捕与寻找的区别 ,看一下示例 ”5-1-Compare.swf ”就明白了
5-1-Compare.swf (4.23 KB)
如上图所示,白色机车以恒定的速度向右移动,红色的机车以seek的方式”寻找”机车,其中红色的虚线是其路线,而蓝色的机车是以pursue的方式”追捕”机车,蓝色的虚线是其路线. 这样再解释起来就简单多了.
要想追上你的目标,有两种方法,一是你的速度比目标快,二是在目标前面等着他.
对于第一种情况,在我们的代码 中,所有机车的最大速度都一样,都是maxSpeed.所以这个方法不是我们本节讨论的内容.
再看第二种方法,在目标的前面等着它,什么意思?就像我的示例” 5-1-Compare.swf”里一样,白色机车以恒定的速度像右移动.要想在它前面等着就要知道这个”未来目标”地方在哪里,我们把这个”未来目标”定义为predictedTarget;
如上图所示,predictedTarget应该等于机车的位置加上distance,这个没有疑问吧.即vech.position.add(distance.position);所以下面的问题就是这个distance应该怎么算呢?
距离肯定就是速度乘以时间了,白色机车的速度是vech.velocity,这是一个已知量,不用担心,那么问题的最后就是计算这个时间了.
想一想,在我们追到目标之前,目标有多长的时间可以逃跑?就是我们追他的这段时间嘛lookAheadTime,这个时间就是我们与目标之间的距离除以我们的宿舍啊!转换到机车来想就是:
lookAheadTime = pursuer.position.dist(vech.position)/maxSpeed;
你有可能就问了:”pursuer与白色机车vech的距离不是一直在变化中的啊,那怎么算啊?”哈哈,刚好,我的lookAheadTime也是及时更新的,看下下面的代码你就知道了!
public function pursue(target:Vehicle):void {
var lookAheadTime:Number = target.position.dist(_position) / _maxSpeed;
//计算此时追上目标的预计时间,即lookAheadTime.
var predictedTarget:Vector2D = target.position.add(target.velocity.multiply(lookAheadTime));
//在这段时间内,目标以现在的速度,预计会到达的位置,即"未来目标"
seek(predictedTarget);
//寻找这个"未来目标"
}
在下面的示例 ” 5-1-Pursue.swf” 中 , 我创建了三个对象 , 白色的 vech, 红色的 seeker 和蓝色的 pursuer. 他们之间关系 ,vech.flee(seeker),seeker.seek(vech),pursuer.pursue(vech).
5-1-Pursue.swf (4.22 KB)
文档 Pursue 类如下 , 我就不做过多的解释了 :
package
{
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.Event;
import ladeng6666.steering.Vector2D;
import ladeng6666.steering.Vehicle;
import ladeng6666.steering.TargetObj;
public class Pursue extends Sprite
{
private var vech:Vehicle; //机车实例
private var seeker:Vehicle; //添加红色的机车,来seek白色的机车
private var pursuer:Vehicle //添加蓝色的的机车,来pursue白色的机车
public function Pursue()
{
vech = new Vehicle();
vech.position = new Vector2D(100, 200);
vech.edgeBehavior = Vehicle.BOUNCE;
seeker = new Vehicle(0xff0000);
seeker.edgeBehavior = Vehicle.BOUNCE;
pursuer = new Vehicle(0x0000ff);
addChild(vech);
addChild(seeker);
addChild(pursuer);
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
//按照帧频随速度更新机车的位置
private function enterFrameHandler(e:Event):void {
vech.flee(seeker.position);
vech.update();
seeker.seek(vech.position);
seeker.update();
pursuer.pursue(vech);
pursuer.update();
}
}
}
本章的源码 如下:
chapter5.rar (19.76 KB)