行为

来源:互联网 发布:工资计算软件 免费 编辑:程序博客网 时间:2024/04/28 17:29





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

                   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;                   }






0 0
原创粉丝点击