上篇文章我们解释了几种基本的控制力,今天我们会讨论几种较为复杂的行为,涉及了碰撞,以及辅助图形进行运动控制。
7、Wander徘徊(巡逻)
徘徊(四处巡逻)是一种很常见的行为,但是要得到smoothly平滑的转向行为,并不是特别容易,这里有一种借用辅助圆实现的平滑移动。
如图,我们在物体前面构造了一个辅助圆,我们控制目标点,从而用seek方法控制运动行为,如果我们让目标点在圆周上运动,就可以产生一个力,他有如下属性:
- 一定向前(分力向物体的当前运动方向)
- 单帧转角范围为切线与x轴的夹角
- 大小为圆与x轴交点的范围
这样我们就可以控制辅助圆的相对位置来控制wander行为,比如我们想要总的运动轨迹为一个不规则的圆,我们可以将圆放到第一象限(逆时针旋转)或者第四象限(顺时针旋转),圆的位置为max_double,则进行直线运动。
接下来我们只需要写一个关于目标点在圆周上随机移动的方法就行(这里可以随便写,比如用三角函数),这里有一种实现:
- 目标点一定范围内随机移动
- 将其投影到圆上(获取其单位向量)
我们首先为SteeringBehaviors类添加新的成员变量:
//wander attributes
Vec2 _wanderTarget;//目标点
double _wanderRadius;//辅助圆半径
double _wanderDistance;//辅助圆离物体的距离
double _wanderJitter;//给目标点的随机位置一个限制值,这是为了减少速度变化过快产生的抖动
接下来是wander函数的实现:
Vec2 SteeringBehaviors::wander()
{
//random move
_wanderTarget = Vec2(Random::Rand(-1, 1)*_wanderJitter,
Random::Rand(-1, 1)*_wanderJitter);
//project it onto the circle
_wanderTarget = _wanderTarget.getNormalized()*_wanderRadius;
//add jitter
Vec2 targe