読者です 読者をやめる 読者になる 読者になる

夏までにiPhone アプリつくってみっか!

趣味でiPhone/Androidアプリを開発し、日々勉強した事を書いています。オープンワールド系レースゲームをUnityで開発中です。

cocos2d-xで手抜きローカライズする方法

cocos2d-x TravelShooting JP

TravelShooting JPのアンドロイド版がほぼ完成し、今は若干薄っぺらだった敵キャラの陰影を濃くて立体感を付けたりなどの改良作業を行っています。
そんな中、TravelShooting JPの絶賛予約受付中の予約トップ10をのぞいてみると、あるアプリの言語が英語版のみの対応であるばかりにコメント欄(PCからは読めないと思います)で数多くの否定的な意見が書かれていることにショックを受けました。

そう、TravelShooting JP Android版は日本語にローカライズせずに英語版のみでリリースするつもりだったのです。
恐ろしくなった私は慌ててcocos2d-xでのローカライズの方法を調べました。
iOSのNSLocalizedStringのような物のcocos2d-x版を作って公開している方がいるようなのでそれを使わせてもらおうかとも思いましたが、TravelShooting JP Android版はテキストの量がかなり少なく、コンフィグ画面やゲームオーバー画面などにちょっとだけ出てくる程度なので、NSLocalizedStringのようなローカライズ用のテキストファイルを用意せずに手抜きの方法で実装してみました。

作ったのは、引数で受けとった英語と日本語のストリングからデバイスの言語設定にあった方を返すスタティックメソッドだけを持つ非常にシンプルなクラスです。

ヘッダファイル

#include "cocos2d.h"

#define LOC(en, ja) Localize::localize(en, ja)

class Localize
{
public:
    static std::string localize(const std::string& en, const std::string& ja);
};

実装ファイル

#include "Localize.h"

USING_NS_CC;

std::string Localize::localize(const std::string& en, const std::string& ja)
{
    auto lang = Application::getInstance()->getCurrentLanguage();
    switch(lang) {
        case LanguageType::JAPANESE:
            return ja;
        default:
            return en;
    }
}

関数の引数に入れても行が長くならないようにヘッダでLOCという短縮形を#defineで定義しています。

こんな感じに、std::stringが入るところにいれて使います。
この例では、デバイスの言語設定が日本語だと"またね!"、日本語以外だと"See you again!"がstd::stringとして入ります。

auto seeYouLabel = Label::createWithBMFont("travelshootingJP.fnt", LOC("See you again!", "またね!"));

NSLocalizedStringと違って、英語と日本語が同じファイルの同じ行で対応しているので、文章の修正が簡単なのもいいですね!

StringUtils::formatの中に入れて使うこともできます。

        auto continueLabel = Label::createWithBMFont("travelshootingJP.fnt", StringUtils::format(LOC("Continue? (%d Left)", "コンティニュー? (残り%d回)").c_str(), _continue));

ゲームオーバーの画面では、デバイスの言語設定が日本語だとこの表示、
f:id:takujidev:20150408235105j:plain
日本語以外だとこのように表示されるようになりました。
f:id:takujidev:20150408235123j:plain
TravelShooting JPは日本のユーザーが一番多くなるはずなので、日本語にローカライズした事で大多数のユーザーに気持ちよく遊んで頂けるようになったと思います。