游戏底层逻辑,运动&&寻路(五)

终于要开始激动人心的Flocking集群行为了,不过在讨论集群行为之前,我们要先来探讨一些很有意思的哲学逻辑。

Emergent Behaviors涌现行为

这里先安利一本神作《失控》,看了这本书,我相信对整个人工智能,社会学,人类学和分布式理论都会有极大地认知提高。

我们先讲一讲蜂巢现象:

一群蜜蜂,他们并没有中枢参与控制,蜜蜂仅仅能做一些基本行为,例如:四处乱飞,找到视野里的花朵,接收一定范围内其他蜜蜂留下的信息素。
但是我们最后看到的却是:一群蜜蜂在空中跳舞(据说能告诉其他蜜蜂花朵的方向),然后蜜蜂找到了很大范围内的所有花朵,并一起完成了很多复杂的行为。

我们再来举个栗子:

在演唱会或者足球场上我们可能会看到“人浪”行为,人浪没有组织者,人们只是看到上附近人的行为,但你远处看到的确实很完美的浪潮。

涌现讲的是这样一种情况:在一个复杂系统中,我们不用进行中枢控制,每个基本的单元拥有基本功能,就能产生出很复杂且强大的集群现象。

  • 涌现行为不受个体影响,就是说某些个体的错误不会影响系统的最终结果,这一点和精确控制,一环接一环的中心化系统有很大差异性。

  • 涌现现象具有不可预测性,所以唯一的研究方法就是模拟,有很多科学实验证明了只需要模拟个体的基本行为,就可以模拟整个集群的系统行为。

我们在探讨集群算法时,也只会关注个体行为的模拟,不会对整个群体进行中枢控制。

Element个体行为

12、Separation保持一定距离

该行为是这样一种规则:
- 在一定范围内(我们认为是视野范围),个体会尽量与neighbor邻居保持远离状态。
由于有很多邻居,所以该控制力是一个平均力:

Vec2 SteeringBehaviors::separation(const std::vector<Vehicle*> neighbors)
{
    Vec2 steeringForce = Point::ZERO;

    for_each(neighbors.cbegin(), neighbors.cend(), [this,&steeringForce](Vehicle* neighbor){
        if (neighbor != _evadingTarget)
        {
            Vec2 awayFromNeighbor = _ownerVehicle->position() - neighbor->position();

            /*steeringForce += awayFromNeighbor.getNormalized() / awayFromNeighbor.getLength()*normalSeparationForce;*/
            steeringForce += awayFromNeighbor / awayFromNeighbor.getLengthSq()*normalSeparationForce;
        }
    });
    return steeringForce;
}

很简单是吧,没错,集群行为就是要简单的个体。

13、Alignment保持相同方向

之前是返回平均斥力,这次是平均方向:

Vec2 SteeringBehaviors::alignment(const std::vector<Vehicle*> neighbors)
{
    Vec2 averageHeading = Vec2::ZERO;

    for_each(neighbors.cbegin(), neighbors.cend(), [this,&averageHeading](Vehicle* neighbor){
        if (neighbor != _evadingTarget)
        {
            averageHeading += neighbor->heading();
        }
    });
    if (neighbors.size() != 0)
    {
        averageHeading = averageHeading / (double)neighbors.size();
    }

    return (averageHeading - _ownerVehicle->heading());
}

14、Cohesion聚集

这次是返回平均吸引力:

Vec2 SteeringBehaviors::cohesion(const std::vector<Vehicle*> neighbors)
{
    //we could consider the weight each neighbor owned
    Vec2 averagePosition;
    for_each(neighbors.cbegin(), neighbors.cend(), [this, &averagePosition](Vehicle* neighbor){
        if (neighbor != _evadingTarget)
        {
            averagePosition += neighbor->position();
        }
    });

    if (neighbors.size() != 0)
    {
        averagePosition = averagePosition / (double)neighbors.size();
    }

    return seek(averagePosition);
}

注意,此处的平均并非是对所有物体的中枢控制,而是个体在视野范围内对自我位置的判断,就像我们人类能判断一处挤满人的操场上哪里有空位一样。

集群行为非常简单,但是组合起来却非常有意思,复杂,且逼真,你还可以模拟一些其他的基本行为,来实现其他的复杂系统,我们下一次再来将组合行为。

准备写一个有关游戏底层算法,物理算法,以及AI(重点是机器学习在游戏中的应用)的长篇博客,欢迎大家指正交流╰( ̄▽ ̄)╯

你可能感兴趣的:(游戏,集群,人工智能)