Day 65/100 100 Days of Code

Day 65/100 100 Days of Code

Rebuild Back Better

I added music in the game's main menu.

First, I updated the CMakeLists.txt to add the audio file to the .app file.

file(GLOB MENU_MUSIC "audio/music/onceuponatime.mp3")

file(RELATIVE_PATH GET_REL_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${MENU_MUSIC} )
get_filename_component(FILE_PATH "${GET_REL_PATH}" DIRECTORY)
set_property(SOURCE "${MENU_MUSIC}" PROPERTY MACOSX_PACKAGE_LOCATION "Resources/${FILE_PATH}")

Then, I created a new AudioPlayer for the music.

// game.h
static AudioPlayer<Mix_Music> *menuMusic;

// game.cpp

AudioPlayer<Mix_Music> *Game::menuMusic = nullptr;

if (menuMusic == nullptr)
{
    menuMusic = new AudioPlayer<Mix_Music>(execpath + std::string("Resources/audio/music/onceuponatime.mp3"));
}

Everything looked fine but when I tried to run the program I was getting some errors that didn't make sense like "device not found" and "touch id error". After looking around the code to find what it might be the problem, I figured out that there was mistake in the path of the music file.

menuMusic = new AudioPlayer<Mix_Music>(execpath + std::string("/Contents/Resources/audio/music/onceuponatime.mp3"))

Then, I created an isPlaying() method that returns a Boolean value. The method calls an SDL_Mixer function which returns a non-zero value if the sound is playing.

bool isPlaying()
{
    int result = Mix_Playing(getReSult);

    if (result != 0)
    {
        return true;
    }

    return false;
}

This approach failed because the PlayAudio() method was being called even when there was a conditional statement using the isPlaying() method. Therefore, I decided to use a boolean variable and set it to true whenever the PlayAudio() method is called.

bool plays;

With the following code, the music plays and loops forever(According to the SDL Wiki, an audio file can't loop forever).

if (!menuMusic->plays)
{
    menuMusic->PlayAudio(-1, 0);
}

Now, that I read the method again, I see that I was calling the wrong function. To find out if the audio is being played, we need to use another method:

int Mix_PlayingMusic(void);

I think keeping the bool variable is the better choice here because I avoid calling two more functions.

The only thing left is to fade out the music when the player starts the game. This was very easy to accomplish.

menuMusic->StopAudio(200);