行为





看图说事: feel 和seek 唯一的不同就是 就是force 的方向不一样,seek force的方向是朝向目标,feel则相反。

注意看速度和转向力的矢量叠加,叠加后加载postion上,这就是当前智能体的位置。

                   public function update():void {
                            velocity = _velocity.add(_steerForce);                //速度与转向力的矢量叠加
                            _position = _position.add(_velocity);                 //位置与速度的矢量叠加
                            
                            this.x = _position.x;
                            this.y = _position.y;
                            //判断并设置边缘行为
                            if (_edgeBehavior == "bounce") {
                                     bounce();
                            }else if (_edgeBehavior == "wrap") {
                                     wrap();
                            }
                            this.rotation = _velocity.angle * 180 / Math.PI;
                   }


------------------------------------------------------------------------------------




假设上图的圆圈处是我们的target位置,那么desiredVelocity就是机车的positiontargetposition的矢量差(绿色),当然desiredVelocity不会是整个绿色线段的长度大小,否则机车就直接跳到target处了,所以我们把desiredVelocity限制在最大速度maxSpeed以内,也就是以最大的速度向目标行驶,转向力forcedesiredVelocityvelocity的矢量差

Vector2D SteeringBehavior::Seek(Vector2D TargetPos)
{
	//预期的速度,理想化情况下到达目标位置所需要的速度。它是从智能体到目标的向量,大小为智能体的当前最大速度。
  Vector2D DesiredVelocity = Vec2DNormalize(TargetPos - m_pVehicle->Pos())
                            * m_pVehicle->MaxSpeed();

  //预期速度 - 当前速度 = 操控力 见图3-2 P68
  return (DesiredVelocity - m_pVehicle->Velocity());
}

例子效果参见

http://bbs.9ria.com/forum.php?mod=viewthread&tid=41805

2_2.swf


Vector2D SteeringBehavior::Flee(Vector2D TargetPos)
{

  Vector2D DesiredVelocity = Vec2DNormalize(m_pVehicle->Pos() - TargetPos) 
                            * m_pVehicle->MaxSpeed();

  return (DesiredVelocity - m_pVehicle->Velocity());
}

随转向力转向,实现避开行为
寻找行为是把机车向target,避开行为则是把机车往target外推,所以把add(force)改成substract(force)即可:

以下是AS 代码

和上面的C++代码意思是一样的。

                   public function flee(target:Vector2D):void {
                            var desiredVelocity:Vector2D = target.substract(_position);  
                            //计算desiredVelocity
                            desiredVelocity.normalize();            
                                                        
                            //将desiredVelocity单位化
                            desiredVelocity = desiredVelocity.multiply(_maxSpeed);               
                            //desiredVelociy乘以最大速度maxSpeed,最大速度向目标前进
                            
                            var force:Vector2D = desiredVelocity.substract(_velocity);
                            //计算转向力
                            steerForce = _steerForce. substract (force);
                            //将计算出来的转向力与原转向力做矢量差
                   }


参见例子:feel.swf





















注意:

(1)现实中不管是什么车总有它的最大的速度,当速度达到这个最大值后,将以最大值作匀速运动,所以我们也对velocity作一下限制.  ————这就是maxSpeed 的作用

(2)转向力相对于质量的处理,从相对的角度上来讲,同样大小的力作用到质量大的机车上时,我们把质量缩小比例到小质量,转向力也等比的缩小,这样我们把质量等同后,质量大的机车受到的转向力相对就会小,所以我们将转向力除以质量,来处理质量与转向力之间的关系,steerForce方法变更如下:

                public function set steerForce(value:Vector2D):void {
                        _steerForce = value.divide(_mass);
                }

(3) 想为什么没有转向动作呢 ? 机车转的太快 , , 转的太快就意味着转向力太大 , 自己观察你会发现 , 红色的转向力有时候特别长 , 也就是转向力特别大 , 实际现实中 , 你转方向盘的劲儿再大 , 也不可能一下子把车头调过来 , 是吧 !^_^! 所以我们要给转向力加一个最大值 , 并在 steerForce setter 方法中用最大值加以限制 :

                   private var _maxForce:Number = 1;      //机车的最大转向力;

                   public function set steerForce(value:Vector2D):void {
                            value.truncate(_maxForce);                    //限制转向力的最大值,因为"方向盘转的角度有限"
                            _steerForce = value.divide(_mass);           //大质量的机车转弯比较慢
                   }
这样转向力有了限制 , 机车无法在一次运算后 瞄准 ”target, 我们就能看出转向的动作来了

(4)当机车行驶到边缘时,如果不冲出舞台,那么会有两种边缘行为edgeBehavior:折返和卷屏.我们先给这个边缘行为进行定义:

然后定义两种边缘行为:

                   private function bounce():void {
                            if (stage == null) return;
                            
                            if (_position.x < 0) {
                                     _position.x = 0;
                                     _velocity.x *= -1;
                            }else if (_position.x > stage.stageWidth) {
                                     _position.x = stage.stageWidth;
                                     _velocity.x *= -1;
                            }
                            if (_position.y < 0) {
                                     _position.y = 0;
                                     _velocity.y *= -1;
                            }else if (_position.y > stage.stageHeight) {
                                     _position.y = stage.stageHeight;
                                     _velocity.y *= -1;
                            }
                   }
                   private function wrap():void {
                            if (stage == null) return;
                            if (_position.x < 0) _position.x = stage.stageWidth;
                            if (_position.x > stage.stageWidth) _position.x = 0;
                            if (_position.y < 0) _position.y = stage.stageHeight;
                            if (_position.y > stage.stageHeight) _position.y = 0;
                   }






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值