public override void Update(float elapsedSeconds, float totalSeconds) { base.Update(elapsedSeconds, totalSeconds); nextWaveCanRespawn = nextWaveCanRespawn || minimumTimeBetweenWaves.Tick(elapsedSeconds); spawnNextWave = nextWaveCanRespawn && (currentAnimalCount <= animalThresholdForNextWave || maxiumumTimeBetweenWaves.Tick(elapsedSeconds)); // if the next if ((spawnNextWave && remainingWaves > 0) || (currentAnimalCount == 0 && nextWaveCanRespawn)) { nextWaveCanRespawn = false; spawnNextWave = false; minimumTimeBetweenWaves.Reset(); maxiumumTimeBetweenWaves.Reset(); WaveType waveType = RandomExt.GetRandomFloat(0, 1) >= 0.5f ? WaveType.Collecting : WaveType.Fighting; currentAnimalCount += this.SpawnWave(waveType, new Rectangle((int)(0.625f * centerX), (int)(-0.625f * centerY), 2, (int)screenHeight / 2)); animalThresholdForNextWave = (int)Math.Ceiling(currentAnimalCount * 0.1f); remainingWaves--; if (remainingWaves == 0) { base.StartCountown(); } } }
public static int SpawnWave(this GameScene scene, WaveType type, Rectangle zone) { int numberOfPlayers = scene.Game.CurrentGameMode.PlayerInfos.Count; int numberOfBoars; int numberOfChicken; switch (type) { case WaveType.Fighting: if (RandomExt.GetRandomFloat(0, 1) >= 0.5f) { numberOfBoars = numberOfPlayers - 1; numberOfChicken = 0; } else { numberOfBoars = 0; numberOfChicken = RandomExt.GetRandomInt(5 + numberOfPlayers, 12 + numberOfPlayers); } break; default: case WaveType.Collecting: numberOfBoars = RandomExt.GetRandomInt(numberOfPlayers, numberOfPlayers * 2); numberOfChicken = RandomExt.GetRandomInt(numberOfPlayers * 3, numberOfPlayers * 5); break; } scene.SpawnCattleInZone(zone, numberOfBoars, numberOfChicken); return(numberOfBoars + numberOfChicken); }
private static AnimalType <BoarState> CreateType(ContentManager content) { float baseSpeed = 1.3f; float slowSpeed = 0.2f; float fleeingDuration = RandomExt.GetRandomFloat(1f, 1.5f); float followingDuration = RandomExt.GetRandomFloat(1f, 1.5f); float size = RandomExt.GetRandomFloat(1.23f, 1.32f); return(AnimalTypeFactory.CreateAnimal(BoarState.Wandering) .WithAsset(content.LoadFromJson <AnimationDefintion>("Animations/boar_anim"), new Vector2(size, size)) .WithCollisionShape(new[] { new Vector2(0, 0.4f), new Vector2(-0.2f, 0.3f), new Vector2(-0.2f, -0.3f), new Vector2(0, -0.4f), new Vector2(0.2f, -0.3f), new Vector2(0.2f, 0.3f) }) .WithSensing() .WithBehaviour(() => new WanderingBehavior <BoarState>(BoarState.Wandering, 1.5f, new OutgoingState <BoarState>(0.4f, BoarState.Rootling), new OutgoingState <BoarState>(0.6f, BoarState.Wandering)) { CircleRadius = 4f, CircleCenterOffset = 2f, WanderingSpeedMin = baseSpeed, WanderingSpeedMax = baseSpeed * 1.1f }) .WithBehaviour(() => new WanderingBehavior <BoarState>(BoarState.Rootling, 1.5f, new OutgoingState <BoarState>(0.2f, BoarState.Rootling), new OutgoingState <BoarState>(0.8f, BoarState.Wandering)) { MaxTurningSpeed = 0.1f, WanderingSpeedMin = 0, WanderingSpeedMax = slowSpeed }) // Fleeing .WithBehaviour(() => new FleeingBehavior <BoarState>(BoarState.Fleeing, fleeingDuration, new OutgoingState <BoarState>(1f, BoarState.Wandering)) { Name = "fleeing", Speed = baseSpeed * 3f }) // Following .WithBehaviour(() => new FollowingBehavior <BoarState>(BoarState.Following, followingDuration, new OutgoingState <BoarState>(1f, BoarState.Wandering)) { Speed = baseSpeed }) // Being hit .WithBehaviour(() => new HitBehavior <BoarState>(BoarState.BeingHit, 1f, new OutgoingState <BoarState>(1f, BoarState.Fleeing)) { Name = "beinghit", Speed = 0.5f }) .WithBehaviour(() => new ObstacleAvoidanceBehaviour <BoarState>(EnumExt.GetValues <BoarState>(), new OutgoingState <BoarState> [0]) { Weight = 10f }) .WithBehaviour(() => new UnstuckBehavior <BoarState>(EnumExt.GetValues <BoarState>(), new OutgoingState <BoarState> [0])) .DefaultAnimation("walking").StateToAnimation(BoarState.Rootling, "neutral").StateToAnimation(BoarState.BeingHit, "hit")); }
private void FleeingTrigger(BoarState currentState, Entity entity, float elapsedSeconds, float totalElapsedSeconds) { // Only allow fleeing if the animal is not in following mode but when it is, only has a distance of smaller than 1 meters if (hearingSensor.SensedEntities.Any() && (aiComponent.CurrentState != BoarState.Following || (followingBehaviour.EntityToFollow.Body.Position - Body.Position).Length() > 1f)) { fleeingBehaviour.FleeingPoint = hearingSensor.SensedEntities.Average(e => e.Body.Position); if (currentState != BoarState.Fleeing) { var randI = RandomExt.GetRandomInt(1, 5); var delay = RandomExt.GetRandomFloat(0, 0.25f); this.Scene.Dispatcher.Delay(delay, () => GetComponent <AudioSourceComponent>().PlaySound($"Audio/PigScared{randI}")); } aiComponent.ChangeState(BoarState.Fleeing); } }
protected override void UpdateBehaviour(float elapsedSeconds, float totalSeconds) { if (Vector2.Distance(lastLocation, Entity.Body.Position) > 0.3) { lastLocation = Entity.Body.Position; timeStuck = 0; } timeStuck += elapsedSeconds; if (timeStuck > 2) { if (obstacleSensor.SensedEntity != null && obstacleSensor.SensedEntity.Body.BodyType == FarseerPhysics.Dynamics.BodyType.Static) { Entity.Body.ApplyLinearImpulse(RandomExt.GetRandomVector(10, 30) * Weight); Entity.Body.ApplyAngularImpulse(RandomExt.GetRandomFloat(100, 300) * Weight); } } }
public void SpawnCattleInZone(Rectangle zone, int boars, int chicken) { int amount = boars + chicken; for (int i = 0; i < amount; i++) { var x = RandomExt.GetRandomFloat(zone.Left, zone.Right); var y = RandomExt.GetRandomFloat(zone.Top, zone.Bottom); var r = RandomExt.GetRandomFloat(0, 2 * (float)Math.PI); if (boars > 0) { AddEntity(new BoarEntity(this, new Vector2(x, y), r)); boars--; } else { AddEntity(new ChickenEntity(this, new Vector2(x, y), r)); } } }
public void SwitchToOutputState() { float random = RandomExt.GetRandomFloat(0, 1); float accumulated = 0; T nextState = stateAI.CurrentState; for (int i = 0; i < OutgoingStates.Length; i++) { OutgoingState <T> state = OutgoingStates[i]; accumulated += state.Probabiliy; if (random <= accumulated) { nextState = state.State; break; } } stateAI.ChangeState(nextState); }
public bool TryGetInstance(bool throttle, float totalTime, out WrappedSoundEffectInstance result) { result = null; if (!(totalTime - lastPlayed > definition.MinimumTimeBetween) && throttle) { return(false); } bool lockTaken = false; spinLock.Enter(ref lockTaken); try { if (instanceCount < definition.InstanceLimit || !throttle) { instanceCount++; } else { return(false); } lastPlayed = totalTime; } finally { spinLock.Exit(); } var pooledObject = instancePool.GetFree(); result = pooledObject.Value; result.PoolObject = pooledObject; result.Instance.Volume = MathHelper.Clamp(RandomExt.GetRandomFloat(definition.MinVolume, definition.MaxVolume), 0, 1); result.Instance.Pitch = MathHelper.Clamp(RandomExt.GetRandomFloat(definition.MinPitchShift, definition.MaxPitchShift), 0, 1); return(true); }
protected override void UpdateBehaviour(float elapsedSeconds, float totalSeconds) { // Switch to next state after some time if (timerForChange.Tick(elapsedSeconds)) { SwitchToOutputState(); } Body body = this.Entity.Body; var position = body.Position; var rotation = body.Rotation; Vector2 desiredPosition = position + VectorExtensions.AngleToUnitVector(rotation) * CircleCenterOffset; desiredPosition += VectorExtensions.AngleToUnitVector(RandomExt.GetRandomAngle()) * CircleRadius; Vector2 direction = (desiredPosition - position); movement.Speed = RandomExt.GetRandomFloat(WanderingSpeedMin, WanderingSpeedMax); movement.TurningSpeed = MaxTurningSpeed; movement.Steer(direction, Weight); }
private static AnimalType <ChickenState> CreateType(ContentManager content, int chickenType) { float baseSpeed = 2f; float slowSpeed = 0f; float fleeingDuration = RandomExt.GetRandomFloat(0.8f, 1.5f); float followingDuration = RandomExt.GetRandomFloat(1f, 1.5f); var asset = content.LoadFromJson <AnimationDefintion>("Animations/chicken_anim"); float size = RandomExt.GetRandomFloat(0.9f, 1.2f); if (chickenType == -1 && RandomExt.GetRandomFloat(0, 1) < 0.35f || chickenType == 1) { asset.AssetName = "chicken_walk-spritesheet_8x4_a512_orange"; size = RandomExt.GetRandomFloat(0.5f, 0.7f); } return(AnimalTypeFactory.CreateAnimal(ChickenState.Wandering) .WithAsset(asset, new Vector2(size, size)) .WithCollisionShape(size * 0.13f, 0.6f) .WithSensing() .WithBehaviour(() => new WanderingBehavior <ChickenState>(ChickenState.Wandering, 3f, new OutgoingState <ChickenState>(0.4f, ChickenState.Picking), new OutgoingState <ChickenState>(0.6f, ChickenState.Wandering)) { CircleRadius = 2f, CircleCenterOffset = 1f, WanderingSpeedMin = baseSpeed * 0.35f, WanderingSpeedMax = baseSpeed * 0.55f, MaxTurningSpeed = 5f }) .WithBehaviour(() => new WanderingBehavior <ChickenState>(ChickenState.Picking, 1.5f, new OutgoingState <ChickenState>(0.2f, ChickenState.Picking), new OutgoingState <ChickenState>(0.8f, ChickenState.Wandering)) { MaxTurningSpeed = 0.1f, WanderingSpeedMin = 0, WanderingSpeedMax = slowSpeed }) .WithBehaviour(() => new FleeingBehavior <ChickenState>(ChickenState.Fleeing, fleeingDuration, new OutgoingState <ChickenState>(1f, ChickenState.Wandering)) { Weight = 10f, Speed = baseSpeed * 1.5f, MaxTurningSpeed = 10f }) .WithBehaviour(() => new FollowingBehavior <ChickenState>(ChickenState.Following, followingDuration, new OutgoingState <ChickenState>(1f, ChickenState.Wandering)) { Weight = 30f, Speed = baseSpeed * 0.7f }) .WithBehaviour(() => new ObstacleAvoidanceBehaviour <ChickenState>(EnumExt.GetValues <ChickenState>(), new OutgoingState <ChickenState> [0]) { Weight = 50f, AvoidingDistance = 1f }) .WithBehaviour(() => new CohesionBehavior <ChickenState>(EnumExt.GetValues <ChickenState>(), new OutgoingState <ChickenState> [0]) { Weight = 1f }) .WithBehaviour(() => new SeparationBehavior <ChickenState>(EnumExt.GetValues <ChickenState>(), new OutgoingState <ChickenState> [0]) { Name = "separation", Weight = 1f }) .WithBehaviour(() => new PlayerFleeingBehavior <ChickenState>(ChickenState.AvoidingPlayer, 0.5f, new OutgoingState <ChickenState>(1f, ChickenState.Wandering)) { Speed = 3f }) .WithBehaviour(() => new VelocityMatchBehavior <ChickenState>(EnumExt.GetValues <ChickenState>(), new OutgoingState <ChickenState> [0]) { Weight = 2f }) .WithBehaviour(() => new UnstuckBehavior <ChickenState>(EnumExt.GetValues <ChickenState>(), new OutgoingState <ChickenState> [0]) { Weight = 0.25f }) .DefaultAnimation("walking").StateToAnimation(ChickenState.Picking, "eating").StateToAnimation(ChickenState.AvoidingPlayer, "flapping") .StateToAnimation(ChickenState.Fleeing, "flapping")); }