-1
\$\begingroup\$

So I'm using the game states (enum) to change my game screens. I have 2 songs for main menu and game playing states, respectively. To play songs, I'm using an old code example I saw at MSDN, like this:

bool songStart = false;
Song song1;
Song song2;

// LoadContent method:
song1 = Content.Load<Song>(".\\Songs\\mainMenuTheme");
song2 = Content.Load<Song>(".\\Songs\\mainGameTheme");
MediaPlayer.IsRepeating = true;

// Update method:
switch (CurrentGameState)
{
case gameState.mainMenu:
        if (CurrentGameState == gameState.mainMenu && !songStart)
    {
        MediaPlayer.Stop();
        MediaPlayer.Play(song);
        songStart = true;
    }
    else if (CurrentGameState != gameState.mainMenu && songStart == true)
    {
        MediaPlayer.Stop();
        songStart = false;
    }
break;
case gameState.gamePlaying:
        if (CurrentGameState == gameState.gamePlaying && !m_SongStart)
        {
            MediaPlayer.Stop();
            MediaPlayer.Play(song2);
            m_SongStart = true;
        }
        else if (CurrentGameState != gameState.gamePlaying && songStart == true)
        {
            MediaPlayer.Stop();
            songStart = false;
        }
break;

So if I am in mainMenu, the first song plays; when I go to gamePalying the first song stops and the second one starts playing. If I return to mainMenu, the mainMenu song plays. My issue however, is that if I click Play game and the state moves to gamePlaying there is no background music! What could've caused the problem? Please help me fix it, I'm stuck for a whole week.

\$\endgroup\$
  • \$\begingroup\$ If you're going to have different songs for each game state, why not remove the else if's and just use a TRY to stop the song, and start the correct one? It doesn't really matter if it's playing or not, you can't go from playing to playing and somehow restart the song, there will always be a gamestate change. Is this older code? I don't see a song2 ever referenced either. \$\endgroup\$ – Joe Swindell Oct 17 '14 at 14:56
  • \$\begingroup\$ The code was at MSDN under "Playing a Song" but now they replaced it with MediaLibrary()... song2 is now fixed, sorry I typed my code by hand and forgot to change it anyway, could I have an example with try? I've never used it before. \$\endgroup\$ – PowerUser Oct 17 '14 at 15:23
1
\$\begingroup\$

This is an old thread, but I noticed it didn't really have an answer. I worked up this:

switch (currentGameState)
        {
            case GameState.MainMenu:
                if (musicState == MusicState.Playing && currentGameState != lastGameState)
                {
                    MediaPlayer.Stop();
                    musicState = MusicState.NotPlaying;
                }
                if (musicState == MusicState.NotPlaying)
                {
                    MediaPlayer.Play(song_mainTheme);
                    musicState = MusicState.Playing;
                }
                break;

            case GameState.GamePlaying:
                if (musicState == MusicState.Playing && currentGameState != lastGameState)
                {
                    MediaPlayer.Stop();
                    musicState = MusicState.NotPlaying;
                }
                if (musicState == MusicState.NotPlaying)
                {
                    MediaPlayer.Play(song_actionTheme);
                    musicState = MusicState.Playing;
                }
                break;
         }

You have to make sure to assign lastGameState = currentGameState at the end of the loop, so the next time it runs through it won't start the song over 60x a second. And of course a way to switch states through the case.

\$\endgroup\$
0
\$\begingroup\$

Looking over the code you should be able to :

switch (CurrentGameState)
{
case gameState.mainMenu: 
       MediaPlayer.Stop();       
       MediaPlayer.Play(song);         
break;
case gameState.gamePlaying:           
       MediaPlayer.Stop();
       MediaPlayer.Play(song2);          
break;
}

I wasn't sure if calling .Stop() without music playing would throw an error, if it does, that's when you could do

try {
MediaPlayer.Stop();
}
     catch (exception e)
{
     // Probably do nothing.
}
\$\endgroup\$
  • \$\begingroup\$ Where should I put the try and is the above code needed for it to work? Also I think I tried without the ifs but it was lagging like hell and no music was produced at all. \$\endgroup\$ – PowerUser Oct 17 '14 at 16:40
  • \$\begingroup\$ @PowerUser it's lagging as you are calling this code 60 times per second in your update method. this should be called only once when state is changed and only then. \$\endgroup\$ – Davor Mlinaric Jan 7 '15 at 6:57
  • \$\begingroup\$ @Davor Mlinaric And what to do in that case? \$\endgroup\$ – PowerUser Jan 11 '15 at 22:55
0
\$\begingroup\$

Like in your original post, you have one boolean that is set to true only when you change state. like when you click some button in menu.

on part where you change CurrentGameState set also stateChanged to true. and this code will be exectuted only once in your update funciton.

if(stateChanged){
   MediaPlayer.Stop();  
   switch (CurrentGameState)
   {
      case gameState.mainMenu: 
         MediaPlayer.Play(song);         
      case gameState.gamePlaying:           
         MediaPlayer.Play(song2);          
   }
   stateChanged = false;
}

for such cases my mainMenu have beside Update, Draw, Reset, Dispose have Init funciton (that load textures, music, buttons, level...) that is exectued only once when somebody change state to mainMenu using similar logic.

\$\endgroup\$
  • \$\begingroup\$ I can't get this to work - the result is the same... \$\endgroup\$ – PowerUser Jan 15 '15 at 17:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.