cocos2d-xで音声ファイルの名前を自動で取得してpreloadする
cocos2d-xのSimpleAudioEngineやexperimental::AudioEngineで音声ファイルを鳴らすときは、アプリ起動時等にpreloadしてから使う。
experimental::AudioEngine::preload("a.mp3");
音声ファイルがたくさんある場合は、それらのファイル名を全て指定するのが面倒だし、 ファイルを追加、削除、リネームした場合に ファイル名を間違える可能性がある。
音声ファイル名を自動で取得して、preloadするようにしたい。
Resourcesフォルダ内に、soundNames.txtという空のテキストファイルを追加する。
Resources/seフォルダ内のmp3ファイル名一覧を取得して、soundNames.txtに書き込む。
Target->Build Phasesを開き、 左上の+ボタンを押してNew Run Script Phaseを追加する。
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の上に移動する。
これで、ビルドした時にsoundNames.txtに音声ファイル名が書き込まれる。
あとは、アプリ起動時にsoundNames.txtから読み込んだファイル名を指定してpreloadする。
このプロジェクトではRRGSoundManagerというクラスで 音声を扱っているので、全ての音声ファイルをpreloadするメソッドを追加する。
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();
};
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メソッドを起動時に呼ぶ。
AppDelegate.cpp
bool AppDelegate::applicationDidFinishLaunching() {
/*中略*/
sharedSoundManager->preloadAll();
/*中略*/
return true;
}
Written on September 19, 2016