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); }
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); }
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(); }
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); }
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); }
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); }
// This is used to add new force for a specific behaviour public void AddNewForce(SteeringForce newForce) { m_forces.AddLast(newForce); }