I am trying to do some proof of concept work using Monogame, mostly for my own knowledge. One thing I am having trouble with, however, is timing sounds effects and background music to my liking.
So in my scenario I would like to play a series of SoundEffect
objects when the game first loads, and when those effects have finished, play a Song
in the background until the game is finished. When either the player or computer meets victory conditions the game will end, which involves stopping the background Song
, playing a win/lose SoundEffect
, and loading the end screen.
Here's where I started:
var open0 = Content.Load<SoundEffect>("Open0");
var open1 = Content.Load<SoundEffect>("Open1");
open0.Play();
open1.Play();
bgMusic = Content.Load<Song>("BGTrack");
MediaPlayer.Play(bgMusic);
MediaPlayer.IsRepeating = true;
MediaPlayer.Volume = 0.25f;
This approach ends up just playing all three items simultaneously. Its more noise than good game experience.
I also tried moving the Play()
method calls into an async
method and using await
on the threads, but of course Play()
doesn't return Task
so that didn't work. Likewise, SoundEffectInstance
and DynamicSoundEffectInstance
don't seem to offer any kind of awaitable method calls, unless I'm missing them.
I also tried wrapping subsequent calls in a while
loop, using the SoundEffectInstance.State
property as my logic control:
var open0 = Content.Load<SoundEffect>("Open0");
var open1 = Content.Load<SoundEffect>("Open1");
SoundEffectInstance open0Instance = open0.CreateInstance();
SoundEffectInstance open1Instance = open1.CreateInstance();
open0Instance.Play();
while (open0Instance.State != SoundState.Playing)
open1Instance.Play();
while (open0Instance.State != SoundState.Playing &&
open1Instance.State != SoundState.Playing)
{
bgMusic = Content.Load<Song>("BGTrack");
MediaPlayer.Play(bgMusic);
MediaPlayer.IsRepeating = true;
MediaPlayer.Volume = 0.25f;
}
Ugly code, but I was trying to figure out what would work...and this didn't. The first sound played and nothing else, so I'm guessing the State
property doesn't implement INotifyPropertyChanged
(although I'm not even sure that's relevant outside of MVVM now that I think about it).
The sounds at the end of the game are not giving me trouble because I can simply stop the MediaPlayer
and play my closing Effect:
MediaPlayer.Stop();
gameObjects.PlayerWinEffect.Play(1.0f, 0.0f, 0.0f);
So is there a way to control SoundEffect
and MediaPlayer
timing more explicitly?