Xamarin.Froms でパズルゲームを作る(Windows Phone版)

昨日の続きで…と言いますか、実装は昨日のうちに済ませました。移植自体は簡単で1時間かかりません。

image

ちょっと、XAMLを書き直して、コマの大きさを変えたりセンタリングしたりしています。

■ファイルアクセスは ApplicationData.Current.LocalFolder を使う

基本的なところは、iOS/Android と同じなのですが、ファイルアクセス部分がちょっとだけ違います。iOS/Android の場合は、System.Environment.GetFolderPath を使って普通のフォルダアクセス(といえ、アプリ内のフォルダだけなのですが…システムフォルダへのアクセスは要調査)と同様に使えますが、Windows Phone の場合は、ApplicationData.Current.LocalFolder を使います。これは WinRT と同じで、アプリからアクセスできるフォルダが OS 上で制限されているためですね。

このサンプルが「共有プロジェクト」を使っているのは、このためでもあって、以下のように #if でコンパイル時に分岐させます。PCL でやると、ここのコードビハイドが委譲を使ったりして面倒なので、そのままコード共有で。

var se = new XmlSerializer(typeof(MyData));
try
{
#if __IOS__ || __ANDROID__ 
    var documents =
        System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments);
    var file = System.IO.Path.Combine(documents, "mydata.xml");
    using (var stream = System.IO.File.OpenRead(file))
    {
        var m = se.Deserialize(stream) as MyData;
        m.CopyTo(_model);
    }
#else
    using (var stream = await Windows.Storage.ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(
        "mydata.xml"))
    {
        var m = se.Deserialize(stream) as MyData;
        m.CopyTo(_model);
    }
#endif
}
catch
{
    // 各スコアを0にする
    this._logic.Reset();
}

stream を取るところは一緒なので、Windows Phone で使っている OpenStreamForReadAsync メソッドを、適当に包んでやれば共有化できるのですが…まあ、このままで。気になるのは、iOS/Android で使っているのは OpenWrite で同期メソッドなんだけど、Windows Phone の OpenStreamForReadAsync は非同期メソッドってところですよね。ここは非同期に揃えたいところです。

■ゲームロジックやAzure Mobile Serivces は、PCL で

image

PCL(移植可能)を使っているのはゲームロジックとAzure Mobile Service のところです。カメラ機能とかは Xamarin.Mobile を使えば共有化できるので、シンプルなものならば結構すんなり共有化できるかなと。ただし、カメラを撮った後の遷移が各プラットフォームで若干異なるので、そのあたりはひと工夫が必要そうです。

■画像リソースはどうする?

このアプリでは、画像ファイルを

_mk[0] = ImageSource.FromFile("MarkNone.png")

な感じでファイル名を指定して直接取ってきています。ここのルートが何処を指すかというと、プラットフォーム毎に違っていて、

iOS /Resources/MarkNone.png
Android /Resources/Drawable/MarkNone.png
WinPhone /MarkNone.png

ってな感じで、Windows Phone はプロジェクト直下を示しているという…画像ファイルがちりばめられるのは嫌なので、このあたり WinPhone のために Images フォルダを作成して、

iOS /Resources/Images/MarkNone.png
Android /Resources/Drawable/Images/MarkNone.png
WinPhone /Images/MarkNone.png

とかにしたいところですね。ちなみに、Windows Phone には Resources というフォルダがあるのですが、そこは参照していません。

ただし、画像がたくさんあったり多言語化を考えると、リソースを使いたいわけで、そのあたりは Xamarin.iOS/Android で、文字列と画像をPCLを使って共有させる方法 を使って PCL にしたいところです。ここでの方法は iOS/Android しか対応していないので、WinPhone と WinRT にも拡張したいところですね。

■サンプルコード

もう少し手を入れますが、現状のは Github に
https://github.com/moonmile/TMPuzzleXForms

カテゴリー: Android, Xamarin, iOS パーマリンク