internal SteeringBehaviours(MovingEntity movingEntity) { _movingHelper = new MovingHelper(); _feelers = new List <Vector2>(); _actor = movingEntity; _taggedNeighbors = new List <MovingEntity>(); _taggedObstacles = new List <BaseGameEntity>(); }
private Vector2 Evade(MovingEntity pursuer) { /* Not necessary to include the check for facing direction this time */ Vector2 ToPursuer = pursuer.Position - _actor.Position; //the look-ahead time is proportional to the distance between the pursuer //and the evader; and is inversely proportional to the sum of the //agents' velocities var LookAheadTime = ToPursuer.Length() / (_actor.MaxSpeed + pursuer.MaxSpeed); //todo:provjera //now flee away from predicted future position of the pursuer return(Flee(pursuer.Position + pursuer.Velocity * LookAheadTime)); }
private float TurnAroundTime(MovingEntity pAgent, Vector2 targetPos) { //determine the normalized vector to the target Vector2 toTarget = targetPos - pAgent.Position; toTarget.Normalize(); var dot = Vector2.Dot(pAgent.Heading, toTarget); //change this value to get the desired behavior. The higher the max turn //rate of the vehicle, the higher this value should be. If the vehicle is //heading in the opposite direction to its target position then a value //of 0.5 means that this function will return a time of 1 second for the //vehicle to turn around. const float coefficient = 0.5f; //the dot product gives a value of 1 if the target is directly ahead and -1 //if it is directly behind. Subtracting 1 and multiplying by the negative of //the coefficient gives a positive value proportional to the rotational //displacement of the vehicle and target. return((dot - 1.0f) * -coefficient); }
private Vector2 Pursuit(MovingEntity evader) { //if the evader is ahead and facing the agent then we can just seek //for the evader's current position. Vector2 ToEvader = evader.Position - _actor.Position; var relativeHeading = Vector2.Dot(evader.Heading, _actor.Heading); if ((Vector2.Dot(ToEvader, _actor.Heading) > 0) && (relativeHeading < -0.95)) //acos(0.95)=18 degs { return(Seek(evader.Position)); } //Not considered ahead so we predict where the evader will be. //the look-ahead time is proportional to the distance between the evader //and the pursuer; and is inversely proportional to the sum of the //agents' velocities var lookAheadTime = ToEvader.Length() / (_actor.MaxSpeed + evader.MaxSpeed); //todo:provjera lookAheadTime += TurnAroundTime(_actor, evader.Position); //todo:provjera //now seek to the predicted future position of the evader return(Seek(evader.Position + evader.Velocity * lookAheadTime)); }
/// <summary> /// Prevents Overlaps with others moving entities /// </summary> protected void EnforceNonPenetrationConstraint() { for (int i = MovingEntities.Count - 1; i >= 0; i--) { MovingEntity movingEntity = MovingEntities[i]; if (movingEntity == this) { continue; } Vector2 toEntity = this.Position - movingEntity.Position; float distanceEntities = Vector2.Distance(this.Position, movingEntity.Position); float amountOfOverLap = this.Radius + movingEntity.Radius - distanceEntities; if (amountOfOverLap >= 0) { //move the entity a distance away equivalent to the amount of overlap. this.Position = this.Position + (toEntity / distanceEntities) * amountOfOverLap; } } }
/// <summary> /// Turns evade behaviour off /// </summary> /// <param name = "pursuer"></param> public void EvadeOff(MovingEntity pursuer) { _evadeOn = false; }
/// <summary> /// Turns evade behaviour on /// </summary> /// <param name = "pursuer">The entity witch we are evading</param> public void EvadeOn(MovingEntity pursuer) { _pursuer = pursuer; _evadeOn = true; }
/// <summary> /// Turns pursuit behaviour off /// </summary> /// <param name = "evader"></param> public void PursuitOff(MovingEntity evader) { _pursuitOn = false; }
/// <summary> /// Turns pursuit behaviour on /// </summary> /// <param name = "evader">The entity whitch we are pursuing</param> public void PursuitOn(MovingEntity evader) { _evader = evader; _pursuitOn = true; }