マイクロソフトの田中達彦です。
本連載では、Windowsストアアプリとして作成したパズルゲームである、Line Attackのプログラムを解説します。
Line Attack : http://apps.microsoft.com/webpdp/app/f11e327c-6228-4c8f-8245-ea57d65e0f09


[注意事項]

- この連載で提供するプロジェクトファイルは、サンプルとして提供しています。
- 毎回の記事で提供するプロジェクトファイルは、その時点でのソースコードです。最終バージョンのソースコードと異なる場合があります。


[今回のプロジェクトファイル]
日本語環境で起動するとUIが日本語で表示され、英語環境で起動すると英語のUIが表示されるように実装しています。
マウスで操作したときに、思ったように動かないところも微修正しています。


[英語版作成のすすめ]
せっかくWindowsストアアプリを作るのなら、なるべく多くの人に使ってもらいたいですね。
いろいろな言語に対応すれば、それだけ多くの人に遊んでもらえる可能性が広がります。
Line Attackは、日本語と英語に対応させました。
その結果、Line Attackのダウンロード先の国としては、日本以外の国が半分以上占めています。
以下の図は、このブログ記事を書いている時点の、Line Attackをダウンロードした人の国の情報です。



日本では、日本語でのブログ記事を書いていますが、それ以外の露出はしていません。
それなのに、海外の方が多く使ってくれているのです。

さらに、Line AttackのWindows Phone版に関しては、ロシアの方からメールが来ました。
内容は、「PEGIというゲームのレーティングを取っていないゲームは、ロシアではダウンロードできない。PEGIを取得して、ロシア向けにも公開してほしい」というものです。
こんなメールもらったら、めちゃうれしいですよ。
さっそくPEGIを取って、Windows PhoneのMarketplaceに再提出しました。
このあたりの情報も、本連載が一段落したら書く予定です。
という理由で、英語化がそれほど難しくないアプリであれば、英語版も作ってしまうことをお勧めします。


[リソースという考え方]
Line Attackの例をとってみても、特にゲームの場合は日本語版と英語版でプログラムが変わるということはありません。
変わるところは、表示されている文字列の部分です。
プログラムから文字列の部分を抜き出して、別のファイルにしてしまうと、言語を変えるときにその言語に対応したファイルを使えばよいことになります。
文字列や画像ファイルのようなものをリソースと呼びます。
リソースとは、日本語で資源とか供給源と訳されます。
プログラムの部分からリソースを抜き出し、そのリソースを日本語と英語に対応させれば、Windowsストアアプリがあっという間に2か国語対応になります。


[リソースファイルの作り方]
リソースファイルを作るには、以下の手順で行います。
1. Visual Studio 2012でプロジェクトファイルを開きます。
2. ソリューション エクスプローラー上に表示されているプロジェクト名上で右クリックし、[追加]-[新しいフォルダー]を選択し、strings というフォルダーを作成します。
3. その下に、en-us と ja-jp というフォルダーを作成します。
注) スクリーンショットは en フォルダーと ja フォルダーになっていますが、特に ja フォルダーのほうは ja ではなく、ja-jp にしてください
理由は後で説明します。
4. en-usフォルダーの上で右クリックして[追加]-[新しい項目]を選択します。
5. 新しい項目ダイアログが表示されたら、[リソースファイル (.resw)]を選択し、ファイル名はResources1.reswのままで[追加]ボタンを押します。



6. ja-jpフォルダーにもResource1.reswを追加します。
ここまで実行すると、下図のようになります。



en-usのリソースファイルと、ja-jpのリソースファイルに、使用する文字列を登録していきます。
Line Attackの場合は、使っている文字列が少ないので、10個程度の日本語の文字列と英語の文字列を以下のように用意するだけです。



これで文字列の用意ができました。


[リソースの使い方]
用意したリソースを使うには、まずMainPage.xaml.csの最初のusing節の中に、以下の1文を加えます。

using Windows.ApplicationModel.Resources.Core;

そして、読み込んだ文字列を入れておくためのstring型のフィールドを用意しています。

// strings for localize
string StringComplete;
string StringMove;
string StringNewRecord;
string StringNext;
string StringPrevious;
string StringRecord;
string StringSecLong;
string StringSecShort;
string StringStage;

string StringSec;

Line Attackでは、GetStringsというメソッドを作ってリソースを読み込みました。
用意しているstring型のフィールドに文字列を入れていますが、文字列を使用するときに直接文字列を読み込んでもかまいません。

