[AI-Steering编程]四.到达行为

四.到达行为 4.1 目的
到达行为是寻找行为的特殊情况,靠近目标后,减速并停止在目标位置上
4.2 实现
l寻找目标
l判断与目标的距离是否在arrivalThreshold内,如果在arrivalThreshold内,减速直到停在目标位置
4.3 讨论
在” 2-1-force2.swf ”的示例中,停止移动鼠标 细细观看,你会发现机车一直在鼠标的前后徘徊,这是为什么呢?回头看看我们的算法 可以找到答案.机车想目标的移动一直都是以最大的速度maxSpeed进行移动的,所以,跑过头之后,有以最大的速度再跑回来,又过头,然后又以最大的的速度跑回来,又过头….
当机车在靠近目标时,减速移动,并最后停在目标的位置上,这就是到达行为.
l寻找目标
向seek方法中对目标寻找的算法还是不能少的,但是对速度大小设置上,判断不同的情况,进行不同的设置.

                   public function arrive(target:Vector2D):void {
                            var desiredVelocity:Vector2D = target.substract(_position); 
                            //计算desiredVelocity
                            desiredVelocity.normalize();                                                                   
                            //将desiredVelocity单位化
                            //desiredVelocity = desiredVelocity.multiply(_maxSpeed);           
                            //desiredVelociy乘以最大速度maxSpeed,最大速度向目标前进,这是seeking的算法,在arrive中我们不会直接讲速度设置为大,为了能进行判断,我们增加了一个arrivalThreshold属性,具体请看下一节.
                           
                            var force:Vector2D = desiredVelocity.substract(_velocity);
                            //计算转向力
                            steerForce = _steerForce.add(force);
                            //讲计算出来的转向力与原转向力叠加
                   }

l判断与目标的距离是否在arrivalThreshold内
人的视力范围总是有限的,晴天是100米,雾天可能就是40米,当在我的可是范围内出现其他的汽车时,我们肯定会减速慢行,然后在力其他汽车3~4远的地方停下(干嘛要停下?绕过去就好了!嘿嘿,”绕过去”是后面章节的内容,本节只能停下来).在vehicle类中,我们也给机车增加了”可是范围”_arrivalThreshold属性,来让机车”看到”目标后减速慢行:

                   private var _arrivalThreshold:Number = 20;  //机车的视力范围
 
                   public function set arrivalThreshold(value:Number):void {
                            _arrivalThreshold = value;
                   }
                   public function get arrivalThreshold():Number {
                            return _arrivalThreshold;
                   }

接下来就是当机车看到目标之后的减速慢行,上一节提到过的.
我们分两种情况,a.目标没有出现在机车”视力范围”内时,机车最大速度想目标行驶,b.目标出现在机车”视力范围”内时,机车的速度等于距离目标与”视力范围”的比率乘以最大速度.具体算法如下:

                   public function arrive(target:Vector2D):void {
                            var desiredVelocity:Vector2D = target.substract(_position); 
                            //计算desiredVelocity
                            desiredVelocity.normalize();
                            //将desiredVelocity单位化
                           
                            var distance:Number = _position.dist(target);
                            //机车与目标的距离
                            if (distance < _arrivalThreshold) {
                                     desiredVelocity = desiredVelocity.multiply(_maxSpeed * distance / _arrivalThreshold);
                                     //机车的速度等于距离目标与”视力范围”的比率乘以最大速度
                            }else {
                                     desiredVelocity = desiredVelocity.multiply(_maxSpeed);             
                                     //desiredVelociy乘以最大速度maxSpeed,最大速度向目标前进
                            }
                           
                            var force:Vector2D = desiredVelocity.substract(_velocity);
                            //计算转向力
                            steerForce = _steerForce.add(force);
                            //讲计算出来的转向力与原转向力叠加
                   }


文档Arrive类,只需要相应的做出一些简单的调整,由seek目标改为arrive目标:

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 Arrive extends Sprite
         {
                   private var vech:Vehicle;                           //机车实例          
                   private var redVech:Vehicle;            //添加红色的机车,来seek白色的机车
                  
                   private var targetObj:TargetObj;       //机车到达的目标
                   public function Arrive()
                   {
                            vech = new Vehicle();
                            vech.position = new Vector2D(100, 200);
                            vech.edgeBehavior = Vehicle.BOUNCE;
                           
                            targetObj = new TargetObj();
                           
                            addChild(vech);
                            addChild(targetObj);
                            targetObj.x = Math.random() * 400;
                            targetObj.y = Math.random() * 400;
                            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
                   }
                   //按照帧频随速度更新机车的位置
                   private function enterFrameHandler(e:Event):void {
                            vech.arrive(targetObj.position);
                            //由seek目标改为arrive目标
                            vech.update();

                            var dis:Vector2D = vech.position.substract(targetObj.position);
                            if (dis.length < 5) {
                                     targetObj.x = Math.random() * stage.stageWidth;
                                     targetObj.y = Math.random() * stage.stageHeight;
                            }
                   }
         }
}


运行上面的结果后 ,可以很明显的看到 ,目标在机车视力范围外时 ,蓝色速度的长度最大 ,目标出现在机车视力范围内时 ,机车的蓝色速度明显有变小 ,如下图 .
4-1-arrive.swf (4.13 KB)

arrive1.jpg arrive2.jpg
下载 (21.47 KB)
2009-12-25 20:18

本章的源码如下:
chapter4.rar (15.05 KB)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值