行为
来源:互联网 发布:工资计算软件 免费 编辑:程序博客网 时间: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就是机车的position与target的position的矢量差(绿色),当然desiredVelocity不会是整个绿色线段的长度大小,否则机车就直接跳到target处了,所以我们把desiredVelocity限制在最大速度maxSpeed以内,也就是以最大的速度向目标行驶,转向力force是desiredVelocity与velocity的矢量差
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; }
- 行为
- 行为
- DataRow行为
- 使用行为
- WebService行为
- 思考+行为
- 行为模式
- 盗窃行为??
- 行为模式
- 代码行为
- UNDO 行为
- 磁盘行为
- 隔离行为
- 未定义行为
- 行为编辑器
- 行为控制
- 未定义行为
- 手势行为
- 安卓训练-开始-开发你的第一个应用
- iOS 各种传值方式
- ArcCatalog发布地图服务
- win7 64位操作系统tiny6410开发DMW USB下载驱动安装个人记录
- 风险风险之深入分析协方差意义与算法
- 行为
- (eclipse使用技巧)切换项目里面的包的显示样式
- Android--使用动态加载框架DL进行插件化开发
- 有关eclipse的介绍
- ZooKeeper安装部署
- 在open函数中将文件私有数据指向设备结构体
- linux 系统配置java环境变量
- ps aux各参数意义
- sqlserver技术内幕<二> 表运算符之apply