private void GetStrings()
{
    ResourceMap resMap = ResourceManager.Current.MainResourceMap;

    StringComplete = resMap.GetValue("Resources/StringComplete").ValueAsString;
    StringMove = resMap.GetValue("Resources/StringMove").ValueAsString;
    StringNewRecord = resMap.GetValue("Resources/StringNewRecord").ValueAsString;
    StringNext = resMap.GetValue("Resources/StringNext").ValueAsString;
    StringPrevious = resMap.GetValue("Resources/StringPrevious").ValueAsString;
    StringRecord = resMap.GetValue("Resources/StringRecord").ValueAsString;
    StringSecLong = resMap.GetValue("Resources/StringSecLong").ValueAsString;
    StringSecShort = resMap.GetValue("Resources/StringSecShort").ValueAsString;
    StringStage = resMap.GetValue("Resources/StringStage").ValueAsString;

    StringSec = StringSecLong;

    AppBarButtonPrev.SetValue(AutomationProperties.NameProperty, StringPrevious);
    AppBarButtonNext.SetValue(AutomationProperties.NameProperty, StringNext);
           
}

あとは、前回までのプロジェクトで文字列を決め打ちで入れているとことを、これらのフィールドを使うように書き換えるだけです。
例えば、DrawAllTextメソッドにあるステージ番号とラインの移動数、そして移動数のハイスコアを表示する部分は、以下のように変わります。

(前回のプロジェクト)
textStage.Text = "Stage " + StageNumber.ToString();
textMove.Text = "Moves " + MoveLineCount.ToString();
if (MoveHighScore == 0)
    textMoveHighScore.Text = "";
else
    textMoveHighScore.Text = "Record " + MoveHighScore.ToString();


(今回のプロジェクト)
textStage.Text = StringStage + " " + StageNumber.ToString();
textMove.Text = StringMove + " " + MoveLineCount.ToString();
if (MoveHighScore == 0)
    textMoveHighScore.Text = "";
else
    textMoveHighScore.Text = StringRecord + " " + MoveHighScore.ToString();


あとは、ユーザーが設定している言語に応じて、日本語のリソースが使われるか、英語のリソースが使われるかが決まります。
言語の設定については、以下のブログ記事の4行め以下をご参照ください。
http://blogs.msdn.com/b/ttanaka/archive/2013/01/30/line-attack-windows-phone.aspx


[なぜ ja-jp なのか]

今回公開したプロジェクトでは、stringsフォルダーの下に作っているフォルダー名がjaになっています。
この状態でストアに上げようとすると、以下のように ja に相当する「日本語」の情報と、ja-jp に相当する「日本語(日本)」の2つの情報を入れなくてはいけなくなります。



これは、デフォルトの言語としてja-jpが指定されていることに加え、リソースでjaというフォルダーを追加したために、それらの2つが表示されています。
これらの入力項目は必須項目なので、実際には使われない「日本語」の情報を入れなければならなくなってしまいます。
リソースで使用するフォルダーをja-jpにしておくと、日本語に関しては「日本語(日本)」のみしか表示されなくなります。
日本語を使用している国は日本だけなのでjaでもja-jpでも違いを感じませんが、英語の場合はアメリカ英語やイギリス英語、オーストラリア英語と微妙な違いがあります。
もし、これらの違いに対応させるときには、アメリカ英語はen-us、イギリス英語はen-gb、オーストラリア英語はen-auフォルダーを作成して、リソースを追加します。

Windowsストアがサポートしている言語については、下記サイトをご参照ください。
http://msdn.microsoft.com/ja-jp/library/windows/apps/jj657969.aspx
アプリでサポートしている言語と、コントロールパネルで設定している言語によって、どの言語がアプリ上に表示されるかについては、下記サイトのいちばん下の表をご参照ください。
http://msdn.microsoft.com/ja-jp/library/windows/apps/hh967758.aspx


[マウスを使ったときの調整]

今回公開したプロジェクトでは、マウスで画面をクリックしたときに、思った方向に動かないことがあるという問題に対処しました。
いままでのプロジェクトでは、マウスクリックの直後のマウスの横方向の移動量と縦方向の移動量を比較し、水平のラインを動かすか垂直のラインを動かすかを決めていました。
しかし、ラインを水平後方に動かそうとしてマウスのボタンをクリックした瞬間に、ボタンを押すという動作がマウスを垂直方向にちょっと動かしてしまい、垂直のラインを動かすと判断するケースがありました。
そこで、GamePage_PointerMovedイベントハンドラーの該当部分のコードに黄色くマーカーした部分を追加し、少し調整しました。

delta.X = p.X - PressedPoint.X;
delta.Y = p.Y - PressedPoint.Y;

if(MoveDirection == 0 && PressedPoint.X != -1)
{
    if(Math.Abs(delta.X) > 5 || Math.Abs(delta.Y) > 5)  // adjust for mouse
    {
        if(Math.Abs(delta.X) > Math.Abs(delta.Y))
            MoveDirection = 1; // horizontal
        else if (Math.Abs(delta.X) < Math.Abs(delta.Y))
            MoveDirection = 2; // virtical
    }
}

このコードでは、マウスカーソルが縦方向または横方向に5以上動いたときのみに、動かすラインの方向を決めています。


[前後の記事]
第6回 ハイスコアの記録と表示
第8回 アプリ内購入(アプリ内課金)


マイクロソフト
田中達彦