2015年7月29日水曜日

[cocos2dx] でローカライズに対応する【LocalizedString】


ローカライズ関数を用意した理由

理由も何もないんですが、cocos2d-xで気軽にObjective-cで利用できるようなローカライズ関数が欲しいなと思い、作成しました。

今回はそんなローカライズ関数です。



実際の関数

はじめに。
この関数は以下の記事の関数を利用しています。
cocos2d-xで文字列を置換する【Replace】
cocos2dでトリミング関数を作る【trim】
cocos2d-xで文字列をデリミタで分解しリスト化する関数を作る【split】

次にこの関数を利用するには、[ja.lproj]や[en.lproj]などのLanguageごとのフォルダを用意し、それぞれにローカライズファイル[Localizable.strings]用意する必要があります。
【ja.lproj/Localizable.strings】
test=テスト
hogehoge=ほげほげ
【en.lproj/Localizable.strings】
test=Test
hogehoge=HogeHoge

【注意】
ローカライズファイル[Localizable.strings][File Type]は、[Localizable Strings]から[Plain Text]に変更して進める必要があります。
これをしておかないと、コンパイル時にファイルが最適化され、getStringFromFile()によるロードがうまくいきません。



使い方


こんな感じで使います。
std::string result = LocalizedString("hogehoge", "ほげほげの取得");
//result は日本語環境では "ほげほげ" となります
//result は英語環境では "Hogehoge" となります

簡単な説明

static map<std::string, std::string> localizable;
ローカライズ文字列のマップデータは、静的変数にセットすることで、無駄なファイル解析を避けます。

if(localizable.empty()){
ローカライズ文字列のマップデータがない場合に、1度だけローカライズファイルを解析します。

FileUtils* fileUtil = FileUtils::getInstance();
LanguageType language = Application::getInstance()->getCurrentLanguage();
if (language == LanguageType::JAPANESE) {
    fileUtil->addSearchPath("ja.lproj");
if (language == LanguageType::★★★★) {  //ローカライズしたいLanguageTypeを指定
    fileUtil->addSearchPath("★★★★");   //LanguageTypeごとのフォルダを指定
} else {
    fileUtil->addSearchPath("en.lproj");
}
ローカライズファイルのあるディレクトリを検索対象パスに追加します。

std::string fullpath = fileUtil->fullPathForFilename("Localizable.strings");
std::string strings = fileUtil->getStringFromFile(fullpath);
if (strings == "") return ret;
ローカライズファイル(Localizable.strings)を読み込みます。

list<std::string> stringLines = split(strings, "\n");
行ごとに分解して、以降の処理を実施します。

for(list<std::string>::iterator begin = stringLines.begin(), end = stringLines.end(); begin != end; ++begin){
    list<std::string> stringKeyValue = split(*begin, "=");
    if(stringKeyValue.size() >= 2){
        list<std::string>::iterator keyv = stringKeyValue.begin();
        localizable.insert(pair<std::string, std::string>(*keyv, *(++keyv)));
    }
}
1行ごととり出し、"="でkeyとvalueに切り出し、ローカライズ文字列のマップデータに設定します。

map<std::string, std::string>::iterator iterator = localizable.find(searchKey);
if(iterator != localizable.end()){
    ret = iterator->second.c_str();
}
ローカライズ文字列のマップデータから、対象のデータを取り出し返却します。

std::string result = stringReplace(ret, "\\n", "\n");
最後に対象データの改行をケアしています。


このプログラムが皆様のお役に立てば幸いです。

ではまた。


0 件のコメント:

コメントを投稿