いぬでもわかる

iOSやCocos2dxが好きでときどきAndroid。できるだけ毎日何かしら書く事を目標に頑張る。

cocos2d-x 3.0での多言語化対応

今作っているゲームが完成を迎えそうです。リリースに向けて最後の調整を行っています。その1つが多言語化対応です。多言語に対応することでターゲットとなるユーザのパイを増やすことができ少しでも多くの人にダウンロードされ遊んでもらえる可能性が増えます。そのため、僕らの母国語である日本語以外にも少なくとも話者が多い英語は対応したいところです。欲を言えば中国語も。

しかし、cocos2d-xでは多言語化の機能を提供していません。そのため、その処理は自分で各必要があります。iOSアプリ開発を行っていた方はわかると思いますが、iOSでは非常に簡単に多言語化対応を行う事ができます。以下のようにすることで、設定した言語ごとにGameTitleに対応する文字列が取得できます。コードでは、if(英語){}elseif(日本語)といったことをやらなくても良いのです。そこで、今回はiOSにならって同等の多言語化対応のメソッドの実装を行います。

//日本語の場合には、"ほげタイトル"という文字列がそれ以外の場合には"hogeTitle"が返ってきます
NSString *title = NSLocalizedString(@"GameTitle", @"");

どのように多言語化を実現しているのか簡単に説明すると、言語ごとにテキストファイルを用意し起動時に設定された言語によって読む込むテキストファイルを変更しています。テキストファイルの中には以下のようになっておりkeyとvalueで設定されています。今回作るメソッドに、keyとなる文字列を渡せば利用している言語に合わせた文字列が返ってきます。titleMenuStartを引数に渡した場合、戻り値には日本語端末では、スタートが返ってきて、それ以外の言語端末であればSTARTが返されるといったことを実現します。



前準備

まず、言語ごとにテキストファイルを用意します。起動時に設定された言語によって読む込むテキストファイルを変更しています。テキストファイルの中には以下のようになっておりkeyとvalueで設定されています。
日本語用ファイル

"titleMenuStart" = "スタート";
"titleMenuRanking" = "ランキング";
"titleMenuGallery" ="ギャラリー";

英語用ファイル

"titleMenuStart" = "START";
"titleMenuRanking" = "RANKING";
"titleMenuGallery" ="GALLERY";

ファイルの作成は、AndroidiOSどちらからもアクセスできる共有のリソースになるのでResourcesディレクトリ以下にファイルの作成を行います。New File>Resource>String fileの順に選択しテキストファイルを作成してください。ファイル名は何でも良いのですがここでは、iOSにならってLocalizable.stringsとしました。
f:id:temptation_dog:20140612173345p:plain

デフォルトでは作成したファイルを選択し、右側のペインでTypeをDefaultからPlain Textに変更してください。これは、Defaultのままだとビルド時にplistとしてバイナリに変換されてしまい意図したように動作しないためです。
f:id:temptation_dog:20140612173133p:plain

最後に右側のペインからLocalizeボタンをクリックして日本語用のファイルを追加します。英語用、日本語用のファイルそれぞれに上述ファイル内容を記載します。

実装

ここまでで前準備が終了で、ここからは実装に入っていきます。まず、今回作るLocalizedStringメソッドはNSLocalizedString同様、対象の文字列に対応するキーと文字列がなかった場合に表示するコメントを引数にとります。LocalizedString内では、まず現在設定されている言語情報から日本語が設定されている場合は、ファイルの検索パスにja.lprojを追加し、それ以外の場合にはen.lprojを追加しています。これで、日本語の場合には日本語ファイルが読み込まれ、それ以外の場合には英語ファイルが読み込まれます。

const char* LocalizedString(const char* searchKey, const char* comment){
    const char* ret = comment;
    
    static map<string, string> localizable;
    if(localizable.empty()){
        FileUtils* fileUtil = FileUtils::getInstance();
        LanguageType language = Application::getInstance()->getCurrentLanguage();
        if(language == LanguageType::JAPANESE){
            fileUtil->addSearchPath("ja.lproj");
        }
        else{
            fileUtil->addSearchPath("en.lproj");
        }
}

次に読み込んだファイル内容をパースして引数に渡されたキーに対応するものがあれば返しなければcommentを返しています。

        list<string> stringLines = split(strings, ";");
        
        for(list<string>::iterator begin = stringLines.begin(), end = stringLines.end(); begin != end; ++begin){
            list<string> stringKeyValue = split(*begin, "=");
            if(stringKeyValue.size() >= 2){
                list<string>::iterator keyv = stringKeyValue.begin();
                localizable.insert(pair<string, string>(*keyv, *(++keyv)));
            }
        }

ソースはすべてgithubにあげましたので詳細はそちらを見てみてください。
ttdog/LocalizedStringForCocos2d-x · GitHub