Example #1
0
        private void Flock()
        {

            var flockingVector = Vector2.Zero;

            int count = 0;
            Vector2 exclusiveCenter = Vector2.Zero;
            Vector2 separationAccumulator = Vector2.Zero;
            Vector2 alignmentAccumulator = Vector2.Zero;


            var thisShip = this;
            World.BodiesNear(Position, World.Hook.FishFlockCohesionMaximumDistance, (body) =>
            {
                if (body is Ship otherShip)
                {
                    if (otherShip != thisShip)
                    {
                        count++;

                        var distance = Vector2.Distance(thisShip.Position, otherShip.Position);

                        if (distance < World.Hook.FishFlockCohesionMaximumDistance)
                            exclusiveCenter += otherShip.Position;

                        if (distance < World.Hook.FishFlockSeparationMinimumDistance)
                        {
                            if (distance < 1)
                                distance = 1;

                            separationAccumulator += (thisShip.Position - otherShip.Position) / (distance * distance);
                        }

                        alignmentAccumulator += otherShip.LinearVelocity;
                    }
                }
            });

            Vector2 cohesion = Vector2.Zero;
            Vector2 alignment = Vector2.Zero;
            Vector2 separation = Vector2.Zero;

            if (count > 0)
            {
                exclusiveCenter /= count;
                var relative = exclusiveCenter - thisShip.Position;

                if (relative != Vector2.Zero)
                    cohesion = Vector2.Normalize(relative) * Vector2.Distance(thisShip.Position, exclusiveCenter);

                alignment = alignmentAccumulator / (count);
                separation = separationAccumulator;

                flockingVector =
                    (World.Hook.FishFlockCohesion * cohesion)
                    + (World.Hook.FishFlockAlignment * alignment)
                    + (World.Hook.FishFlockSeparation * separation);

                if (flockingVector != Vector2.Zero)
                {
                    var steeringVector =
                        new Vector2(MathF.Cos(Angle), MathF.Sin(Angle))
                        + flockingVector;

                    Angle = MathF.Atan2(steeringVector.Y, steeringVector.X);
                }
            }
        }