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);