cocos2d-xで音声ファイルの名前を自動で取得してpreloadする

cocos2d-xのSimpleAudioEngineやexperimental::AudioEngineで音声ファイルを鳴らすときは、アプリ起動時等にpreloadしてから使う。

```c++
experimental::AudioEngine::preload("a.mp3");
```

音声ファイルがたくさんある場合は、それらのファイル名を全て指定するのが面倒だし、
ファイルを追加、削除、リネームした場合に
ファイル名を間違える可能性がある。

音声ファイル名を自動で取得して、preloadするようにしたい。

Resourcesフォルダ内に、soundNames.txtという空のテキストファイルを追加する。

<img width="300" alt="2016-09-19-1.png" src="https://qiita-image-store.s3.amazonaws.com/0/37640/1b49d7b3-fc0c-3cf8-97a3-448d93340b30.png">

Resources/seフォルダ内のmp3ファイル名一覧を取得して、soundNames.txtに書き込む。

Target->Build Phasesを開き、
左上の+ボタンを押してNew Run Script Phaseを追加する。

<img width="500" alt="2016-09-19-2.png" src="https://qiita-image-store.s3.amazonaws.com/0/37640/10b44115-7afa-bce5-9d8f-debb42ab3bde.png">

```shell
output="${PROJECT_DIR}/../Resources/soundNames.txt"
echo '' > $output

se="${PROJECT_DIR}/../Resources/se"
for file in `find $se -name "*.mp3"`; do
echo ${file##*/} >> $output
done
```

このRun Script PhaseはCopy Bundle Resourcesの上に移動する。

<img width="500" alt="2016-09-19-3.png" src="https://qiita-image-store.s3.amazonaws.com/0/37640/8c362fba-8156-73b2-3f47-a0fd47b98755.png">

これで、ビルドした時にsoundNames.txtに音声ファイル名が書き込まれる。

<img width="300" alt="2016-09-19-4.png" src="https://qiita-image-store.s3.amazonaws.com/0/37640/00c7e475-bea3-ff96-bb42-c765621620ad.png">

あとは、アプリ起動時にsoundNames.txtから読み込んだファイル名を指定してpreloadする。

このプロジェクトではRRGSoundManagerというクラスで
音声を扱っているので、全ての音声ファイルをpreloadするメソッドを追加する。

```c++:RRGSoundManager.h
#include "cocos2d.h"

#define sharedSoundManager RRGSoundManager::getInstance()

class RRGSoundManager : public cocos2d::Ref
{
private:
    bool _isPlaying;
    std::string _bgm;
    int _audioID;
public:
    RRGSoundManager();
    virtual ~RRGSoundManager();
    static RRGSoundManager* getInstance();
    static void destroyInstance();
    void playBGM(const std::string& bgm);
    void stopBGM();
    void playSE(const std::string& sound);
    void pauseAll();
    void resumeAll();
    //追加
    void preloadAll();
};
```

```c++:RRGSoundManager.cpp
#include "RRGSoundManager.h"
#include "audio/include/AudioEngine.h"

using namespace std;
USING_NS_CC;

/*中略*/

namespace {
    string trim(const string& str, const char* trimCharacterList = "; \t\v\r\n\"\'") {
        string result;
        string::size_type left = str.find_first_not_of(trimCharacterList);
        
        if (left != string::npos) {
            string::size_type right = str.find_last_not_of(trimCharacterList);
            result = str.substr(left, right - left + 1);
        }
        
        return result;
    }
    
    list<string> split(string str, string delim) {
        list<string> result;
        long cutAt;
        
        
        while( (cutAt = str.find_first_of(delim)) != str.npos ) {
            if(cutAt > 0) {
                result.push_back(trim(str.substr(0, cutAt)));
            }
            str = str.substr(cutAt + 1);
        }
        if(str.length() > 0) {
            result.push_back(trim(str));
        }
        
        return result;
    }
}

void RRGSoundManager::preloadAll()
{
    FileUtils* fileUtil = FileUtils::getInstance();
    string fullpath = fileUtil->fullPathForFilename("soundNames.txt");
    string strings = fileUtil->getStringFromFile(fullpath);
    
    if (strings.empty()) return;
    
    list<string> stringLines = split(strings, "\n");
    for(list<string>::iterator begin = stringLines.begin(),
        end = stringLines.end();
        begin != end;
        ++begin)
    {
        CCLOG("soundName = %s",(*begin).c_str());
        experimental::AudioEngine::preload(*begin);
    }
}
```

preloadAllメソッドを起動時に呼ぶ。

```c++:AppDelegate.cpp
bool AppDelegate::applicationDidFinishLaunching() {
	/*中略*/
	sharedSoundManager->preloadAll();
	/*中略*/
	return true;
}
```