[AI-Steering编程]七.漫游行为

七.漫游行为
“漫游行为”就像它的名字一样,机车在场景中漫无目的的游走,对于漫游的的解释,我就不掺假了,还是完全套用<AdvancED ActionScript3>中的官方解释:



    漫游是指角色在场景中毫无目的的移动.这通常用来模拟巡视和觅食,也有纯粹是为了漫游而漫游的.
    漫游行为在实现上不像听起来那么容易.简单的使用随机而产生的布朗运动,会让角色感觉像一个神经病的傻瓜.我们需要更自然更平滑的感觉.有个办法,通常设想在角色前方有个圆,然后把圆上任意一点作为目标,每次更新都想这个随机点移动.由于目标点总是落在假象的圆上,所以转向力永远不会一下子就变化很大.可以参照右图加以理解!


漫游.jpg


7.1 目标
如<AdvancED ActionScript3>的描述,实现机车的漫游行为.
7.2 实现
l创建圆
l在圆上添加随机点,引导机车转向
l向圆上的随机点转向
7.3 讨论
l创建圆
像<AdvancED ActionScriopt3>中描述的那样,在机车的正前方添加一个圆.要添加圆,就一定要有圆心,这一点你不会反对吧.这个圆心处在机车的正前方,也就是说要在velocity的延长线上,通过上面的图解也能看的出来,那这个圆心离机车多远呢?我们定义这个距离为_wanderDistance:

                   private var _wanderDistance:Number = 50;             //机车漫游的圆心位置

                   public function set wanderDistance(value):void {
                            _wanderDistance = value;
                   }
                   public function get wanderDistance():Number {
                            return _wanderDistance;
                   }

然后是圆心的计算 :

                            var center:Vector2D = _velocity.clone().normalize().multiply(_wanderDistance);
                            //在机车的正前方_wanderDistance位置,添加圆的圆心

再多啰嗦两句 ,velocity.clone().normalize() 的作用是将 velocity 单位化 , 因为我们要的只是 velocity 的方向 , 然后在velocity 的方向上乘以 _wanderDistance 就是圆心的位置了 ! 另外 , 圆心的位置是实时更新的 , 所以上面的代码在 wander 方法中 , 要和 update 方法一起更新的 .
圆心定下来了 , 下面是圆的半径 :

                   private var _wanderRadius:Number = 30;                         //机车漫游目标的范围

                   public function set wanderRadius(value):void {
                            _wanderRadius = value;
                   }
                   public function get wanderRadius():Number {
                            return _wanderRadius;
                   }

l 在圆上添加随机点 , 引导机车转向
这样 , 图中的那个圆我们就 ” 画出来了 ”, 然后 , 就是在圆上添加随机的点 , 引导机车转向 .
所谓随机是相对于圆心来讲的 . 所以随机点的位置可以用圆心矢量 center 加上偏移矢量 offset, 为了让随机点落在圆上 , 我们就把偏移量 offset 的长度限定为半径 wanderRadius. 然后随机化偏移量 offset 的角度就好了 , 代码如下 :

                            var offset:Vector2D = new Vector2D(0);
                            //随机点与圆心的偏移量
                            offset.length = _wanderRadius;
                            //为是随机点落在圆心上,限定偏移量的长度为_wanderRadius
                            offset.angle = _wanderAngle;
                            //随机偏移的角度
                            _wanderAngle += (Math.random()-0.5);
                            var force:Vector2D = center.add(offset);
                            //圆心矢量加偏移矢量确定随机点,随机点确定后,直接添加随机点方向的转向力.

l 向圆上的随机点转向
随机点确定后 , 直接添加随机点方向的转向力 force, 然后这个转向力 force 与之前的 steerForce 叠加即是新的作用力 :

                            steerForce = _steerForce.add(force);
                            //讲计算出来的转向力与原转向力叠加


讨论完上面的内容后 , 完整的 wander 方法如下 :

                   public function wander():void {
                            var center:Vector2D = _velocity.clone().normalize().multiply(_wanderDistance);
                            //在机车的正前方_wanderDistance位置,添加圆的圆心
                            var offset:Vector2D = new Vector2D(0);
                            //随机点与圆心的偏移量
                            offset.length = _wanderRadius;
                            //为是随机点落在圆心上,限定偏移量的长度为_wanderRadius
                            offset.angle = _wanderAngle;
                            //随机偏移的角度
                            _wanderAngle += (Math.random()-0.5);
                           
                            var force:Vector2D = center.add(offset);
                            //圆心矢量加偏移矢量确定随机点,随机点确定后,直接添加随机点方向的转向力.
                            steerForce = _steerForce.add(force);
                            //讲计算出来的转向力与原转向力叠加
                   }


文档 Wander 类如下 :

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 Wander extends Sprite
         {
                   private var wanderVehicle:Vehicle;                     //漫游机车实例
                  
                   public function Wander()
                   {
                            wanderVehicle = new Vehicle();
                            wanderVehicle.position = new Vector2D(100, 200);
                           
                            addChild(wanderVehicle);
                           
                            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
                   }
                   //按照帧频随速度更新机车的位置
                   private function enterFrameHandler(e:Event):void {
                            wanderVehicle.wander();
                            wanderVehicle.update();
                   }
         }
}


运行结果示例如 ” 7-1-Wander.swf”( 如下右图 ).
7-1-Wander.swf (4.37 KB)

7-2-Wander.swf (4.41 KB)




本章源代码:
chapter7.rar (20.46 KB)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值