Ejemplo n.º 1
0
        protected override Vector2 OnUpdateSteeringForce(float elapsedTime, Steerable movingEntity)
        {
            if (MovesPerMinute < 0f)
            {
                MovesPerMinute = 0f;
            }

            // Check if we are outside our moving range
            if (Vector2.Subtract(movingEntity.Position, location).LengthSquared() > PatrolRange * PatrolRange * 1.2F)
            {
                timer    = (float)(Random.NextDouble() * 60 / (MovesPerMinute + 0.001f));
                location = movingEntity.Position;
            }

            // Select a random location when the timer expires
            timer -= (float)elapsedTime;

            if (timer < 0)
            {
                Vector2 target = new Vector2();

                float a = (float)(Random.NextDouble() * Math.PI * 2);
                float r = (float)(Random.NextDouble());

                target.X = (float)(Math.Cos(a) * PatrolRange * r);
                target.Y = (float)(Math.Sin(a) * PatrolRange * r);

                movingEntity.Target = target + location;

                timer = (float)(Random.NextDouble() * 60 / (MovesPerMinute + 0.001f));
            }

            return(SteeringHelper.Arrive(elapsedTime, movingEntity));
        }
Ejemplo n.º 2
0
        protected override Vector2 OnUpdateSteeringForce(float elapsedTime, Steerable movingEntity)
        {
            //if the evader is ahead and facing the agent then we can just seek
            //for the evader's current position.
            Vector2 toEvader = Evader.Position - movingEntity.Position;

            float relativeHeading = Vector2.Dot(movingEntity.Forward, Evader.Forward);

            if ((Vector2.Dot(toEvader, movingEntity.Forward) > 0) &&
                (relativeHeading < -0.95f))  //acos(0.95)=18 degs
            {
                movingEntity.Target = Evader.Position + Offset;
                return(SteeringHelper.Seek(elapsedTime, movingEntity));
            }

            //Not considered ahead so we predict where the evader will be.

            //the lookahead time is propotional to the distance between the evader
            //and the pursuer; and is inversely proportional to the sum of the
            //agent's velocities
            float lookAheadTime = toEvader.Length() / (movingEntity.MaxSpeed + Evader.Speed);

            //now seek to the predicted future position of the evader
            movingEntity.Target = Evader.Position + Evader.Velocity * lookAheadTime + Offset;
            return(SteeringHelper.Seek(elapsedTime, movingEntity));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Calculates the steering force to arrive at the target.
        /// </summary>
        public static Vector2 Arrive(float elapsedTime, Steerable movingEntity)
        {
            if (!movingEntity.Target.HasValue)
            {
                return(Vector2.Zero);
            }

            Vector2 toTarget = movingEntity.Target.Value - movingEntity.Position;

            // Stop when the moving entity has passed target.
            if (toTarget.Length() <= movingEntity.BoundingRadius + movingEntity.Skin + movingEntity.DecelerationRange)
            {
                if (movingEntity.Velocity != Vector2.Zero && Vector2.Dot(toTarget, movingEntity.Velocity) <= 0)
                {
                    movingEntity.Target = null;
                    return(Vector2.Zero);
                }
            }

            // Stop when the moving entity is close enough.
            float distance = toTarget.Length();

            if (distance <= movingEntity.DecelerationRange)
            {
                movingEntity.Target = null;
                return(Vector2.Zero);
            }

            return(SteeringHelper.Seek(elapsedTime, movingEntity));
        }
Ejemplo n.º 4
0
        protected override Vector2 OnUpdateSteeringForce(float elapsedTime, Steerable movingEntity)
        {
            int     count  = 0;
            Vector2 center = Vector2.Zero;

            var boundingSphere = new BoundingSphere(new Vector3(movingEntity.Position, 0), Range);

            Neighbors.FindAll(ref boundingSphere, Partners);

            foreach (var partner in Partners)
            {
                if (partner != null && partner != movingEntity)
                {
                    center += partner.Position;
                    if (++count >= SteeringHelper.MaxAffectingEntities)
                    {
                        break;
                    }
                }
            }
            Partners.Clear();

            if (count > 0)
            {
                center /= count;
                movingEntity.Target = center;
                return(SteeringHelper.Seek(elapsedTime, movingEntity));
            }
            return(Vector2.Zero);
        }
Ejemplo n.º 5
0
        protected override Vector2 OnUpdateSteeringForce(float elapsedTime, Steerable movingEntity)
        {
            // Not necessary to include the check for facing direction this time
            Vector2 toPursuer = Pursuer.Position - movingEntity.Position;

            //uncomment the following two lines to have Evade only consider pursuers
            //within a 'threat range'
            if (toPursuer.LengthSquared() > ThreatRange * ThreatRange)
            {
                return(Vector2.Zero);
            }

            //the lookahead time is propotional to the distance between the pursuer
            //and the pursuer; and is inversely proportional to the sum of the
            //agents' velocities
            float LookAheadTime = toPursuer.Length() / (movingEntity.MaxSpeed + Pursuer.Speed);

            //now flee away from predicted future position of the pursuer
            return(SteeringHelper.Flee(elapsedTime, movingEntity, Pursuer.Position + Pursuer.Velocity * LookAheadTime));
        }
Ejemplo n.º 6
0
 protected override Vector2 OnUpdateSteeringForce(float elapsedTime, Steerable movingEntity)
 {
     return(SteeringHelper.Arrive(elapsedTime, movingEntity));
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Updates the internal state of the object based on game time.
        /// </summary>
        public void Update(float elapsedTime)
        {
            if (elapsedTime <= 0)
            {
                return;
            }

            // The max acceleration can stops the moving entity from top speed.
            float MaxAcceleration = MaxSpeed / elapsedTime;

            if (acceleration >= MaxAcceleration)
            {
                currentAcceleration = MaxAcceleration;
            }

            force    = Vector2.Zero;
            MaxForce = Acceleration;

            DecelerationRange = SteeringHelper.GetDecelerateRange(this);
            TargetedForward   = SteeringHelper.GetTargetedForward(this);
            Skin = MaxSpeed * elapsedTime * 2;

            // Accumulate force of each behavior
            for (int i = 0; i < Behaviors.Count; ++i)
            {
                Vector2 steeringForce = Behaviors.GetWeightByIndex(i) * Behaviors[i].UpdateSteeringForce(elapsedTime, this);
                if (BlendMode == SteeringBehaviorBlendMode.WeightedSum)
                {
                    if (!AccumulateForceWeightedSum(ref force, MaxForce, steeringForce))
                    {
                        break;
                    }
                }
                else if (BlendMode == SteeringBehaviorBlendMode.Solo)
                {
                    if (!AccumulateForceSolo(ref force, MaxForce, steeringForce))
                    {
                        break;
                    }
                }
            }

            if (Speed >= 0 && force == Vector2.Zero)
            {
                // The moving entity has fully stopped.
                if (Speed == 0)
                {
                    return;
                }

                // Apply friction when there is no force but the entity is still moving.
                Vector2 previousVelocity = Velocity;
                Velocity -= forward * MaxForce * elapsedTime;

                // When the velocity has changed its direction, that indicates the moving
                // entity has fully stopped.
                if (Vector2.Dot(previousVelocity, Velocity) <= 0)
                {
                    Velocity = Vector2.Zero;
                    Speed    = 0;
                    return;
                }

                Speed = Velocity.Length();
            }
            else
            {
                // We don't multiply elapsedTime here because our force
                // is calculated based on the subtracting desired speed and current speed.
                Velocity += force * elapsedTime;
                Speed     = Velocity.Length();

                if (Speed <= 0)
                {
                    return;
                }

                // Turncate speed
                if (Speed > MaxSpeed)
                {
                    Velocity *= (float)(MaxSpeed / Speed);
                    Speed     = MaxSpeed;
                }
            }

            Debug.Assert(Speed > 0);
            forward = Vector2.Normalize(Velocity);

            // Update position
            Vector2 newPosition;

            IsStucked = DetectCollision(Position, Position + Velocity * elapsedTime, elapsedTime, out newPosition);
            Position  = newPosition;
        }