十.群落行为
看大雁,快看快看,一会排成”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)
好了,大结局了,
![](http://bbs.9ria.com/images/smilies/yocimonkey/123_093.gif)
http://www.brsbox.com/filebox/down/fc/1ad7dc9f53f48c883156af245e18df5f
好了,就到这里了,我是拉登,英文名ladeng6666,专注AS3游戏和视觉编,程欢迎大家来我的博客浇水, 也可以加入我的群进行交流!算是打广告了,咱也得瑟一把
![](http://bbs.9ria.com/images/smilies/yocimonkey/123_125.gif)
博客 : http://blog.sina.com.cn/ladeng6666
Q群: 43806024