/// <summary> /// CohesionBehavior.Update infuences the owning animal to move towards the /// otherAnimal that it sees as long as it isn’t too close, in this case /// that means inside the separationDist in the passed in AIParameters. /// </summary> /// <param name="otherAnimal">the Animal to react to</param> /// <param name="aiParams">the Behaviors' parameters</param> public override void Update(Animal otherAnimal, AIParameters aiParams) { base.ResetReaction(); Vector3 pullDirection = Vector3.Zero; float weight = aiParams.PerMemberWeight; //if the otherAnimal is too close we dont' want to fly any //closer to it if (Animal.ReactionDistance > 0.0f && Animal.ReactionDistance > aiParams.SeparationDistance) { //We want to make the animal move closer the the otherAnimal so we //create a pullDirection vector pointing to the otherAnimal bird and //weigh it based on how close the otherAnimal is relative to the //AIParameters.separationDistance. pullDirection = -(Animal.Location - Animal.ReactionLocation); Vector3.Normalize(ref pullDirection, out pullDirection); weight *= (float)Math.Pow((double) (Animal.ReactionDistance - aiParams.SeparationDistance) / (aiParams.DetectionDistance - aiParams.SeparationDistance), 2); pullDirection *= weight; reacted = true; reaction = pullDirection; } }
/// <summary> /// separationBehavior.Update infuences the owning animal to move away from /// the otherAnimal is it’s too close, in this case if it’s inside /// AIParameters.separationDistance. /// </summary> /// <param name="otherAnimal">the Animal to react to</param> /// <param name="aiParams">the Behaviors' parameters</param> public override void Update(Animal otherAnimal, AIParameters aiParams) { base.ResetReaction(); Vector3 pushDirection = Vector3.Zero; float weight = aiParams.PerMemberWeight; if (Animal.ReactionDistance > 0.0f && Animal.ReactionDistance <= aiParams.SeparationDistance) { //The otherAnimal is too close so we figure out a pushDirection //vector in the opposite direction of the otherAnimal and then weight //that reaction based on how close it is vs. our separationDistance pushDirection = Animal.Location - Animal.ReactionLocation; Vector3.Normalize(ref pushDirection, out pushDirection); //push away weight *= (1 - (float)Animal.ReactionDistance / aiParams.SeparationDistance); pushDirection *= weight; reacted = true; reaction += pushDirection; } }
/// <summary> /// AlignBehavior.Update infuences the owning animal to move in same the /// direction as the otherAnimal that it sees. /// </summary> /// <param name="otherAnimal">the Animal to react to</param> /// <param name="aiParams">the Behaviors' parameters</param> public override void Update(Animal otherAnimal, AIParameters aiParams) { base.ResetReaction(); if (otherAnimal != null) { reacted = true; reaction = otherAnimal.Direction * aiParams.PerMemberWeight; } }
public SchoolOfFish(ContentManager Content, Texture2D fishTexture, int minX, int maxX, int minZ, int maxZ, float camHeight) { flock = null; //cat = null; flockParams = new AIParameters(); this.content = Content; this.fishTexture = fishTexture; this.gameMaxX = GameConstants.MainGameMaxRangeX; this.gameMaxZ = GameConstants.MainGameMaxRangeZ; minValueX = minX; minValueZ = minZ; maxValueX = maxX; maxValueZ = maxZ; camHeightScale = (float)GameConstants.StandardCamHeight / (float)camHeight; ResetAIParams(); }
/// <summary> /// update fish position, wrapping around the screen edges /// </summary> /// <param name="gameTime"></param> public void Update(GameTime gameTime, ref AIParameters aiParams) { EffectHelpers.GetEffectConfiguration(ref fogColor, ref ambientColor, ref diffuseColor, ref specularColor); float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds; Vector3 randomDir = Vector3.Zero; randomDir.X = (float)random.NextDouble() - 0.5f; randomDir.Y = 0; randomDir.Z = (float)random.NextDouble() - 0.5f; Vector3.Normalize(ref randomDir, out randomDir); if (aiNumSeen > 0) { aiNewDir = (direction * aiParams.MoveInOldDirectionInfluence) + (aiNewDir * (aiParams.MoveInFlockDirectionInfluence / (float)aiNumSeen)); } else { aiNewDir = direction * aiParams.MoveInOldDirectionInfluence; } aiNewDir += (randomDir * aiParams.MoveInRandomDirectionInfluence); Vector3.Normalize(ref aiNewDir, out aiNewDir); aiNewDir = ChangeDirection(direction, aiNewDir, aiParams.MaxTurnRadians * elapsedTime); direction = aiNewDir; if (direction.LengthSquared() > .01f) { Vector3 moveAmount = direction * moveSpeed * elapsedTime; location = location + moveAmount; if (Math.Abs(location.X) > boundryWidth + 200) location.X = -location.X; if (Math.Abs(location.Z) > boundryHeight + 200) location.Z = -location.Z; } }
public void ReactToSwimmingObject(SwimmingObject swimmingObject, ref AIParameters AIparams) { if (swimmingObject != null) { //setting the the reactionLocation and reactionDistance here is //an optimization, many of the possible reactions use the distance //and location of theAnimal, so we might as well figure them out //only once ! Vector3 otherLocation = swimmingObject.Position; ClosestLocation(ref location, ref otherLocation, out reactionLocation); reactionDistance = Vector3.Distance(location, reactionLocation); //we only react if theAnimal is close enough that we can see it if (reactionDistance < AIparams.DetectionDistance) { fleeReaction.Update(swimmingObject, AIparams); if (fleeReaction.Reacted) { aiNewDir += fleeReaction.Reaction; aiNumSeen++; } } } }
/// <summary> /// React to an Animal based on it's type /// </summary> /// <param name="animal"></param> public void ReactTo(Animal animal, ref AIParameters AIparams) { if (animal != null) { //setting the the reactionLocation and reactionDistance here is //an optimization, many of the possible reactions use the distance //and location of theAnimal, so we might as well figure them out //only once ! Vector3 otherLocation = animal.Location; ClosestLocation(ref location, ref otherLocation, out reactionLocation); reactionDistance = Vector3.Distance(location, reactionLocation); //we only react if theAnimal is close enough that we can see it if (reactionDistance < AIparams.DetectionDistance) { Behaviors reactions = behaviors[animal.AnimalType]; foreach (Behavior reaction in reactions) { reaction.Update(animal, AIparams); if (reaction.Reacted) { aiNewDir += reaction.Reaction; aiNumSeen++; } } } } }
public virtual void Update(SwimmingObject swimmingObject, AIParameters aiParams) { }
public virtual void Update(HydroBot tank, AIParameters aiParams) { }
/// <summary> /// Abstract function that the subclass must impliment. Figure out the /// Behavior reaction here. /// </summary> /// <param name="otherAnimal">the Animal to react to</param> /// <param name="aiParams">the Behaviors' parameters</param> public abstract void Update(Animal otherAnimal, AIParameters aiParams);