public override void StopInstance(SoundInstance instanceToStop) { var channelHandle = (int)instanceToStop.Handle; if(channelHandle == InvalidHandle) return; openAL.Stop(channelHandle); }
protected override void RemoveChannel(SoundInstance instanceToRemove) { var effectInstance = instanceToRemove.Handle as SoundEffectInstance; if (effectInstance != null) effectInstance.Dispose(); instanceToRemove.Handle = null; }
public void StopPreviewSound() { if (this.prevSoundInst == null) return; this.prevSoundInst.FadeOut(0.25f); this.prevSoundInst = null; this.Invalidate(); }
protected override void CreateChannel(SoundInstance instanceToAdd) { var channelHandle = openAL.CreateChannel(); if (channelHandle <= 0) Logger.Error(new UnableToCreateSoundChannelOpenTKMightNotBeInitializedCorrectly()); openAL.AttachBufferToChannel(bufferHandle, channelHandle); instanceToAdd.Handle = channelHandle; }
public override void StopInstance(SoundInstance instanceToStop) { var handle = (int)instanceToStop.Handle; if (handle == InvalidHandle) return; AL.SourceStop(handle); }
public override void StopInstance(SoundInstance instanceToStop) { var soundInstance = instanceToStop.Handle as SourceVoice; if (soundInstance != null) soundInstance.Stop(); if (instancesPlaying.Contains(instanceToStop)) instancesPlaying.Remove(instanceToStop); }
public void PlayPreviewSound() { if (this.prevSound == null) return; if (this.prevSoundInst != null) return; this.prevSoundInst = DualityApp.Sound.PlaySound(this.prevSound); this.prevSoundInst.Looped = true; this.Invalidate(); }
private static void TestSoundMusicLoadingImpl(Game game) { Sound sound = null; Assert.DoesNotThrow(() => sound = game.Content.Load<Sound>("EffectBip"), "Failed to load the SoundMusic."); Assert.IsNotNull(sound, "The SoundMusic loaded is null."); testInstance = sound.CreateInstance(game.Audio.AudioEngine.DefaultListener); testInstance.Play(); // Should hear the sound here. }
public override void PlayInstance(SoundInstance instanceToPlay) { var effectInstance = instanceToPlay.Handle as SoundEffectInstance; if (effectInstance == null) return; effectInstance.Volume = instanceToPlay.Volume.Clamp(0.0f, 1.0f); effectInstance.Pan = instanceToPlay.Panning.Clamp(-1.0f, +1.0f); effectInstance.Pitch = (instanceToPlay.Pitch - 1).Clamp(-1.0f, +1.0f); effectInstance.Play(); }
public override void PlayInstance(SoundInstance instanceToPlay) { int channelHandle = (int)instanceToPlay.Handle; if (channelHandle == InvalidHandle) return; openAL.SetVolume(channelHandle, instanceToPlay.Volume); openAL.SetPosition(channelHandle, new Vector3D(instanceToPlay.Panning, 0.0f, 0.0f)); openAL.SetPitch(channelHandle, instanceToPlay.Pitch); openAL.Play(channelHandle); }
protected override async Task LoadContent() { await base.LoadContent(); music = Content.Load<Sound>("MusicFishLampMp3").CreateInstance(Audio.AudioEngine.DefaultListener); effect = Content.Load<Sound>("EffectBip").CreateInstance(Audio.AudioEngine.DefaultListener); music.IsLooped = true; effect.IsLooped = true; music.Play(); effect.Play(); }
public override void PlayInstance(SoundInstance instanceToPlay) { var handle = (int)instanceToPlay.Handle; if (handle == InvalidHandle) return; AL.Source(handle, ALSourcef.Gain, instanceToPlay.Volume); AL.Source(handle, ALSource3f.Position, instanceToPlay.Panning, 0, 0); AL.Source(handle, ALSourcef.Pitch, instanceToPlay.Pitch); AL.SourcePlay(handle); }
public override void PlayInstance(SoundInstance instanceToPlay) { var soundInstance = instanceToPlay.Handle as SourceVoice; if (soundInstance == null) return; soundInstance.SubmitSourceBuffer(buffer, decodedInfo); soundInstance.SetVolume(instanceToPlay.Volume); float left = 0.5f - instanceToPlay.Panning / 2; float right = 0.5f + instanceToPlay.Panning / 2; soundInstance.SetOutputMatrix(1, 2, new[] { left, right }); soundInstance.SetFrequencyRatio(instanceToPlay.Pitch); soundInstance.Start(); instancesPlaying.Add(instanceToPlay); }
/// <summary> /// Sets the screen up (UI components, multimedia content, etc.) /// </summary> public override void Initialize() { base.Initialize(); lovelyInstance = ResourceManager.CreateSound("lovelySound").CreateInstance(); playStop = new Button(ResourceManager.CreateImage("play"), ResourceManager.CreateImage("play_pressed")); balanceLeft = new Button(ResourceManager.CreateImage("balance_left"), ResourceManager.CreateImage("balance_left_pressed")); balanceNormal = new Button(ResourceManager.CreateImage("balance_normal"), ResourceManager.CreateImage("balance_normal_pressed")); balanceRight = new Button(ResourceManager.CreateImage("balance_right"), ResourceManager.CreateImage("balance_right_pressed")); AddComponent(playStop, 230, 325); AddComponent(balanceLeft, 18, 325); AddComponent(balanceNormal, 111, 325); AddComponent(balanceRight, 354, 325); playStop.Released += new Component.ComponentEventHandler(playStop_Released); balanceLeft.Released += new Component.ComponentEventHandler(balanceLeft_Released); balanceNormal.Released += new Component.ComponentEventHandler(balanceNormal_Released); balanceRight.Released += new Component.ComponentEventHandler(balanceRight_Released); }
public override void LoadAsset(AssetInfo assetInfo) { base.LoadAsset(assetInfo); this.soundInstance.Stop(); this.soundInstance = null; this.bank.Remove(this.sound); var path = "Content/" + assetInfo.FileName; if ((this.sound != null) && (this.sound.SoundEffect != null)) { this.sound.SoundEffect.Unload(); WaveServices.Assets.Global.UnloadAsset(path); } this.sound = new SoundInfo(path); this.bank.Add(this.sound); this.UpdateSoundInfoTextBlock(); this.soundInstance = WaveServices.SoundPlayer.Play(this.sound, 1, false); }
void ICmpUpdatable.OnUpdate() { Transform transform = this.GameObj.Transform; RigidBody body = this.GameObj.GetComponent<RigidBody>(); ShipBlueprint blueprint = this.blueprint.Res; // Heal when damaged if (this.hitpoints < 1.0f) { this.hitpoints = MathF.Clamp(this.hitpoints + blueprint.HealRate * Time.SPFMult * Time.TimeMult / blueprint.MaxHitpoints, 0.0f, 1.0f); } // Apply force according to the desired thrust Vector2 actualVelocity = body.LinearVelocity; Vector2 targetVelocity = this.targetThrust * blueprint.MaxSpeed; Vector2 velocityDiff = (targetVelocity - actualVelocity); float sameDirectionFactor = Vector2.Dot( velocityDiff / MathF.Max(0.001f, velocityDiff.Length), this.targetThrust / MathF.Max(0.001f, this.targetThrust.Length)); Vector2 thrusterActivity = this.targetThrust.Length * MathF.Max(sameDirectionFactor, 0.0f) * velocityDiff / MathF.Max(velocityDiff.Length, 1.0f); body.ApplyWorldForce(thrusterActivity * blueprint.ThrusterPower); // Turn to the desired fire angle if (this.targetAngleRatio > 0.0f) { float shortestTurnDirection = MathF.TurnDir(transform.Angle, this.targetAngle); float shortestTurnLength = MathF.CircularDist(transform.Angle, this.targetAngle); float turnDirection; float turnLength; if (MathF.Abs(body.AngularVelocity) > blueprint.MaxTurnSpeed * 0.25f) { turnDirection = MathF.Sign(body.AngularVelocity); turnLength = (turnDirection == shortestTurnDirection) ? shortestTurnLength : (MathF.RadAngle360 - shortestTurnLength); } else { turnDirection = shortestTurnDirection; turnLength = shortestTurnLength; } float turnSpeedRatio = MathF.Min(turnLength * 0.25f, MathF.RadAngle30) / MathF.RadAngle30; float turnVelocity = turnSpeedRatio * turnDirection * blueprint.MaxTurnSpeed * this.targetAngleRatio; body.AngularVelocity += (turnVelocity - body.AngularVelocity) * blueprint.TurnPower * Time.TimeMult; } // Weapon cooldown this.weaponTimer = MathF.Max(0.0f, this.weaponTimer - Time.MsPFMult * Time.TimeMult); // Play the owners special flight sound, when available if (this.owner != null && this.owner.FlightLoop != null) { SoundListener listener = Scene.Current.FindComponent<SoundListener>(); Vector3 listenerPos = listener.GameObj.Transform.Pos; // Determine the target panning manually, because we don't want a true 3D sound here (doppler, falloff, ...) float targetPanning; if (listenerPos.Xy == transform.Pos.Xy || Player.AlivePlayers.Count() <= 1) targetPanning = 0.0f; else targetPanning = -Vector2.Dot(Vector2.UnitX, (listenerPos - transform.Pos).Xy.Normalized); // Determine the target volume float targetVolume = MathF.Clamp(this.targetThrust.Length, 0.0f, 1.0f); // Clean up disposed flight loop if (this.flightLoop != null && this.flightLoop.Disposed) this.flightLoop = null; // Start the flight loop when requested if (targetVolume > 0.0f && this.flightLoop == null) { if ((int)Time.MainTimer.TotalMilliseconds % 2976 <= (int)Time.MsPFMult) { this.flightLoop = DualityApp.Sound.PlaySound(this.owner.FlightLoop); this.flightLoop.Looped = true; } } // Configure existing flight loop if (this.flightLoop != null) { this.flightLoop.Volume += (targetVolume - this.flightLoop.Volume) * 0.05f * Time.TimeMult; this.flightLoop.Panning += (targetPanning - this.flightLoop.Panning) * 0.05f * Time.TimeMult; } } // Display the damage effect when damaged if (this.hitpoints < 0.85f && blueprint.DamageEffect != null) { // Create a new damage effect instance, if not present yet if (this.damageEffect == null) { GameObject damageObj = blueprint.DamageEffect.Res.Instantiate(transform.Pos); damageObj.Parent = this.GameObj; this.damageEffect = damageObj.GetComponent<ParticleEffect>(); if (this.damageEffect == null) throw new NullReferenceException(); } // Configure the damage effect foreach (ParticleEmitter emitter in this.damageEffect.Emitters) { if (emitter == null) continue; emitter.BurstDelay = new Range(50.0f + this.hitpoints * 50.0f, 100.0f + this.hitpoints * 300.0f); if (this.owner != null) { ColorHsva targetColor = this.owner.Color.ToHsva(); emitter.MinColor = new ColorHsva(targetColor.H, targetColor.S, emitter.MinColor.V, emitter.MinColor.A); emitter.MaxColor = new ColorHsva(targetColor.H, targetColor.S, emitter.MaxColor.V, emitter.MaxColor.A); } } } // Get rid of existing damage effects, if no longer needed else if (this.damageEffect != null) { // Stop emitting and dispose when empty foreach (ParticleEmitter emitter in this.damageEffect.Emitters) { if (emitter == null) continue; emitter.BurstDelay = float.MaxValue; } this.damageEffect.DisposeWhenEmpty = true; this.damageEffect = null; } }
public void OnUpdate() { m_direction = -this.GameObj.Transform.Pos; this.GameObj.Transform.Angle = m_direction.Xy.Angle + MathF.RadAngle180; Vector3 moveDelta = Time.TimeMult * m_direction * m_speed; LevelController levelController = this.GameObj.ParentScene.FindComponent <LevelController>(); // Hovering animation { SpriteRenderer sprite = this.GameObj.GetComponent <SpriteRenderer>(); if (this.initialSpriteRect == Rect.Empty) { this.initialSpriteRect = sprite.Rect; } float hoverTimeOffset = (float)(this.GameObj.Id.GetHashCode() % 1000) / 1000.0f; sprite.Rect = new Rect( this.initialSpriteRect.X, this.initialSpriteRect.Y + 10.0f * (1.0f + MathF.Sin(2.0f * (float)Time.GameTimer.TotalSeconds + hoverTimeOffset)), this.initialSpriteRect.W, this.initialSpriteRect.H); } switch (m_shipState) { case ShipState.MoveToTarget: this.GameObj.Transform.MoveBy(moveDelta); if (IsInShootingRange()) { StartScanning(); } break; case ShipState.ScanTarget: //Log.Game.Write("countdownTime: {0}, lastDelta: {1}", m_countdownToAttack, Time.LastDelta); if (m_beamSoundInstance == null || m_beamSoundInstance.Disposed) { m_beamSoundInstance = DualityApp.Sound.PlaySound(m_beamSound); m_beamSoundInstance.Looped = true; m_beamSoundInstance.Pitch = MathF.Rnd.NextFloat(0.8f, 1.25f); } m_countdownToAttack -= Time.LastDelta / 1000; if (levelController == null || levelController.IsGameOver) { m_beamSoundInstance.Volume = 0.1f + 0.1f * MathF.Clamp(1.0f - ((float)m_countdownToAttack / (float)m_scanDuration), 0.0f, 1.0f); } else { m_beamSoundInstance.Volume = 0.5f + 0.5f * MathF.Clamp(1.0f - ((float)m_countdownToAttack / (float)m_scanDuration), 0.0f, 1.0f); } UpdateLineRenderer(false); if (m_countdownToAttack <= 0) { //Log.Game.Write("distance: {0}", this.GameObj.Transform.Pos.LengthSquared); Vector2 hitPos; if (ScanPlanet(out hitPos)) { m_hitPosition = new Vector3(hitPos.X, hitPos.Y, 0); StartShooting(); } else { StartLeaving(); } m_beamSoundInstance.FadeOut(0.1f); } break; case ShipState.ShootTarget: if (m_target != null) { if (levelController != null && !levelController.IsGameOver) { DualityApp.Sound.PlaySound(m_lockAcquiredSound); } Planet planetComp = m_target.GetComponent <Planet>(); if (planetComp != null) { planetComp.IncreaseDetectionCounter(); } } SpawnParticle(); m_shipState = ShipState.LockPosition; break; case ShipState.LeaveTarget: this.GameObj.Transform.MoveBy(-moveDelta); if (IsOutsideRange()) { StartWaiting(); } break; case ShipState.Waiting: m_countdownToAttack -= Time.LastDelta / 1000; if (m_countdownToAttack <= 0) { StartMovingToTarget(); } break; case ShipState.LockPosition: // occasionally spawn particles pulled towards the ship m_countdownToAttack -= Time.LastDelta / 1000; if (m_countdownToAttack <= 0) { SpawnParticle(); } break; default: break; } }
/// <summary> /// Updates the sound source. /// </summary> /// <param name="emitter">The sources parent <see cref="SoundEmitter"/>.</param> /// <returns>True, if the source is still active. False, if it requests to be removed.</returns> public bool Update(SoundEmitter emitter) { // Revalidate Sound reference this.sound.MakeAvailable(); // If the SoundInstance has been disposed, set to null if (this.instance != null && this.instance.Disposed) this.instance = null; // If there is a SoundInstance playing, but it's the wrong one, stop it if (this.instance != null && this.instance.Sound != this.sound) { this.instance.Stop(); this.instance = null; } if (this.instance == null) { // If this Source isn't looped and it HAS been played already, remove it if (!this.looped && this.hasBeenPlayed) return false; // Play the sound this.instance = DualityApp.Sound.PlaySound3D(this.sound, emitter.GameObj); this.instance.Pos = this.offset; this.instance.Looped = this.looped; this.instance.Volume = this.volume; this.instance.Pitch = this.pitch; this.instance.Paused = this.paused; this.hasBeenPlayed = true; } return true; }
void ICmpInitializable.OnShutdown(Component.ShutdownContext context) { if (context == ShutdownContext.Deactivate) { // Fade out playing loop sounds, if there are any. Clean up! if (this.moveSoundLoop != null) { this.moveSoundLoop.FadeOut(0.5f); this.moveSoundLoop = null; } if (this.dangerSoundLoop != null) { this.dangerSoundLoop.FadeOut(0.5f); this.dangerSoundLoop = null; } } }
void ReturnSfxInst(SoundInstance inst) { soundPool.Free(inst); }
void ICmpUpdatable.OnUpdate() { Transform transform = this.GameObj.Transform; RigidBody body = this.GameObj.GetComponent <RigidBody>(); ShipBlueprint blueprint = this.blueprint.Res; // Heal when damaged if (this.hitpoints < 1.0f) { this.hitpoints = MathF.Clamp(this.hitpoints + blueprint.HealRate * Time.SPFMult * Time.TimeMult / blueprint.MaxHitpoints, 0.0f, 1.0f); } // Apply force according to the desired thrust Vector2 actualVelocity = body.LinearVelocity; Vector2 targetVelocity = this.targetThrust * blueprint.MaxSpeed; Vector2 velocityDiff = (targetVelocity - actualVelocity); float sameDirectionFactor = Vector2.Dot( velocityDiff / MathF.Max(0.001f, velocityDiff.Length), this.targetThrust / MathF.Max(0.001f, this.targetThrust.Length)); Vector2 thrusterActivity = this.targetThrust.Length * MathF.Max(sameDirectionFactor, 0.0f) * velocityDiff / MathF.Max(velocityDiff.Length, 1.0f); if (thrusterActivity.Length > 0.00001f) // Don't wake physics without actually doing work { body.ApplyWorldForce(thrusterActivity * blueprint.ThrusterPower); } // Turn to the desired fire angle if (this.targetAngleRatio > 0.0f) { float shortestTurnDirection = MathF.TurnDir(transform.Angle, this.targetAngle); float shortestTurnLength = MathF.CircularDist(transform.Angle, this.targetAngle); float turnDirection; float turnLength; if (MathF.Abs(body.AngularVelocity) > blueprint.MaxTurnSpeed * 0.25f) { turnDirection = MathF.Sign(body.AngularVelocity); turnLength = (turnDirection == shortestTurnDirection) ? shortestTurnLength : (MathF.RadAngle360 - shortestTurnLength); } else { turnDirection = shortestTurnDirection; turnLength = shortestTurnLength; } float turnSpeedRatio = MathF.Min(turnLength * 0.25f, MathF.RadAngle30) / MathF.RadAngle30; float turnVelocity = turnSpeedRatio * turnDirection * blueprint.MaxTurnSpeed * this.targetAngleRatio; float angularVelocityChange = (turnVelocity - body.AngularVelocity) * blueprint.TurnPower; if (MathF.Abs(angularVelocityChange) > 0.0000001f) // Don't wake physics without actually doing work { body.AngularVelocity += angularVelocityChange * Time.TimeMult; } } // Weapon cooldown this.weaponTimer = MathF.Max(0.0f, this.weaponTimer - Time.MsPFMult * Time.TimeMult); // Play the owners special flight sound, when available if (this.owner != null && this.owner.FlightLoop != null) { SoundListener listener = Scene.Current.FindComponent <SoundListener>(); Vector3 listenerPos = listener.GameObj.Transform.Pos; // Determine the target panning manually, because we don't want a true 3D sound here (doppler, falloff, ...) float targetPanning; if (listenerPos.Xy == transform.Pos.Xy || Player.AlivePlayers.Count() <= 1) { targetPanning = 0.0f; } else { targetPanning = -Vector2.Dot(Vector2.UnitX, (listenerPos - transform.Pos).Xy.Normalized); } // Determine the target volume float targetVolume = MathF.Clamp(this.targetThrust.Length, 0.0f, 1.0f); // Clean up disposed flight loop if (this.flightLoop != null && this.flightLoop.Disposed) { this.flightLoop = null; } // Start the flight loop when requested if (targetVolume > 0.0f && this.flightLoop == null) { if ((int)Time.MainTimer.TotalMilliseconds % 2976 <= (int)Time.MsPFMult) { this.flightLoop = DualityApp.Sound.PlaySound(this.owner.FlightLoop); this.flightLoop.Looped = true; } } // Configure existing flight loop if (this.flightLoop != null) { this.flightLoop.Volume += (targetVolume - this.flightLoop.Volume) * 0.05f * Time.TimeMult; this.flightLoop.Panning += (targetPanning - this.flightLoop.Panning) * 0.05f * Time.TimeMult; } } // Display the damage effect when damaged if (this.hitpoints < 0.85f && blueprint.DamageEffect != null) { // Create a new damage effect instance, if not present yet if (this.damageEffect == null) { GameObject damageObj = blueprint.DamageEffect.Res.Instantiate(transform.Pos); damageObj.Parent = this.GameObj; this.damageEffect = damageObj.GetComponent <ParticleEffect>(); if (this.damageEffect == null) { throw new NullReferenceException(); } } // Configure the damage effect foreach (ParticleEmitter emitter in this.damageEffect.Emitters) { if (emitter == null) { continue; } emitter.BurstDelay = new Range(50.0f + this.hitpoints * 50.0f, 100.0f + this.hitpoints * 300.0f); if (this.owner != null) { ColorHsva targetColor = this.owner.Color.ToHsva(); emitter.MinColor = new ColorHsva(targetColor.H, targetColor.S, emitter.MinColor.V, emitter.MinColor.A); emitter.MaxColor = new ColorHsva(targetColor.H, targetColor.S, emitter.MaxColor.V, emitter.MaxColor.A); } } } // Get rid of existing damage effects, if no longer needed else if (this.damageEffect != null) { // Stop emitting and dispose when empty foreach (ParticleEmitter emitter in this.damageEffect.Emitters) { if (emitter == null) { continue; } emitter.BurstDelay = float.MaxValue; } this.damageEffect.DisposeWhenEmpty = true; this.damageEffect = null; } }
public void WriteStoryboards(List <IInstance> instances, bool isRoot) { // write storyboard info //<Canvas.Triggers> // <EventTrigger RoutedEvent="FrameworkElement.Loaded"> // <BeginStoryboard> // <Storyboard SlipBehavior="Slip"> // ... // </Storyboard> // </BeginStoryboard> // </EventTrigger> //</Canvas.Triggers> xw.WriteStartElement("Canvas.Triggers"); xw.WriteStartElement("EventTrigger"); xw.WriteStartAttribute("RoutedEvent"); xw.WriteValue("FrameworkElement.Loaded"); // MediaElement.Loaded xw.WriteEndAttribute(); xw.WriteStartElement("BeginStoryboard"); xw.WriteStartElement("Storyboard"); xw.WriteStartAttribute("SlipBehavior"); xw.WriteValue("Slip"); xw.WriteEndAttribute(); for (int i = 0; i < instances.Count; i++) { if (instances[i] == null) { continue; } instances[i].InstanceId = (uint)i; instName = GetInstanceName(instances[i]); // i + timelineSeparator + timelineStack.Peek().InstanceID; if (instances[i] is Instance) { Instance instance = (Instance)instances[i]; if (v.Definitions.ContainsKey(instance.DefinitionId)) { IDefinition def = v.Definitions[instance.DefinitionId]; if (def != null && !instance.IsMask) { // write appear and disappear code for instance lifetime WriteVisibility(instance); WriteStoryboard(def, instance); } } } else if (instances[i] is SoundInstance) { SoundInstance sound = (SoundInstance)instances[i]; WriteSoundStoryboard(sound); } } // write watermark if (isWatermarking && isRoot) { WriteWatermarkStoryboards(); } xw.WriteEndElement(); xw.WriteEndElement(); xw.WriteEndElement(); xw.WriteEndElement(); }
public override bool IsPlaying(SoundInstance instance) { return instancesPlaying.Contains(instance); }
void ICmpCollisionListener.OnCollisionBegin(Component sender, CollisionEventArgs args) { RigidBodyCollisionEventArgs bodyArgs = args as RigidBodyCollisionEventArgs; if (bodyArgs == null) { return; } if (bodyArgs.OtherShape.IsSensor) { return; } // Did we collide with a ship? If it's the same that fired the bullet, ignore this Ship otherShip = args.CollideWith.GetComponent <Ship>(); if (otherShip != null && otherShip.Owner == this.owner) { return; } // Get all the objet references we'll need RigidBody otherBody = args.CollideWith.RigidBody; Transform transform = this.GameObj.Transform; RigidBody body = this.GameObj.RigidBody; BulletBlueprint blueprint = this.blueprint.Res; // Okay, let's determine where *exactly* our bullet hit RayCastData firstHit; bool hitAnything = RigidBody.RayCast(transform.Pos.Xy - body.LinearVelocity * 2, transform.Pos.Xy + body.LinearVelocity * 2, data => { if (data.Shape.IsSensor) { return(-1.0f); } return(data.Fraction); }, out firstHit); Vector3 hitPos; float hitAngle; if (hitAnything) { hitPos = new Vector3(firstHit.Pos, 0.0f); hitAngle = (-firstHit.Normal).Angle; } else { // Note that it is possible for the raycast to not hit anything, // because it is essentially a line, while our bullet is wider than zero. hitPos = transform.Pos; hitAngle = transform.Angle; } // Push around whatever we've just hit and do damage, if it was a ship otherBody.ApplyWorldImpulse(body.LinearVelocity * MathF.Min(otherBody.Mass, blueprint.ImpactMass), transform.Pos.Xy); if (otherShip != null) { otherShip.DoDamage(blueprint.Damage); } // If we hit a part of the world, spawn the world hit effect if (otherShip == null && blueprint.HitWorldEffect != null) { GameObject effectObj = blueprint.HitWorldEffect.Res.Instantiate(hitPos, hitAngle); Scene.Current.AddObject(effectObj); } // Also spawn a generic hit effect in the color of the bullet if (blueprint.HitEffect != null) { GameObject effectObj = blueprint.HitEffect.Res.Instantiate(hitPos, hitAngle); ParticleEffect effect = effectObj.GetComponent <ParticleEffect>(); if (effect != null && this.owner != null) { ColorHsva color = this.owner.Color.ToHsva(); foreach (ParticleEmitter emitter in effect.Emitters) { emitter.MaxColor = emitter.MaxColor.WithSaturation(color.S).WithHue(color.H); emitter.MinColor = emitter.MinColor.WithSaturation(color.S).WithHue(color.H); } } Scene.Current.AddObject(effectObj); } // Play hit sounds if (blueprint.HitSound != null) { SoundInstance inst = DualityApp.Sound.PlaySound3D(blueprint.HitSound, hitPos); inst.Pitch = MathF.Rnd.NextFloat(0.95f, 1.05f); } HitSoundController otherHitSound = otherBody.GameObj.GetComponent <HitSoundController>(); if (otherHitSound != null) { otherHitSound.NotifyHit(MathF.Rnd.NextFloat(0.75f, 1.0f)); } // Delete the bullet this.GameObj.DisposeLater(); }
public override bool IsPlaying(SoundInstance instance) { var effectInstance = instance.Handle as SoundEffectInstance; return(effectInstance != null && effectInstance.State == SoundState.Playing); }
void ICmpUpdatable.OnUpdate() { EnemyBlueprint blueprint = this.blueprint.Res; Transform transform = this.GameObj.Transform; RigidBody body = this.GameObj.RigidBody; Ship ship = this.GameObj.GetComponent <Ship>(); // Calculate distress caused by going in a different direction than desired float moveDistress = 0.0f; if (body.LinearVelocity.Length > 1.0f) { Vector2 actualVelocityDir = body.LinearVelocity.Normalized; Vector2 desiredVelocityDir = ship.TargetThrust; float desiredDirectionFactor = Vector2.Dot(actualVelocityDir, desiredVelocityDir); moveDistress = MathF.Clamp(1.0f - desiredDirectionFactor, 0.0f, 1.0f) * MathF.Clamp(body.LinearVelocity.Length - 0.5f, 0.0f, 1.0f); } // Do AI state handling stuff float moveTowardsEnemyRatio = 0.0f; switch (this.state) { case MindState.Asleep: { // Wake up, if there is a player near float nearestDist; GameObject nearestObj = this.GetNearestPlayerObj(out nearestDist); if (nearestObj != null && nearestDist <= WakeupDist && this.HasLineOfSight(nearestObj, true)) { this.Awake(); } // Don't move actively ship.TargetThrust = Vector2.Zero; ship.TargetAngle = MathF.Rnd.NextFloat(-MathF.RadAngle30, MathF.RadAngle30); ship.TargetAngleRatio = 0.0f; break; } case MindState.FallingAsleep: { if (this.eyeOpenValue <= 0.0001f) { this.state = MindState.Asleep; } break; } case MindState.Awaking: { if (this.eyeOpenValue >= 0.9999f) { this.state = MindState.Idle; } break; } case MindState.Idle: { // Follow, if there is a player near float nearestDist; GameObject nearestObj = this.GetNearestPlayerObj(out nearestDist); if (nearestObj != null && this.HasLineOfSight(nearestObj, false)) { if (behavior.HasFlag(BehaviorFlags.Chase)) { Transform nearestObjTransform = nearestObj.Transform; Vector2 targetDiff = nearestObjTransform.Pos.Xy - transform.Pos.Xy; ship.TargetThrust = targetDiff / MathF.Max(targetDiff.Length, 25.0f); moveTowardsEnemyRatio = ship.TargetThrust.Length; } else { ship.TargetThrust = Vector2.Zero; } ship.TargetAngle += 0.001f * Time.TimeMult; ship.TargetAngleRatio = 0.1f; this.idleTimer = MathF.Rnd.NextFloat(0.0f, SleepTime * 0.25f); if (nearestDist <= SpikeAttackMoveDist) { moveDistress = 0.0f; if (!this.spikesActive) { this.ActivateSpikes(); } } else if (ship.TargetThrust.Length > 0.1f) { if (this.spikesActive) { this.DeactivateSpikes(); } } } // Try to stay in place otherwise else { ship.TargetThrust = -body.LinearVelocity / MathF.Max(body.LinearVelocity.Length, ship.Blueprint.Res.MaxSpeed); ship.TargetAngleRatio = 0.1f; this.idleTimer += Time.MsPFMult * Time.TimeMult; if (this.spikesActive) { this.DeactivateSpikes(); } } // Blink occasionally this.blinkTimer -= Time.MsPFMult * Time.TimeMult; if (this.blinkTimer <= 0.0f) { this.RandomizeBlinkTimer(); this.BlinkEye(); } // Go to sleep if nothing happens. if (this.idleTimer > SleepTime) { this.Sleep(); } break; } } // Udpate the eyes state and visual appearance { float actualTarget = MathF.Clamp(this.eyeOpenTarget - moveDistress * 0.35f, 0.0f, 1.0f); float eyeDiff = MathF.Abs(actualTarget - this.eyeOpenValue); float eyeChange = MathF.Sign(actualTarget - this.eyeOpenValue) * MathF.Min(this.eyeSpeed, eyeDiff); this.eyeOpenValue = MathF.Clamp(this.eyeOpenValue + eyeChange * Time.TimeMult, 0.0f, 1.0f); if (this.eyeBlinking && this.eyeOpenValue <= this.eyeOpenTarget + 0.0001f) { this.eyeOpenTarget = 1.0f; } if (this.eye != null) { this.eye.AnimTime = this.eyeOpenValue; } } // Update the spikes state and visual appearance for (int i = 0; i < this.spikeState.Length; i++) { float actualTarget = MathF.Clamp(this.spikeState[i].OpenTarget - moveDistress, 0.0f, 1.0f); if (actualTarget > this.spikeState[i].OpenValue) { Vector2 spikeDir; switch (i) { default: case 0: spikeDir = new Vector2(1, -1); break; case 1: spikeDir = new Vector2(1, 1); break; case 2: spikeDir = new Vector2(-1, 1); break; case 3: spikeDir = new Vector2(-1, -1); break; } Vector2 spikeBeginWorld = transform.GetWorldPoint(spikeDir * 4); Vector2 spikeEndWorld = transform.GetWorldPoint(spikeDir * 11); bool hitAnything = false; RigidBody.RayCast(spikeBeginWorld, spikeEndWorld, data => { if (data.Shape.IsSensor) { return(-1); } if (data.Body == body) { return(-1); } Ship otherShip = data.GameObj.GetComponent <Ship>(); if (otherShip != null && otherShip.Owner != null) { return(-1); } hitAnything = true; return(0); }); if (hitAnything) { actualTarget = 0.0f; } } float spikeMoveDir = MathF.Sign(actualTarget - this.spikeState[i].OpenValue); this.spikeState[i].OpenValue = MathF.Clamp(this.spikeState[i].OpenValue + spikeMoveDir * this.spikeState[i].Speed * Time.TimeMult, 0.0f, 1.0f); if (this.spikeState[i].Blinking && this.spikeState[i].OpenValue <= this.spikeState[i].OpenTarget + 0.0001f) { this.spikeState[i].OpenTarget = 1.0f; this.spikeState[i].Speed = Time.SPFMult / MathF.Rnd.NextFloat(0.25f, 1.0f); } // If we're extending a spike where the sensor has already registered a contact, explode if (this.spikeState[i].OpenValue > 0.75f && this.spikeState[i].ContactCount > 0) { this.FireExplosives(); } } if (this.spikes != null) { for (int i = 0; i < this.spikes.Length; i++) { if (this.spikes[i] == null) { continue; } Rect spikeRect = this.spikes[i].Rect; spikeRect.Y = MathF.Lerp(3.5f, -4.5f, this.spikeState[i].OpenValue); this.spikes[i].Rect = spikeRect; } } // Make a sound while moving if (blueprint.MoveSound != null) { // Determine the target volume float targetVolume = MathF.Clamp(moveTowardsEnemyRatio, 0.0f, 1.0f); // Clean up disposed loop if (this.moveSoundLoop != null && this.moveSoundLoop.Disposed) { this.moveSoundLoop = null; } // Start the loop when requested if (targetVolume > 0.0f && this.moveSoundLoop == null) { this.moveSoundLoop = DualityApp.Sound.PlaySound3D(blueprint.MoveSound, this.GameObj); this.moveSoundLoop.Looped = true; } // Configure existing loop and dispose it when no longer needed if (this.moveSoundLoop != null) { this.moveSoundLoop.Volume += (targetVolume - this.moveSoundLoop.Volume) * 0.05f * Time.TimeMult; if (this.moveSoundLoop.Volume <= 0.05f) { this.moveSoundLoop.FadeOut(0.1f); this.moveSoundLoop = null; } } } // Make a danger sound while moving with spikes out if (blueprint.AttackSound != null) { // Determine the target volume float targetVolume = this.spikesActive ? MathF.Clamp(moveTowardsEnemyRatio, 0.25f, 1.0f) : 0.0f; // Clean up disposed loop if (this.dangerSoundLoop != null && this.dangerSoundLoop.Disposed) { this.dangerSoundLoop = null; } // Start the loop when requested if (targetVolume > 0.0f && this.dangerSoundLoop == null) { this.dangerSoundLoop = DualityApp.Sound.PlaySound3D(blueprint.AttackSound, this.GameObj); this.dangerSoundLoop.Looped = true; } // Configure existing loop and dispose it when no longer needed if (this.dangerSoundLoop != null) { this.dangerSoundLoop.Volume += (targetVolume - this.dangerSoundLoop.Volume) * 0.1f * Time.TimeMult; if (this.dangerSoundLoop.Volume <= 0.05f) { this.dangerSoundLoop.FadeOut(0.1f); this.dangerSoundLoop = null; } } } }
void ICmpUpdatable.OnUpdate() { GamepadInput gamepad = DualityApp.Gamepads[0]; Vector2 moveDir = gamepad.LeftThumbstick.Normalized; float moveSpeed = MathF.Clamp((gamepad.LeftThumbstick.Length - 0.3f) / 0.7f, 0.0f, 1.0f); Vector2 lookDir = gamepad.RightThumbstick.Normalized; float lookIntensity = MathF.Clamp((gamepad.RightThumbstick.Length - 0.3f) / 0.7f, 0.0f, 1.0f); this.controlTarget.ThrusterActivity = moveDir * moveSpeed; this.controlTarget.RotateActivity = lookDir * lookIntensity; if (gamepad.RightTrigger > 0.5f) { this.controlTarget.FireWeapons(); } if (gamepad.ButtonHit(GamepadButton.Start)) { if (musicInstance != null && !musicInstance.Disposed) { musicInstance.Lowpass = 1.0f; } Scene.Reload(); } if (gamepad.ButtonHit(GamepadButton.Back)) { DualityApp.Terminate(); } if (musicInstance == null || musicInstance.Disposed) { musicInstance = DualityApp.Sound.PlaySound(this.backgroundMusic); musicInstance.Looped = true; musicInstance.Volume = 0.4f; musicInstance.BeginFadeIn(5.0f); } else { float targetLowPass = 1.0f; if (this.controlTarget == null || this.controlTarget.Disposed) { targetLowPass = 0.05f; } else { targetLowPass = 1.0f; } float changeDir = MathF.Sign(targetLowPass - musicInstance.Lowpass); float changeAbs = MathF.Abs(targetLowPass - musicInstance.Lowpass); if (changeAbs <= 0.01f) { musicInstance.Lowpass = targetLowPass; } else { musicInstance.Lowpass += changeDir * Time.TimeMult * Time.SPFMult / 8.0f; } } }
void ICmpUpdatable.OnUpdate() { if (this.character == null) { return; } if (this.bgTrack == null || this.bgTrack.Disposed) { this.bgTrack = DualityApp.Sound.PlaySound(this.bgMusic); this.bgTrack.Looped = true; this.bgTrack.FadeIn(2.0f); } if (DualityApp.Keyboard.KeyHit(Key.Q) || DualityApp.Gamepads.Any((arg) => arg.ButtonHit(GamepadButton.A))) { GrabObjects(); } if (DualityApp.Keyboard.KeyReleased(Key.Q) || DualityApp.Gamepads.Any((arg) => arg.ButtonReleased(GamepadButton.A))) { DropObjects(); } // Keyboard character controls using WASD Vector2 movement = Vector2.Zero; if (DualityApp.Keyboard[Key.A]) { movement -= Vector2.UnitX; } if (DualityApp.Keyboard[Key.D]) { movement += Vector2.UnitX; } if (DualityApp.Keyboard[Key.W]) { movement -= Vector2.UnitY; } if (DualityApp.Keyboard[Key.S]) { movement += Vector2.UnitY; } // Gamepad character controls using the left stick for (int i = 0; i < DualityApp.Gamepads.Count; i++) { // Those sticks can be a bit inaccurate / loose and report values up // to around 0.25f without any player interaction. Filter those values // out with a threshold, so we only move when the stick is actually moved // around. Vector2 thresholdedStick = DualityApp.Gamepads[i].LeftThumbstick; thresholdedStick = Vector2.FromAngleLength( thresholdedStick.Angle, MathF.Max(thresholdedStick.Length - 0.3f, 0.0f) / 0.7f); movement += thresholdedStick; } // Make sure not to exceed the unit vector if (movement.Length > 1.0f) { movement = movement.Normalized; } this.character.TargetMovement = movement; }
protected override void CreateChannel(SoundInstance instanceToAdd) { var handle = AL.GenSource(); AL.Source(handle, ALSourcei.Buffer, bufferHandle); instanceToAdd.Handle = handle; }
private void UpdateInstanceParams(SoundInstance sound) { sound.Volume = this.IsMuted ? 0 : 1; sound.Pitch = this.Speed - 1; }
protected override void CreateChannel(SoundInstance instanceToFill) { if (buffer == null || xAudio == null) return; var source = new SourceVoice(xAudio, format, true); source.StreamEnd += () => instancesPlaying.Remove(instanceToFill); instanceToFill.Handle = source; }
void UpdateSoundInstance(SoundInstance sfx) { if (!sfx.sound.loop && sfx.normTime >= 1.0f) { RemoveSound(sfx, wasDestroyed: false); return; } float fadeInMix = 1.0f; float fadeOutMix = 1.0f; if (sfx.sound.loop) { // TODO: Not sure what to use for delta time. Think normal one makes most sense if (sfx.loopingData.fadingOut) { sfx.loopingData.fadeOutTimer += Time.deltaTime; float fadeOutAlpha = sfx.loopingData.fadeOutTimer / sfx.sound.fadeOutTime; fadeOutMix = 1.0f - Mathf.Clamp01(fadeOutAlpha); if (sfx.loopingData.fadeOutTimer >= sfx.sound.fadeOutTime) { RemoveSound(sfx, wasDestroyed: false); return; } } if (sfx.sound.fadeInTime > 0.0f) { sfx.loopingData.fadeInTimer += Time.deltaTime; float fadeInAlpha = sfx.loopingData.fadeInTimer / sfx.sound.fadeInTime; fadeInMix = Mathf.Clamp01(fadeInAlpha); } } else { float fadeOutStart = sfx.oneShotData.startedFadingOutAt ?? sfx.length - sfx.sound.fadeOutTime; if (sfx.time >= fadeOutStart) { if (sfx.oneShotData.startedFadingOutAt == null) { sfx.oneShotData.startedFadingOutAt = sfx.time; } float fadeOutAlpha = Mathf.InverseLerp( fadeOutStart, fadeOutStart + sfx.sound.fadeOutTime, sfx.time ); fadeOutMix = 1.0f - Mathf.Clamp01(fadeOutAlpha); if (fadeOutMix <= 0.0f) { RemoveSound(sfx, wasDestroyed: false); return; } } float fadeInAlpha = sfx.time / sfx.sound.fadeInTime; fadeInMix = Mathf.Clamp01(fadeInAlpha); } sfx.fadeVolume = fadeInMix * fadeOutMix; //DbgValues.Set(sfx, "fade in mix", fadeInMix); //DbgValues.Set(sfx, "fade out mix", fadeOutMix); //DbgValues.Set(sfx, "fade volume", sfx.fadeVolume); sfx.RefreshSourceVolume(); }
public override bool IsPlaying(SoundInstance instanceToCheck) { int channelHandle = (int)instanceToCheck.Handle; return(channelHandle != InvalidHandle && openAL.IsPlaying(channelHandle)); }
public void RemoveInstance(SoundInstance instance) { if (_instances != null) { if (_instances.Remove(instance)) { _sound.Dispose(); } } }
protected override void OnFixedUpdate(float timeMult) { base.OnFixedUpdate(timeMult); if (frozenTimeLeft > 0) { return; } canJump = false; Vector3 pos = Transform.Pos; if (attackCooldown < 0f) { attackCooldown = 40f; Vector3 targetPos; List <Player> players = api.Players; for (int i = 0; i < players.Count; i++) { targetPos = players[i].Transform.Pos; direction = (targetPos.Xy - pos.Xy); float length = direction.Length; if (length < 320f && targetPos.Y < api.WaterLevel) { direction.Normalize(); speedX = 0f; speedY = 0f; IsFacingLeft = (direction.X < 0f); state = StateAttacking; idleTime = MathF.Rnd.NextFloat(40f, 60f); attackCooldown = MathF.Rnd.NextFloat(130f, 200f); noise = PlaySound("Noise", 0.8f); break; } } } else { if (state == StateAttacking) { if (idleTime < 0f) { state = StateBraking; if (noise != null) { noise.FadeOut(1f); noise = null; } } else { idleTime -= timeMult; speedX += direction.X * 0.14f * timeMult; speedY += direction.Y * 0.14f * timeMult; } } else if (state == StateBraking) { speedX *= 0.88f / timeMult; speedY *= 0.88f / timeMult; if (MathF.Abs(speedX) < 0.01f && MathF.Abs(speedY) < 0.01f) { state = StateIdle; } } else { if (idleTime < 0f) { float x = MathF.Rnd.NextFloat(-0.4f, 0.4f); float y = MathF.Rnd.NextFloat(-2f, 2f); speedX = (speedX + x) * 0.2f; speedY = (speedY + y) * 0.2f; idleTime = 20f; } else { idleTime -= timeMult; } } // Can't fly into the water if (pos.Y > api.WaterLevel - 12f) { speedY = -0.4f; state = StateIdle; if (noise != null) { noise.FadeOut(0.4f); noise = null; } } attackCooldown -= timeMult; } }
/// <summary> /// Update Method /// </summary> /// <param name="gameTime">Current Game Time</param> protected override void Update(TimeSpan gameTime) { WaveServices.Layout.PerformLayout(); switch (_scene.GameState) { case GameStateEnum.Automatic: if (_timer == null) { _soundManager.PlaySound(SimpleSoundService.SoundType.Timer, 1f, true); _timer = WaveServices.TimerFactory.CreateTimer("TimeToWait", TimeSpan.FromSeconds(1f), () => { _time--; _scene.TimerLeftTextBlock.Text = _time + " s"; }); } else if (_time <= 0) { WaveServices.TimerFactory.RemoveTimer("TimeToWait"); _scene.TimerLeftTextBlock.Text = "- s"; if (_timer2 == null) { _soundManager.StopAllSounds(); _revoluteJoint.EnableMotor = true; _timer2 = WaveServices.TimerFactory.CreateTimer("TimeToAceletare", TimeSpan.FromSeconds(1f), () => { _aceleratingTime--; }); } if (_aceleratingTime <= 0) { WaveServices.TimerFactory.RemoveTimer("TimeToAceletare"); _revoluteJoint.EnableMotor = false; } } break; case GameStateEnum.Manual: WaveServices.TimerFactory.RemoveAllTimers(); _timer = null; _timer2 = null; _scene.TimerLeftTextBlock.Text = "- s"; _revoluteJoint.EnableMotor = false; _touchState = WaveServices.Input.TouchPanelState; if (_touchState.IsConnected) { // Checks Mouse Left Button Click and anyone entity linked if (_touchState.Count > 0 && _mouseJoint == null) { foreach (var touch in _touchState) { // Updates Mouse Position _touchPosition = touch.Position; // Adjust the position to the Viewport. _scene.VirtualScreenManager.ToVirtualPosition(ref _touchPosition); // Collider Test var collider = _needleImage.FindComponent <CircleCollider2D>(); if (collider != null && collider.Contain(_touchPosition)) { var rigidBody = _needleImage.FindComponent <RigidBody2D>(); if (rigidBody != null) { _touchingId = touch.Id; // Create Mouse Joint _mouseJoint = new MouseJoint2D() { Target = _touchPosition }; _needleImage.AddComponent(_mouseJoint); // We break after collide because no more than one touch can be Joint to entity. break; } } } } // If joint exists then update joint anchor position. // If touchReleased Then touchFound = false; so Remove the Joint to conserve physics. if (_mouseJoint != null) { TouchLocation touchLocation; if (_touchState.TryGetTouch(_touchingId, out touchLocation)) { _touchPosition = touchLocation.Position; _scene.VirtualScreenManager.ToVirtualPosition(ref _touchPosition); _mouseJoint.Target = _touchPosition; } else { if (!_needleImage.IsDisposed) { _needleImage.RemoveComponent <MouseJoint2D>(); } _mouseJoint = null; } } } break; } // Collision with pieces when the needle stops. float angularVelocity = _needleImageRigidBody2D.AngularVelocity; if (!_stopRepeat && angularVelocity > -0.005f && angularVelocity < 0.005f) { _soundManager.StopAllSounds(); Movement movement = RouletteHelper.GetMovementFromRotation(_needleImage.FindComponent <Transform2D>().Rotation); movement.Number = _movementsCount++; movement.NumberOfPlayers = _scene.NumberOfPlayers; _noMovementsTextBlock.IsVisible = false; _movementsTextBlockText.Text += "\n" + movement.ToString(); if (_scene.GameState == GameStateEnum.Automatic) { ResetAutomaticTimers(); } _soundManager.PlaySound(SimpleSoundService.SoundType.Pick); _stopRepeat = true; } // When needle start to ride, it's time to another movement if (angularVelocity > 0.01f || angularVelocity < -0.01f) { _stopRepeat = false; } if (angularVelocity > 2f || angularVelocity < -2f) { if (_sound == null || _sound.State == SoundState.Stopped) { _sound = _soundManager.PlaySound(SimpleSoundService.SoundType.Rotating); } } }
public override void Start() { base.Start(); m_Radius = 1.9f; // VertexPositionNormalTexture is the layout that the engine uses in the shaders var vBuffer = Xenko.Graphics.Buffer.Vertex.New(GraphicsDevice, new VertexPositionNormalTexture[] { new VertexPositionNormalTexture(new Vector3(1.9f, -0.4f, 0), new Vector3(0, 1, 1), new Vector2(0, 0)), // Far left edge Bottom line new VertexPositionNormalTexture(new Vector3(0.7f, 0.4f, 0), new Vector3(0, 1, 1), new Vector2(0, 0)), // Top line left edge new VertexPositionNormalTexture(new Vector3(0.3f, 1.1f, 0), new Vector3(0, 1, 1), new Vector2(0, 0)), // new VertexPositionNormalTexture(new Vector3(-0.3f, 1.1f, 0), new Vector3(0, 1, 1), new Vector2(0, 0)), // new VertexPositionNormalTexture(new Vector3(-0.7f, 0.4f, 0), new Vector3(0, 1, 1), new Vector2(0, 0)), // Top line right edge new VertexPositionNormalTexture(new Vector3(-1.9f, -0.4f, 0), new Vector3(0, 1, 1), new Vector2(0, 0)), // Right edge bottom line new VertexPositionNormalTexture(new Vector3(-0.8f, -1.1f, 0), new Vector3(0, 1, 1), new Vector2(0, 0)), // new VertexPositionNormalTexture(new Vector3(0.8f, -1.1f, 0), new Vector3(0, 1, 1), new Vector2(0, 0)), // new VertexPositionNormalTexture(new Vector3(1.9f, -0.4f, 0), new Vector3(0, 1, 1), new Vector2(0, 0)), // Far left edge Bottom line }); MeshDraw meshDraw = new MeshDraw { PrimitiveType = PrimitiveType.LineStrip, // Tell the GPU that this is a line. VertexBuffers = new[] { new VertexBufferBinding(vBuffer, VertexPositionNormalTexture.Layout, vBuffer.ElementCount) }, DrawCount = vBuffer.ElementCount }; Mesh mesh = new Mesh(); mesh.Draw = meshDraw; Model model = new Model(); model.Add(mesh); m_UFOMesh = new ModelComponent(model); m_UFO = new Entity(); m_UFO.Add(m_UFOMesh); this.Entity.AddChild(m_UFO); // Top inside lines for UFO var vBufferti = Xenko.Graphics.Buffer.Vertex.New(GraphicsDevice, new VertexPositionNormalTexture[] { new VertexPositionNormalTexture(new Vector3(0.7f, 0.4f, 0), new Vector3(0, 1, 1), new Vector2(0, 0)), // Top inside line left new VertexPositionNormalTexture(new Vector3(-0.7f, 0.4f, 0), new Vector3(0, 1, 1), new Vector2(0, 0)), // Top inside line right }); MeshDraw meshDrawti = new MeshDraw { PrimitiveType = PrimitiveType.LineStrip, // Tell the GPU that this is a line. VertexBuffers = new[] { new VertexBufferBinding(vBufferti, VertexPositionNormalTexture.Layout, vBufferti.ElementCount) }, DrawCount = vBufferti.ElementCount }; Mesh meshti = new Mesh(); meshti.Draw = meshDrawti; Model modelti = new Model(); modelti.Add(meshti); m_UFOTIMesh = new ModelComponent(modelti); Entity UFOti = new Entity(); UFOti.Add(m_UFOTIMesh); m_UFO.AddChild(UFOti); // Bottom inside lines for UFO var vBufferbi = Xenko.Graphics.Buffer.Vertex.New(GraphicsDevice, new VertexPositionNormalTexture[] { new VertexPositionNormalTexture(new Vector3(1.9f, -0.4f, 0), new Vector3(0, 1, 1), new Vector2(0, 0)), // Bottom inside line left new VertexPositionNormalTexture(new Vector3(-1.9f, -0.4f, 0), new Vector3(0, 1, 1), new Vector2(0, 0)) // Bottom inside line right }); MeshDraw meshDrawbi = new MeshDraw { PrimitiveType = PrimitiveType.LineStrip, // Tell the GPU that this is a line. VertexBuffers = new[] { new VertexBufferBinding(vBufferbi, VertexPositionNormalTexture.Layout, vBufferbi.ElementCount) }, DrawCount = vBufferbi.ElementCount }; Mesh meshbi = new Mesh(); meshbi.Draw = meshDrawbi; Model modelbi = new Model(); modelbi.Add(meshbi); m_UFOBIMesh = new ModelComponent(modelbi); Entity UFObi = new Entity(); UFObi.Add(m_UFOBIMesh); m_UFO.AddChild(UFObi); Destroy(); Prefab myShotPrefab = Content.Load <Prefab>("Shot"); Entity shot = myShotPrefab.Instantiate().First(); SceneSystem.SceneInstance.RootScene.Entities.Add(shot); m_Shot = shot.Components.Get <Shot>(); m_ExplodeSoundInstance = Content.Load <Sound>("UFOExplosion").CreateInstance(); m_ExplodeSoundInstance.Volume = 0.50f; m_FireSoundInstance = Content.Load <Sound>("UFOShot").CreateInstance(); m_FireSoundInstance.Volume = 0.15f; m_LargeUFOSoundInstance = Content.Load <Sound>("UFOLarge").CreateInstance(); m_LargeUFOSoundInstance.Volume = 0.15f; m_SmallUFOSoundInstance = Content.Load <Sound>("UFOSmall").CreateInstance(); m_SmallUFOSoundInstance.Volume = 0.15f; }
static void Player(ContentRef <Sound> s, bool loopable) { sfx = DualityApp.Sound.PlaySound(s); sfx.Volume = File.Res.sfxVol * Vol; sfx.Looped = loopable; }
void ICmpUpdatable.OnUpdate() { EnemyBlueprint blueprint = this.blueprint.Res; Transform transform = this.GameObj.Transform; RigidBody body = this.GameObj.GetComponent<RigidBody>(); Ship ship = this.GameObj.GetComponent<Ship>(); // Calculate distress caused by going in a different direction than desired float moveDistress = 0.0f; if (body.LinearVelocity.Length > 1.0f) { Vector2 actualVelocityDir = body.LinearVelocity.Normalized; Vector2 desiredVelocityDir = ship.TargetThrust; float desiredDirectionFactor = Vector2.Dot(actualVelocityDir, desiredVelocityDir); moveDistress = MathF.Clamp(1.0f - desiredDirectionFactor, 0.0f, 1.0f) * MathF.Clamp(body.LinearVelocity.Length - 0.5f, 0.0f, 1.0f); } // Do AI state handling stuff float moveTowardsEnemyRatio = 0.0f; switch (this.state) { case MindState.Asleep: { // Wake up, if there is a player near float nearestDist; GameObject nearestObj = this.GetNearestPlayerObj(out nearestDist); if (nearestObj != null && nearestDist <= WakeupDist && this.HasLineOfSight(nearestObj, true)) { this.Awake(); } // Don't move actively ship.TargetThrust = Vector2.Zero; ship.TargetAngle = MathF.Rnd.NextFloat(-MathF.RadAngle30, MathF.RadAngle30); ship.TargetAngleRatio = 0.0f; break; } case MindState.FallingAsleep: { if (this.eyeOpenValue <= 0.0001f) this.state = MindState.Asleep; break; } case MindState.Awaking: { if (this.eyeOpenValue >= 0.9999f) this.state = MindState.Idle; break; } case MindState.Idle: { // Follow, if there is a player near float nearestDist; GameObject nearestObj = this.GetNearestPlayerObj(out nearestDist); if (nearestObj != null && this.HasLineOfSight(nearestObj, false)) { if (behavior.HasFlag(BehaviorFlags.Chase)) { Transform nearestObjTransform = nearestObj.Transform; Vector2 targetDiff = nearestObjTransform.Pos.Xy - transform.Pos.Xy; ship.TargetThrust = targetDiff / MathF.Max(targetDiff.Length, 25.0f); moveTowardsEnemyRatio = ship.TargetThrust.Length; } else { ship.TargetThrust = Vector2.Zero; } ship.TargetAngle += 0.001f * Time.TimeMult; ship.TargetAngleRatio = 0.1f; this.idleTimer = MathF.Rnd.NextFloat(0.0f, SleepTime * 0.25f); if (nearestDist <= SpikeAttackMoveDist) { moveDistress = 0.0f; if (!this.spikesActive) this.ActivateSpikes(); } else if (ship.TargetThrust.Length > 0.1f) { if (this.spikesActive) this.DeactivateSpikes(); } } // Try to stay in place otherwise else { ship.TargetThrust = -body.LinearVelocity / MathF.Max(body.LinearVelocity.Length, ship.Blueprint.Res.MaxSpeed); ship.TargetAngleRatio = 0.1f; this.idleTimer += Time.MsPFMult * Time.TimeMult; if (this.spikesActive) this.DeactivateSpikes(); } // Blink occasionally this.blinkTimer -= Time.MsPFMult * Time.TimeMult; if (this.blinkTimer <= 0.0f) { this.RandomizeBlinkTimer(); this.BlinkEye(); } // Go to sleep if nothing happens. if (this.idleTimer > SleepTime) { this.Sleep(); } break; } } // Udpate the eyes state and visual appearance { float actualTarget = MathF.Clamp(this.eyeOpenTarget - moveDistress * 0.35f, 0.0f, 1.0f); float eyeDiff = MathF.Abs(actualTarget - this.eyeOpenValue); float eyeChange = MathF.Sign(actualTarget - this.eyeOpenValue) * MathF.Min(this.eyeSpeed, eyeDiff); this.eyeOpenValue = MathF.Clamp(this.eyeOpenValue + eyeChange * Time.TimeMult, 0.0f, 1.0f); if (this.eyeBlinking && this.eyeOpenValue <= this.eyeOpenTarget + 0.0001f) this.eyeOpenTarget = 1.0f; if (this.eye != null) { this.eye.AnimTime = this.eyeOpenValue; } } // Update the spikes state and visual appearance for (int i = 0; i < this.spikeState.Length; i++) { float actualTarget = MathF.Clamp(this.spikeState[i].OpenTarget - moveDistress, 0.0f, 1.0f); if (actualTarget > this.spikeState[i].OpenValue) { Vector2 spikeDir; switch (i) { default: case 0: spikeDir = new Vector2(1, -1); break; case 1: spikeDir = new Vector2(1, 1); break; case 2: spikeDir = new Vector2(-1, 1); break; case 3: spikeDir = new Vector2(-1, -1); break; } Vector2 spikeBeginWorld = transform.GetWorldPoint(spikeDir * 4); Vector2 spikeEndWorld = transform.GetWorldPoint(spikeDir * 11); bool hitAnything = false; RigidBody.RayCast(spikeBeginWorld, spikeEndWorld, data => { if (data.Shape.IsSensor) return -1; if (data.Body == body) return -1; Ship otherShip = data.GameObj.GetComponent<Ship>(); if (otherShip != null && otherShip.Owner != null) return -1; hitAnything = true; return 0; }); if (hitAnything) { actualTarget = 0.0f; } } float spikeMoveDir = MathF.Sign(actualTarget - this.spikeState[i].OpenValue); this.spikeState[i].OpenValue = MathF.Clamp(this.spikeState[i].OpenValue + spikeMoveDir * this.spikeState[i].Speed * Time.TimeMult, 0.0f, 1.0f); if (this.spikeState[i].Blinking && this.spikeState[i].OpenValue <= this.spikeState[i].OpenTarget + 0.0001f) { this.spikeState[i].OpenTarget = 1.0f; this.spikeState[i].Speed = Time.SPFMult / MathF.Rnd.NextFloat(0.25f, 1.0f); } // If we're extending a spike where the sensor has already registered a contact, explode if (this.spikeState[i].OpenValue > 0.75f && this.spikeState[i].ContactCount > 0) this.FireExplosives(); } if (this.spikes != null) { for (int i = 0; i < this.spikes.Length; i++) { if (this.spikes[i] == null) continue; Rect spikeRect = this.spikes[i].Rect; spikeRect.Y = MathF.Lerp(3.5f, -4.5f, this.spikeState[i].OpenValue); this.spikes[i].Rect = spikeRect; } } // Make a sound while moving if (blueprint.MoveSound != null) { // Determine the target volume float targetVolume = MathF.Clamp(moveTowardsEnemyRatio, 0.0f, 1.0f); // Clean up disposed loop if (this.moveSoundLoop != null && this.moveSoundLoop.Disposed) this.moveSoundLoop = null; // Start the loop when requested if (targetVolume > 0.0f && this.moveSoundLoop == null) { this.moveSoundLoop = DualityApp.Sound.PlaySound3D(blueprint.MoveSound, this.GameObj); this.moveSoundLoop.Looped = true; } // Configure existing loop and dispose it when no longer needed if (this.moveSoundLoop != null) { this.moveSoundLoop.Volume += (targetVolume - this.moveSoundLoop.Volume) * 0.05f * Time.TimeMult; if (this.moveSoundLoop.Volume <= 0.05f) { this.moveSoundLoop.FadeOut(0.1f); this.moveSoundLoop = null; } } } // Make a danger sound while moving with spikes out if (blueprint.AttackSound != null) { // Determine the target volume float targetVolume = this.spikesActive ? MathF.Clamp(moveTowardsEnemyRatio, 0.25f, 1.0f) : 0.0f; // Clean up disposed loop if (this.dangerSoundLoop != null && this.dangerSoundLoop.Disposed) this.dangerSoundLoop = null; // Start the loop when requested if (targetVolume > 0.0f && this.dangerSoundLoop == null) { this.dangerSoundLoop = DualityApp.Sound.PlaySound3D(blueprint.AttackSound, this.GameObj); this.dangerSoundLoop.Looped = true; } // Configure existing loop and dispose it when no longer needed if (this.dangerSoundLoop != null) { this.dangerSoundLoop.Volume += (targetVolume - this.dangerSoundLoop.Volume) * 0.1f * Time.TimeMult; if (this.dangerSoundLoop.Volume <= 0.05f) { this.dangerSoundLoop.FadeOut(0.1f); this.dangerSoundLoop = null; } } } }
/// <summary> /// Perform Run actions /// </summary> protected override void PerformRun() { // Play sound this.SoundInstance = soundPlayer.Play(this.SoundInfo, this.volume, this.loop); }
void ICmpInitializable.OnShutdown(Component.ShutdownContext context) { if (context == ShutdownContext.Deactivate) { if (this.flightLoop != null) { this.flightLoop.Dispose(); this.flightLoop = null; } } }
static void Player(ContentRef <Sound> s) { sfx = DualityApp.Sound.PlaySound(s); sfx.Volume = File.Res.sfxVol * Vol; sfx.Looped = false; }
public override bool IsPlaying(SoundInstance instanceToCheck) { var handle = (int)instanceToCheck.Handle; return handle != InvalidHandle && AL.GetSourceState(handle) == ALSourceState.Playing; }
void ICmpInitializable.OnShutdown(Component.ShutdownContext context) { if (context == ShutdownContext.Deactivate) { if (this.moveSoundInst != null) { this.moveSoundInst.Dispose(); this.moveSoundInst = null; } } }
public void OnDeactivate() { //Unload things this.backgroundMusic = null; this.backgroundMusicInstance = null; }
void ICmpUpdatable.OnUpdate() { PrismaticJointInfo joint = this.DoorJoint; if (joint == null) return; if (joint.MotorEnabled) { if (this.moveSoundInst != null && this.moveSoundInst.Disposed) this.moveSoundInst = null; bool isPanelInTargetArea = false; if (joint.MotorSpeed > 0.0f) isPanelInTargetArea = -joint.JointTranslation >= joint.UpperLimit; else isPanelInTargetArea = -joint.JointTranslation <= joint.LowerLimit; if (joint.JointSpeed <= 0.1f) { if (isPanelInTargetArea) { joint.MotorEnabled = false; joint.MotorSpeed = 0.0f; this.doorPanel.BodyType = BodyType.Static; if (this.moveSoundInst != null) { this.moveSoundInst.FadeOut(0.5f); this.moveSoundInst = null; } } } else { if (this.moveSoundInst == null) { this.moveSoundInst = DualityApp.Sound.PlaySound3D(this.moveSound, this.doorPanel.GameObj); this.moveSoundInst.FadeIn(0.5f); this.moveSoundInst.Looped = true; } this.moveSoundInst.Volume = MathF.Abs(joint.JointSpeed) / MathF.Max(MathF.Abs(this.openSpeed), MathF.Abs(this.closeSpeed)); } } }
protected override void RemoveChannel(SoundInstance instanceToRemove) { var handle = (int)instanceToRemove.Handle; if (handle != InvalidHandle) AL.DeleteSource(handle); instanceToRemove.Handle = InvalidHandle; }
public override bool IsPlaying(SoundInstance instance) { return(instancesPlaying.Contains(instance)); }
protected override void RemoveChannel(SoundInstance instanceToRemove) { var soundInstance = instanceToRemove.Handle as SourceVoice; if (soundInstance != null) { soundInstance.Stop(); soundInstance.Dispose(); } instanceToRemove.Handle = null; }
private void PressKey(int lane, List <SoundObject> values, NoteEvent pressNote = null) { if (seeking && realtime) { return; } if (skin != null) { skin.OnKeyPress(lane); } if (judge != null) { judge.OnKeyPress(lane, pressNote); } List <SoundObject> sounds = values; if (sounds == null) { sounds = new List <SoundObject>(1); int closest = -1; double closestDiff = double.MaxValue; for (int i = lastEventIndex; i < eventList.Count; i++) { double eventTimestamp = eventList[i].timestamp; double difference = eventTimestamp - currentTime; if (difference >= 2.0) { break; } NoteEvent note = eventList[i] as NoteEvent; if (note == null || note.lane != lane) { continue; } if (difference >= closestDiff) { break; } closest = i; closestDiff = Math.Abs(eventTimestamp - currentTime); } for (int i = lastEventIndex - 1; i >= 0; i--) { double eventTimestamp = eventList[i].timestamp; double difference = currentTime - eventTimestamp; if (difference >= 2.0) { break; } NoteEvent note = eventList[i] as NoteEvent; if (note == null || note.lane != lane) { continue; } if (difference >= closestDiff) { continue; } closest = i; closestDiff = Math.Abs(currentTime - eventTimestamp); } if (closest != -1) { NoteEvent noteEvent = eventList[closest] as NoteEvent; sounds.AddRange(noteEvent.sounds); } } foreach (SoundObject soundObject in sounds) { if (soundObject.soundFile == null) { continue; } if (soundObject.soundFile.data == null) { Log.Warning("Sound file not loaded: " + soundObject.name); continue; } SoundData soundData = soundObject.soundFile.data; SoundInstance instance = soundObject.CreateInstance(audioEngine, (float)chart.volume); if (realtime) { audioEngine.Play(instance, soundObject.polyphony); } else { audioEngine.PlayScheduled(currentTime, instance, soundObject.polyphony); } } }
private int LoadStream(WaveStream waveStream) { if (!isInitialized) { Error("Trying to Load Stream format for uninitialized sound manager"); } int channels, bits_per_sample, sample_rate; byte[] sound_data = null; for (int i = 0; i < managedSounds.Count; ++i) { if (managedSounds[i].refCount <= 0) { StopSound(managedSounds[i].bufferHandle); AL.DeleteBuffer(managedSounds[i].bufferHandle); managedSounds[i].bufferHandle = AL.GenBuffer(); managedSounds[i].refCount = 1; sound_data = new byte[waveStream.Length]; waveStream.Read(sound_data, 0, (int)waveStream.Length); channels = waveStream.WaveFormat.Channels; bits_per_sample = waveStream.WaveFormat.BitsPerSample; sample_rate = waveStream.WaveFormat.SampleRate; AL.BufferData(managedSounds[i].bufferHandle, GetSoundFormat(channels, bits_per_sample), sound_data, sound_data.Length, sample_rate); AL.Source(managedSounds[i].soundSource, ALSourcei.Buffer, managedSounds[i].bufferHandle); return i; } } SoundInstance newSound = new SoundInstance(); newSound.refCount = 1; newSound.bufferHandle = AL.GenBuffer(); newSound.soundSource = AL.GenSource(); sound_data = new byte[waveStream.Length]; waveStream.Read(sound_data, 0, (int)waveStream.Length); channels = waveStream.WaveFormat.Channels; bits_per_sample = waveStream.WaveFormat.BitsPerSample; sample_rate = waveStream.WaveFormat.SampleRate; AL.BufferData(newSound.bufferHandle, GetSoundFormat(channels, bits_per_sample), sound_data, sound_data.Length, sample_rate); AL.Source(newSound.soundSource, ALSourcei.Buffer, newSound.bufferHandle); managedSounds.Add(newSound); return managedSounds.Count - 1; }
/// <summary> /// Update Method /// </summary> /// <param name="gameTime">Current Game Time</param> protected override void Update(TimeSpan gameTime) { WaveServices.Layout.PerformLayout(); switch (_scene.GameState) { case GameStateEnum.Automatic: if (_timer == null) { _soundManager.PlaySound(SimpleSoundService.SoundType.Timer, 1f, true); _timer = WaveServices.TimerFactory.CreateTimer("TimeToWait", TimeSpan.FromSeconds(1f), () => { _time--; _scene.TimerLeftTextBlock.Text = _time + " s"; }); } else if (_time <= 0) { WaveServices.TimerFactory.RemoveTimer("TimeToWait"); _scene.TimerLeftTextBlock.Text = "- s"; if (_timer2 == null) { _soundManager.StopAllSounds(); _revoluteJoint.EnableMotor = true; _timer2 = WaveServices.TimerFactory.CreateTimer("TimeToAceletare", TimeSpan.FromSeconds(1f), () => { _aceleratingTime--; }); } if (_aceleratingTime <= 0) { WaveServices.TimerFactory.RemoveTimer("TimeToAceletare"); _revoluteJoint.EnableMotor = false; } } break; case GameStateEnum.Manual: WaveServices.TimerFactory.RemoveAllTimers(); _timer = null; _timer2 = null; _scene.TimerLeftTextBlock.Text = "- s"; _revoluteJoint.EnableMotor = false; _touchState = WaveServices.Input.TouchPanelState; if (_touchState.IsConnected) { // Checks Mouse Left Button Click and anyone entity linked if (_touchState.Count > 0 && _mouseJoint == null) { foreach (var touch in _touchState) { // Updates Mouse Position _touchPosition = touch.Position; // Adjust the position to the Viewport. _scene.VirtualScreenManager.ToVirtualPosition(ref _touchPosition); // Collider Test var collider = _needleImage.FindComponent <CircleCollider2D>(); if (collider != null && collider.Contain(_touchPosition)) { var rigidBody = _needleImage.FindComponent <RigidBody2D>(); if (rigidBody != null) { _touchingId = touch.Id; // Create Mouse Joint _mouseJoint = new MouseJoint2D() { Target = _touchPosition }; _needleImage.AddComponent(_mouseJoint); // We break after collide because no more than one touch can be Joint to entity. break; } } } } // If joint exists then update joint anchor position. // If touchReleased Then touchFound = false; so Remove the Joint to conserve physics. if (_mouseJoint != null) { TouchLocation touchLocation; if (_touchState.TryGetTouch(_touchingId, out touchLocation)) { _touchPosition = touchLocation.Position; _scene.VirtualScreenManager.ToVirtualPosition(ref _touchPosition); _mouseJoint.Target = _touchPosition; } else { if (!_needleImage.IsDisposed) { _needleImage.RemoveComponent <MouseJoint2D>(); } _mouseJoint = null; } } } break; } // Collision with pieces when the needle stops. var angularVelocity = _needleImageRigidBody2D.AngularVelocity; if (!_stopRepeat && angularVelocity > -0.005f && angularVelocity < 0.005f) { _soundManager.StopAllSounds(); Movement movement = RouletteHelper.GetMovementFromRotation(_needleImage.FindComponent <Transform2D>().Rotation); movement.Number = _movementsCount++; movement.NumberOfPlayers = _numberOfPlayers; Movement repeatedFingerMovement = null; switch (_numberOfPlayers) { case NumberPlayerEnum.OnePlayer: repeatedFingerMovement = _movementsList.Find(x => x.Finger == movement.Finger); if (repeatedFingerMovement != null) { if (repeatedFingerMovement.Color != movement.Color) { _movementToRemove = repeatedFingerMovement; _movementsList.Add(movement); } } else { _movementsList.Add(movement); } break; case NumberPlayerEnum.TwoPlayers: repeatedFingerMovement = _movementsList.Find(x => x.PlayerNumber != _playerPlaying && x.Finger == movement.Finger); if (repeatedFingerMovement != null) { if (repeatedFingerMovement.Color != movement.Color) { _movementToRemove = repeatedFingerMovement; _movementsList.Add(movement); } } else { _movementsList.Add(movement); } break; } _noMovementsTextBlock.IsVisible = false; _movementsTextBlockText.Text += "\n" + movement.ToString(); if (_numberOfPlayers == NumberPlayerEnum.TwoPlayers) { if (_playerPlaying == 1) { _playerPlaying++; } else { _playerPlaying--; } } if (_scene.GameState == GameStateEnum.Automatic) { ResetAutomaticTimers(); } _soundManager.PlaySound(SimpleSoundService.SoundType.Pick); _stopRepeat = true; } // When needle start to ride, it's time to another movement if (angularVelocity > 0.01f || angularVelocity < -0.01f) { _stopRepeat = false; if (_movementsList.Any(x => x.CirclePressed == null)) { GameOver(); } } if (angularVelocity > 2f || angularVelocity < -2f) { if (_sound == null || _sound.State == SoundState.Stopped) { _sound = _soundManager.PlaySound(SimpleSoundService.SoundType.Rotating); } } List <Entity> circlesPressed = new List <Entity>(); // We check the Circles to assign the collider with touch. _touchState = WaveServices.Input.TouchPanelState; if (_touchState.IsConnected) { foreach (Entity entity in _scene.EntityManager.FindAllByTag("MatCircles")) { var opacity = 1f; foreach (var touch in _touchState) { // Updates Mouse Position _touchPosition = touch.Position; _scene.VirtualScreenManager.ToVirtualPosition(ref _touchPosition); var collider = entity.FindComponent <CircleCollider2D>(); if (collider != null && collider.Contain(_touchPosition)) { circlesPressed.Add(entity); opacity = 0.5f; break; } } entity.FindComponent <Transform2D>().Opacity = opacity; } } // Check if user adds a new circle touch. foreach (var circle in circlesPressed) { if (!_movementsList.Any(x => x.CirclePressed == circle)) { var emptyMovement = _movementsList.Find(x => x.CirclePressed == null); if (emptyMovement != null && emptyMovement.Color == circle.FindComponent <Sprite>().TintColor) { emptyMovement.CirclePressed = circle; _movementsList.Remove(_movementToRemove); _movementToRemove = null; } else { GameOver(); } } } // Check if user removes a circle touch. if (circlesPressed.Count < _lastCirclesPressed.Count) { Entity circleRemoved = null; foreach (var lastCircle in _lastCirclesPressed) { if (!circlesPressed.Contains(lastCircle)) { circleRemoved = lastCircle; break; } } if (circleRemoved != null) { var movement = _movementsList.Find(x => x.CirclePressed == circleRemoved); if (movement != null && movement != _movementToRemove) { GameOver(); } } } _lastCirclesPressed = circlesPressed.ToList(); }