예제 #1
0
        private SteeringForce UpdateDirection(SteeringForce force)
        {
            if (force.Amount == 0)
            {
                return(force);
            }

            while (Math.Abs(force.Direction - (Direction + Math.PI * 2)) < Math.Abs(force.Direction - Direction))
            {
                force.Direction -= Math.PI * 2;
            }

            while (Math.Abs(force.Direction - (Direction - Math.PI * 2)) < Math.Abs(force.Direction - Direction))
            {
                force.Direction += Math.PI * 2;
            }

            var directionChangeMax = DirectionMaxChange * 1 / Speed;
            var directionDiff      = force.Direction - Direction;

            Direction += Utility.BoundValue(directionDiff, -directionChangeMax, directionChangeMax);

            force.Amount = force.Amount * (1 - directionDiff / Math.PI);

            return(force);
        }
예제 #2
0
        protected void CalculateSteeringForce()
        {
            SteeringForce force = null;

            switch (GameWorld.Instance.SteeringForceCalculationType)
            {
            case SteeringForceCalculationType.Dithering:
                force = CalculateSteeringForceDithering();
                break;

            case SteeringForceCalculationType.Priorization:
                force = CalculateSteeringForcePriorization();
                break;

            case SteeringForceCalculationType.WeightedTruncatedSum:
                force = CalculateSteeringForceTruncatedSum();
                break;

            default:
                throw new Exception("Current SteeringForceCalculationType is invalid.");
            }

            force.Amount = Utility.BoundValueMax(force.Amount, MaxForce);

            ApplySteeringForce(force);
        }
예제 #3
0
        private void ApplySteeringForce(SteeringForce force)
        {
            force       = UpdateDirection(force);
            QuickEnergy = Utility.BoundValue(QuickEnergy, 0.05, 1);

            Speed  = Utility.BoundValueMin(Speed - SlowDownSpeed, 0);
            Speed += force.Amount * 0.1;            // inertia
            Speed  = Utility.BoundValueMax(Speed, MaxSpeed * QuickEnergy);

            Location.X += Math.Cos(Direction) * Speed;
            Location.Y += Math.Sin(Direction) * Speed;

            FixEntityOnEdge();
        }
예제 #4
0
        private SteeringForce CalculateSteeringForceTruncatedSum()
        {
            SteeringForce force = new SteeringForce();

            for (int i = 0; i < SteeringBehaviours.Count; i++)
            {
                force += SteeringBehaviours[i].Calculate(this);
                if (SteeringBehaviours[i].BehaviorDone)
                {
                    SteeringBehaviours.RemoveAt(i);
                    i--;
                }
            }

            return(force);
        }
예제 #5
0
        private SteeringForce CalculateSteeringForcePriorization()
        {
            int           behaviorsCalculationCount = 3;
            SteeringForce force = new SteeringForce();

            for (int i = 0; i < behaviorsCalculationCount && i < SteeringBehaviours.Count; i++)
            {
                force += SteeringBehaviours[i].Calculate(this);
                if (SteeringBehaviours[i].BehaviorDone)
                {
                    SteeringBehaviours.RemoveAt(i);
                    i--;
                }
            }

            return(force);
        }
        /// <summary>
        /// Calculate forces using weights map to each behavior.
        /// Currently all behavior have the same weight.
        /// </summary>
        private void CalculateWeightsSum(double timeElapsed)
        {
            // Check for each behavior
            if (IsSeekOn)
            {
                SteeringForce += Seek(Target.Pos) * _weights[BehaviorType.Seek];
            }
            if (IsFleeOn)
            {
                SteeringForce += Flee(ToAvoid.Pos) * _weights[BehaviorType.Flee];
            }
            if (IsArriveOn)
            {
                SteeringForce += Arrive(Target.Pos) * _weights[BehaviorType.Arrive];
            }
            if (IsPursuitOn)
            {
                SteeringForce += Pursuit(Target) * _weights[BehaviorType.Pursuit];
            }
            if (IsEvadeOn)
            {
                SteeringForce += Evade(ToAvoid) * _weights[BehaviorType.Evade];
            }
            if (IsWanderOn)
            {
                SteeringForce += Wander(timeElapsed) * _weights[BehaviorType.Wander];
            }
            if (IsSeparationOn)
            {
                SteeringForce += Separation(_neighbors) * _weights[BehaviorType.Separation];
            }
            if (IsAlignmentOn)
            {
                SteeringForce += Alignment(_neighbors) * _weights[BehaviorType.Alignment];
            }
            if (IsCohesionOn)
            {
                SteeringForce += Cohesion(_neighbors) * _weights[BehaviorType.Cohesion];
            }
            // if ( IsOffsetPursuitOn )   { SteeringForce += OffsetPursuit(Target, new Vector2(30f, 30f)) * _weights["Cohesion"]; }

            // Make sure force does not exceed max agent Force
            SteeringForce = SteeringForce.TruncateExt(Agent.MaxForce);
        }
예제 #7
0
        private SteeringForce CalculateSteeringForceDithering()
        {
            SteeringForce force = new SteeringForce();

            for (int i = 0; i < SteeringBehaviours.Count; i++)
            {
                if (GameWorld.Instance.Random.NextDouble() < SteeringBehaviours[i].Priority)
                {
                    force += SteeringBehaviours[i].Calculate(this);

                    if (SteeringBehaviours[i].BehaviorDone)
                    {
                        SteeringBehaviours.RemoveAt(i);
                        i--;
                    }
                }
            }

            return(force);
        }
        /// <summary>
        /// Calculate remaining steering force and return false if no more can
        /// be added. Return true if still remaining force that can be added.
        /// </summary>
        private bool AccumulateForce(Vector2 forceToAdd)
        {
            // Get steering force  remaining
            double remainingStrength = Agent.MaxForce - SteeringForce.Length();

            // Max exceeed add nothing and return false to stop steering computation
            if (remainingStrength <= 0)
            {
                return(false);
            }

            // We can add new steering force as it
            if (forceToAdd.Length() < remainingStrength)
            {
                SteeringForce += forceToAdd;
            }
            // We can add new steering force but we need to limit it
            else
            {
                SteeringForce += Vector2.Multiply(Vector2.Normalize(forceToAdd), (float)remainingStrength);
            }

            return(true);
        }
예제 #9
0
 // This is used to add new force for a specific behaviour
 public void AddNewForce(SteeringForce newForce)
 {
     m_forces.AddLast(newForce);
 }