[AI-Steering编程]十.群落行为

十.群落行为

看大雁,快看快看,一会排成”S”形,一会儿排成”B”形,多么可爱啊!!
哈哈,开个玩笑了,本章的群落行为还没有那么智能,能排出”SB”来,讲到这里我就不用再解释群落行为了吧!
10.1 目的
实现像大雁那样的群落行为
10.2 实现
l计算平均位置averagePosition和平均速度averageVelocity
lSeek平均位置和平均速度,别太远也别太近
10.3 讨论
l计算平均位置averagePosition和平均速度averageVelocity
在一个群落整体中行走,呀,离A有点远了,赶紧追上,有离B有点远,再往B那么去一点,恩?离C怎么那么近啊,不行得离C远点,要不就撞到C了…我要走多快呢?按照A的速度走吧,不行,A走的太快了,会把C落下的,按照B的速度走吧也不行,会被C追上的…
通过上面的思路,大概就应该知道机车改怎么走了;
机车要在A,B,C的平均位置上,这样既不会离A太远,也不会离C太近;那么速度呢,按照A,B,C的平均速度行驶.这样既不会被落下,也不会被追上.
好了,我们来看看代码是怎么实现的吧,首先是定义平均变量:

                            //平均速度
                            var averageVelocity:Vector2D = _velocity.clone();
                            //平均位置
                            var averagePosition:Vector2D = new Vector2D();
                            //机车能看到的对象个数


然后是计算平均变量:

                            //收集平均变量
                            averageVelocity=averageVelocity.add(vehicle.velocity);
                            averagePosition=averagePosition.add(vehicle.position);


Seek平均位置和平均速度,别太远也别太近
平均位置和平均速度定下来了,那么就像这个位置以平均速度出发吧.

                            if (inSightCount > 0) {
                                     //将平均变量平均一下
                                     averageVelocity = averageVelocity.divide(inSightCount);
                                     averagePosition = averagePosition.divide(inSightCount);
                                     seek(averagePosition);
                                     _steerForce.add(averageVelocity.substract(_velocity));
                            }


但是也不能太近,否则还是会相撞的:

         if (tooClose(dist)) {
         //如果离C太近了,就躲开
         flee(vehicle.position);
         }


好了讲完了,简单不?比< AdvancED_ActionScript_Animation >里要简单吧,哈哈,傻瓜式理解,好了,看看学习完本章后代码的变化吧,首先是flock方法:

                   public function flock(vehicles:Array):void {
                            //平均速度
                            var averageVelocity:Vector2D = _velocity.clone();
                            //平均位置
                            var averagePosition:Vector2D = new Vector2D();
                            //机车能看到的对象个数
                            var inSightCount:int = 0;
                            
                            for (var i:int = 0; i < vehicles.length; i++) {
                                     //vehicles数组里存放的是所有的机车
                                     var vehicle:Vehicle = vehicles[i] as Vehicle;
                                     //与当前机车对象的距离
                                     var dist:Number = _position.dist(vehicle.position);
                                     
                                     if (vehicle != this && inSight(vehicle, dist)) {//非本车的机车如果在本车的视野之内,继续往下运行
                                               //收集平均变量
                                               averageVelocity=averageVelocity.add(vehicle.velocity);
                                               averagePosition=averagePosition.add(vehicle.position);
                                               
                                               if (tooClose(dist)) {
                                                        //如果离C太近了,就躲开
                                                        flee(vehicle.position);
                                               }
                                               inSightCount++;
                                     }
                            }
                            if (inSightCount > 0) {
                                     //将平均变量平均一下
                                     averageVelocity = averageVelocity.divide(inSightCount);
                                     averagePosition = averagePosition.divide(inSightCount);
                                     seek(averagePosition);
                                     _steerForce.add(averageVelocity.substract(_velocity));
                            }
                   }


下面的inSight和tooClose是附带的,我不解释大家应该也能看懂吧!嘿嘿,我又再偷懒了.

                   public function inSight(vehicle:Vehicle, distance:Number):Boolean {
                            //不再视野范围内,返回FALSE
                            if (distance > _inSightDist) return false;
                            //这个算法如果看过wander一章,理解起来就不难了,这里就不再重复了
                            var heading:Vector2D = _velocity.clone().normalize();
                            var difference:Vector2D = vehicle.position.substract(_position);
                            var dotProd:Number = difference.dotProd(heading);
                            if (dotProd < 0) return false;
                            return true;
                   }
                   public function tooClose(distance:Number):Boolean {
                            //是否太近
                            return distance < _tooCloseDist;
                   }
         }


文档Flock类:

package 
{
         import flash.display.Graphics;
         import flash.display.Sprite;
         import flash.events.Event;
         import flash.events.MouseEvent;
         import flash.text.TextField;
        
         import ladeng6666.steering.Vector2D;
         import ladeng6666.steering.Vehicle;
         import ladeng6666.steering.TargetObj;
        
         public class Flock extends Sprite
         {
                   private var vehicleNum:int = 30;
                   private var vehicleList:Array;
                 
                   public function Flock()
                   {
                            vehicleList = new Array();
                            for (var i:Number = 0; i < vehicleNum; i++) {
                                     var vehicle:Vehicle = new Vehicle(0xffffff * Math.random());
                                     vehicle.position = new Vector2D(stage.stageWidth * Math.random() , stage.stageHeight*Math.random());
                                     vehicle.velocity = new Vector2D(Math.random() * 20-10, Math.random() * 20-10);
                                     vehicle.edgeBehavior = Vehicle.BOUNCE;
                                     vehicleList.push(vehicle);
                                     addChild(vehicle);
                            }
                           
                            conifgEvent();
                   }
                   private function conifgEvent():void {
                            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
                   }
                   //按照帧频随速度更新机车的位置
                   private function enterFrameHandler(e:Event):void {
                            for (var j:Number = 0; j < vehicleNum; j++) {
                                     vehicleList[j].flock(vehicleList);
                                     vehicleList[j].update();
                            }
                   }
         }
}
 


本章源代码:
chapter10.rar (53.71 KB)



好了,大结局了, 终于写完了,可累死我了,不过还是收获很多的,关于游戏中的人工智能,到这里只是一个入门,网上还有大量的资料可以学习,这里给大家推荐一本书< Artificial Intelligence For Games >by Elsevier,书里的代码使用C++写的,不过文章写的很详细,注释也很通俗易懂, 有兴趣的同学可以学习一下,书的下载链接如下:
http://www.brsbox.com/filebox/down/fc/1ad7dc9f53f48c883156af245e18df5f

好了,就到这里了,我是拉登,英文名ladeng6666,专注AS3游戏和视觉编,程欢迎大家来我的博客浇水, 也可以加入我的群进行交流!算是打广告了,咱也得瑟一把 ,嘿嘿!


博客 : http://blog.sina.com.cn/ladeng6666
Q群: 43806024

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值