Example #1
0
        private void RefreshPath(NodeNetwork nodeNetwork, PositionedObject target, TileShapeCollection solidCollisions, TileShapeCollection pitCollision)
        {
            var ai = InputDevice as TopDown.TopDownAiInput <Enemy>;

            // We are going to pathfind to a location
            // that is not exactly on the target but on
            // a point on a line perpendicular to the enemy.
            // This is a quicky way to add some randomness and
            // spread out the enemies so they come from different directions

            var pathfindingTarget = target.Position;

            var lineToTarget  = target.Position - this.Position;
            var perpendicular = new Vector3(-lineToTarget.Y, lineToTarget.X, 0);

            if (perpendicular.Length() != 0)
            {
                perpendicular.Normalize();
                var distanceFromTarget = lineToTarget.Length();

                const float distanceToPerpendicularLengthRatio = 1 / 2f;

                pathfindingTarget = target.Position + perpendicular * perpendicularLengthRatio * distanceToPerpendicularLengthRatio * distanceFromTarget;
            }
            if (DebuggingVariables.ShowEnemyAiShapes)
            {
                thisToPerpendicularTarget.SetFromAbsoluteEndpoints(this.Position, pathfindingTarget);
            }

            var path = nodeNetwork.GetPathOrClosest(ref Position, ref pathfindingTarget);

            ai.Path.Clear();
            var points = path.Select(item => item.Position).ToList();

            while (points.Count > 0)
            {
                var length = (points[0] - Position).Length();
                lineOfSightPathFindingPolygon.SetPoint(0, length / 2.0f, NavigationCollider.Radius);
                lineOfSightPathFindingPolygon.SetPoint(1, length / 2.0f, -NavigationCollider.Radius);
                lineOfSightPathFindingPolygon.SetPoint(2, -length / 2.0f, -NavigationCollider.Radius);
                lineOfSightPathFindingPolygon.SetPoint(3, -length / 2.0f, NavigationCollider.Radius);
                lineOfSightPathFindingPolygon.SetPoint(4, length / 2.0f, NavigationCollider.Radius);

                lineOfSightPathFindingPolygon.X = (points[0].X + Position.X) / 2.0f;
                lineOfSightPathFindingPolygon.Y = (points[0].Y + Position.Y) / 2.0f;

                var angle = (float)System.Math.Atan2(points[0].Y - Position.Y, points[0].X - Position.X);
                lineOfSightPathFindingPolygon.RotationZ = angle;

                var hasClearPath = !solidCollisions.CollideAgainst(lineOfSightPathFindingPolygon) && !pitCollision.CollideAgainst(lineOfSightPathFindingPolygon);

                if (hasClearPath && points.Count > 1)
                {
                    points.RemoveAt(0);
                }
                else
                {
                    break;
                }
            }


            ai.Path.AddRange(points);
            ai.Target = ai.Path.FirstOrDefault();
        }