C ++クロスプラットフォームアプリケーションでのローカライズされたテキストのベストプラクティス

StackOverflow https://stackoverflow.com/questions/403747

  •  03-07-2019
  •  | 
  •  

質問

現在のC ++標準(C ++ 03)では、テキストのローカライズに関する仕様が少なすぎるため、ローカライズされたテキストを操作するときにC ++開発者の生活が通常よりも難しくなります(確かにC ++ 0x標準はここで役立ちます) )。

次のシナリオを想定(これは実際のPC-Macゲーム開発ケースからのものです):

  1. 応答(リアルタイム)アプリケーション:アプリケーションは、応答しない時間を<!> quot; notnotable <!> quot;に最小限に抑える必要があるため、実行速度が重要です。
  2. >
  3. ローカライズされたテキスト:表示されるテキストは2つ以上の言語にローカライズされています。潜在的にはもっと多く-固定数の言語を期待しないで、簡単に拡張可能です。
  4. 実行時に定義された言語:テキストをアプリケーションでコンパイルしないでください(言語ごとに1つのアプリケーションを使用しないでください)。アプリケーションの起動時に選択した言語情報を取得します。 。
  5. クロスプラットフォーム:アプリケーションはクロスプラットフォーム(Windows-Linux / Ubuntu-Mac / OSX)を念頭に置いてコーディングされているため、ローカライズされたテキストシステムもクロスプラットフォームである必要があります。
  6. スタンドアロンアプリケーション:アプリケーションは、実行に必要なすべてを提供します。環境ライブラリを使用したり、ユーザーにOS以外のもの(たとえば、ほとんどのゲームなど)のインストールを要求したりしません。

この種のアプリケーションでC ++のローカライズされたテキストを管理するためのベストプラクティスは何ですか?

昨年このことを検討しましたが、確信しているのは、std::wstringまたはstd::basic_string<ABigEnoughType>を使用してアプリケーション内のテキストを操作することだけです。 <!> quot; text display <!> quot;の作業を続けていたため、研究を停止しました。問題(リアルタイム3Dの場合)ですが、それだけでなく生のC ++でローカライズされたテキストを管理するためのいくつかのベストプラクティスがあり、<!> quot; use Unicode <!> quot;。

だから、すべてのベストプラクティス、提案、情報(クロスプラットフォームは難しいと思う)は大歓迎です!

役に立ちましたか?

解決

Black Lantern Studiosという小さなビデオゲーム会社で、私はLionel Trains DSというゲームの主任開発者でした。英語、スペイン語、フランス語、ドイツ語にローカライズしました。すべての言語を事前に知っていたため、コンパイル時にそれらを含めることが唯一のオプションでした。 (これらはROMに書き込まれます)

私たちがやったことのいくつかに関する情報を提供できます。プレイヤーの言語選択に基づいて、起動時に文字列が配列にロードされました。個々の言語は、すべての文字列が同じ順序の個別のファイルになりました。文字列1は常にゲームのタイトルであり、文字列2は常に最初のメニューオプションなどでした。 enumインデックスは非常に高速で、ゲームでは速度がすべてなので、配列をintegerからキーオフしました。 (他の回答の1つにリンクされているソリューションでは、stringルックアップを使用していますが、これは避ける傾向があります。)文字列を表示するときに、printf()タイプ関数を使用してマーカーを値に置き換えます。 <!> quot; 列車3は都市1を出発しています。 <!> quot;

今、いくつかの落とし穴があります。

1)言語間で、フレーズの順序は完全に異なります。 <!> quot; 列車3は都市1を出発しています。 <!> quot;ドイツ語に翻訳され、バックは<!> quot; City 1からTrain 3が出発しています <!> quot;になります。 %0などを使用していて、文字列が<!> quot; 列車%dが出発都市%dである場合 <!> quot;ドイツ人は最終的に<!> quot; City 3から電車1が出発します。 <!> quot;これは完全に間違っています。翻訳で同じ語順を維持するように強制することでこれを解決しましたが、かなり壊れたドイツ語になってしまいました。もう一度やる場合は、文字列と値のゼロベースの配列を入力する関数を作成します。次に、%1%2$sなどのマーカーを使用します。基本的には、配列インデックスを文字列に埋め込みます。 更新:@Jonathan Lefflerは、POSIX準拠の2$.hタイプマーカーの使用をサポートし、.lang部分が<=>に2番目の追加パラメーターでマーカーを埋めるように指示することを指摘しました。十分に高速である限り、これは非常に便利です。カスタムソリューションの方が高速な場合があるため、両方を確認してテストする必要があります。

2)言語の長さは大きく異なります。英語では30文字だったものが、ドイツ語では110文字にもなりました。これは、私たちが置いていた画面に合わないことが多いことを意味していました。これはおそらくPC / Macゲームではそれほど問題になりませんが、テキストが定義されたボックスに収まる必要がある作業をしている場合は、これを検討する必要があります。この問題を解決するために、他の言語では可能な限り多くの形容詞をテキストから削除しました。これは文を短くしましたが、少し味を失えば意味を保持しました。後で、フォントとボックスサイズを含むアプリケーションを設計し、翻訳者がテキストをボックスに収まるように独自の変更を行えるようにしました。彼らがそれを実装したかどうかはわかりません。この問題がある場合は、テキストのスクロール領域を考慮することもできます。

3)クロスプラットフォームに関しては、ローカリゼーションシステム用にほとんど純粋なC ++を作成しました。ロードするカスタムエンコードバイナリファイル、および言語テキストのCSVから<=>に変換するカスタムプログラムと、enumとファイルから言語へのマップ、および各言語の<=>を作成しました。私たちが使用した最もプラットフォーム固有のものはフォントと<=>関数でしたが、どこで開発するのにも適したものを持っているか、必要に応じて独自のものを書くことができます。

他のヒント

GNU Gettext がすべてを実行します。

受け入れられた答えに強く反対します。最初に、静的配列検索を使用してテキスト検索を高速化することに関する部分は、実行者最適化は非常に経験が浅い-テキストのレイアウトの計算とテキストのレンダリングは、ハッシュルックアップよりも2〜4桁長い時間がかかります。独自の言語ライブラリを実装する場合は、静的配列に基づいてはいけません。

しかし、これは実際には関係ありません。独自のゲームで使用する独自の言語ライブラリを作成することは無意味な時期尚早な最適化よりもさらに悪い GNU Gettext です。 、GPLを使用しているため、営利目的での使用は避けてください。代わりに、ブーストライブラリ boost.localeを使用できます。 はGettextファイルで動作し、あらゆる種類の商用および非商用プロジェクトで自由に使用および変更できます。

私が知る限り、C ++ 0x標準には追加機能はありません。委員会はこれをサードパーティのライブラリの問題と考えています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top