次の方法で共有


Windows ランタイム 8.x から UWP へのケース スタディ: QuizGame サンプル アプリ

このトピックでは、機能しているピア ツー ピア クイズ ゲーム WinRT 8.1 サンプル アプリを Windows 10 ユニバーサル Windows プラットフォーム (UWP) アプリに移植するケース スタディについて説明します。

ユニバーサル 8.1 アプリは、同じアプリの 2 つのバージョン (Windows 8.1 用のアプリ パッケージと Windows Phone 8.1 用の別のアプリ パッケージ) をビルドするアプリです。 QuizGame の WinRT 8.1 バージョンは、ユニバーサル Windows アプリ プロジェクトの配置を使用しますが、別のアプローチを採用し、2 つのプラットフォーム用に機能的に異なるアプリを構築します。 Windows 8.1 アプリ パッケージはクイズ ゲーム セッションのホストとして機能し、Windows Phone 8.1 アプリ パッケージはホストに対するクライアントの役割を果たします。 クイズ ゲーム セッションの 2 つの半分は、ピア ツー ピア ネットワークを介して通信します。

2つの半分をそれぞれPCと電話に合わせるのは理にかなっています。 しかし、任意のデバイスでホストとクライアントの両方を実行できれば、さらに良いのではないでしょうか? このケース スタディでは、両方のアプリを Windows 10 に移植し、ユーザーがさまざまなデバイスにインストールできる 1 つのアプリ パッケージにビルドします。

このアプリでは、ビューとビュー モデルを利用するパターンを使用します。 このクリーンな分離の結果として、このアプリの移植プロセスは、ご覧のように非常に簡単です。

このサンプルでは、カスタム UDP グループ マルチキャスト パケットを送受信するようにネットワークが構成されていることを前提としています (ほとんどのホーム ネットワークはこの前提に該当しますが、社内ネットワークはそのように構成されていない場合があります)。 このサンプルでは、TCP パケットの送受信も行います。

 

Visual Studio で QuizGame10 を開くときに、"Visual Studio 更新プログラムが必要" というメッセージが表示されたら、「TargetPlatformVersion」の手順を実行してください。

 

ダウンロード

QuizGame Universal 8.1 アプリをダウンロード。 これは、移植前のアプリの初期状態です。

QuizGame10 Windows 10 アプリをダウンロード。 これは、移植直後の状態のアプリです。

このサンプルの最新バージョンについては、GitHub を参照してください。

WinRT 8.1 ソリューション

移植するアプリである QuizGame の外観を次に示します。

Windows 上で実行されている quizgame ホスト アプリ

Windows で実行されている QuizGame ホスト アプリ

Windows Phone で実行されているクイズゲーム クライアント アプリ

Windows Phone で実行されている QuizGame クライアント アプリ

使用されている QuizGame のチュートリアル

これは、使用中のアプリの短い架空のアカウントですが、ワイヤレス ネットワーク経由で自分でアプリを試したい場合に役立つ情報を提供します。

楽しいクイズゲームがバーで行われている。 バーには大きなテレビがあり、誰もが見ることができます。 クイズマスターには、テレビに出力が表示されている PC があります。 その PC では、"ホスト アプリ" が実行されています。 クイズに参加したい人は、電話または Surface に "クライアント アプリ" をインストールするだけで済みます。

ホスト アプリはロビー モードであり、大きなテレビでは、クライアント アプリが接続する準備ができていることを宣伝しています。 アローンは、モバイル デバイスでクライアント アプリを起動します。 [ Player name テキスト ボックスに自分の名前を入力し、[ゲームに参加 ] をタップ。 ホスト アプリは、ユーザーの名前を表示して、そのユーザーが参加したことを確認し、そのクライアント アプリはゲームが開始されるのを待機していることを示します。 次に、Maxwell はモバイル デバイスで同じ手順を実行します。

クイズマスターは ゲームの開始 をクリックすると、ホスト アプリに質問と考えられる回答が表示されます (通常のフォントの太さ、灰色の色で参加しているプレイヤーの一覧も表示されます)。 同時に、参加しているクライアント デバイスのボタンに回答が表示されます。 その上に「1975」という答えがあるボタンをタップすると、すべてのボタンが無効になります。 ホストアプリでは、ジョーンの名前は緑色で塗りつぶされ(そして太字になります)、彼女の答えを受け取りました。 マクスウェルも答える。 クイズマスターは、すべてのプレイヤーの名前が緑色であることを示し、 次の質問をクリックします。

質問は、この同じサイクルで引き続き質問され、回答されます。 最後の質問がホスト アプリに表示されている場合、 Show の結果 はボタンの内容であり、次の質問 ではありません結果の表示をクリックすると、結果が表示されます。 ロビーに戻るをクリックすると、参加したプレイヤーが参加したままであるという例外を除き、ゲームライフサイクルの開始に戻ります。 しかし、ロビーに戻ると、新しいプレイヤーが参加する機会が得られ、参加したプレイヤーが退出するのに便利な時間が与えられます (ただし、参加したプレイヤーはいつでも Leave ゲームをタップして退出できます)。

ローカル テスト モード

デバイス間で分散するのではなく、1 台の PC でアプリとその対話を試すには、ローカル テスト モードでホスト アプリをビルドします。 このモードでは、ネットワークの使用が完全にバイパスされます。 代わりに、ホスト アプリの UI はウィンドウの左側にホスト部分を表示し、右側にはクライアント アプリ UI の 2 つのコピーが垂直方向に積み重ねられます (このバージョンでは、ローカル テスト モード UI は PC ディスプレイ用に固定されています。小さなデバイスには適応しません)。 これらの UI セグメントは、すべて同じアプリ内で、モック クライアント コミュニケーターを介して相互に通信します。これにより、ネットワーク経由で行われる対話がシミュレートされます。

ローカル テスト モードをアクティブにするには、 LOCALTESTMODEON (プロジェクト プロパティ内) を条件付きコンパイル シンボルとして定義し、再構築します。

Windows 10 プロジェクトへの移植

QuizGame には次の要素があります。

  • P2PHelper。 これは、ピアツーピア ネットワーク ロジックを含むポータブル クラス ライブラリです。
  • QuizGame.Windows。 これは、Windows 8.1 を対象とするホスト アプリのアプリ パッケージをビルドするプロジェクトです。
  • QuizGame.WindowsPhone。 これは、Windows Phone 8.1 を対象とするクライアント アプリのアプリ パッケージをビルドするプロジェクトです。
  • QuizGame.Shared。 これは、他の 2 つのプロジェクトの両方で使用されるソース コード、マークアップ ファイル、およびその他の資産とリソースを含むプロジェクトです。

このケース スタディでは、サポートするデバイスに関して、 ユニバーサル 8.1 アプリがある場合 で説明されている通常のオプションがあります。

これらのオプションに基づいて、QuizGame.Windows を QuizGameHost という新しい Windows 10 プロジェクトに移植します。 また、QuizGame.WindowsPhone を QuizGameClient という新しい Windows 10 プロジェクトに移植します。 これらのプロジェクトはユニバーサル デバイス ファミリを対象とするため、どのデバイスでも実行されます。 また、QuizGame.Shared ソース ファイルなどを独自のフォルダーに保持し、それらの共有ファイルを 2 つの新しいプロジェクトにリンクします。 前と同じように、すべてを 1 つのソリューションに保持し、QuizGame10 という名前を付けます。

QuizGame10 ソリューション

  • 新しいソリューションを作成し ([新しいプロジェクト]>[その他のプロジェクトの種類]>[Visual Studio ソリューション])、QuizGame10 という名前を付けます。

P2PHelper

  • ソリューションで、新しい Windows 10 クラス ライブラリ プロジェクト (New Project>Windows Universal>Class Library (Windows Universal)) を作成し、P2PHelper という名前を付けます。
  • 新しいプロジェクトからClass1.csを削除します。
  • P2PSession.cs、P2PSessionClient.cs、P2PSessionHost.csを新しいプロジェクトのフォルダーにコピーし、コピーしたファイルを新しいプロジェクトに含めます。
  • プロジェクトは、追加の変更を必要とせずにビルドされます。

共有ファイル

  • \QuizGame.Shared\ から \QuizGame10\ に、Common、Model、View、ViewModel の各フォルダーをコピーします。
  • 共通、モデル、ビュー、および ViewModel は、ディスク上の共有フォルダーを参照するときに意味します。

QuizGameHost

  • 新しい Windows 10 アプリ プロジェクト (Add>New Project>Windows Universal>Blank Application (Windows Universal)) を作成し、QuizGameHost という名前を付けます。
  • P2PHelper に参照を追加します ([参照の追加]>[プロジェクト]>[ソリューション]>[P2PHelper] の順に移動して追加)。
  • ソリューション エクスプローラーで、ディスク上の共有フォルダーごとに新しいフォルダーを作成します。 次に、作成した各フォルダーを右クリックし、 追加>Existing Item をクリックしてフォルダーを上に移動します。 適切な共有フォルダーを開き、すべてのファイルを選択し、[リンク 追加] をクリック
  • \QuizGame.Windows\ から \QuizGameHost\ に MainPage.xaml をコピーして、名前空間を QuizGameHost に変更します。
  • \QuizGame.Shared\ から \QuizGameHost\ に App.xaml をコピーして、名前空間を QuizGameHost に変更します。
  • app.xaml.csを上書きする代わりに、バージョンを新しいプロジェクトに保持し、ローカル テスト モードをサポートするために 1 つのターゲット変更を行います。 app.xaml.csで、次のコード行を置き換えます。
rootFrame.Navigate(typeof(MainPage), e.Arguments);

以下に置き換えます。

#if LOCALTESTMODEON
    rootFrame.Navigate(typeof(TestView), e.Arguments);
#else
    rootFrame.Navigate(typeof(MainPage), e.Arguments);
#endif
  • Properties>Build>conditional コンパイル シンボルに LOCALTESTMODEON を追加します。
  • これで、app.xaml.csに追加したコードに戻り、TestView の種類を解決できるようになります。
  • package.appxmanifest で、機能名を internetClient から internetClientServer に変更します。

QuizGameClient

  • 新しい Windows 10 アプリ プロジェクト (Add>New Project>Windows Universal>Blank Application (Windows Universal)) を作成し、QuizGameClient という名前を付けます。
  • P2PHelper に参照を追加します ([参照の追加]>[プロジェクト]>[ソリューション]>[P2PHelper] の順に移動して追加)。
  • ソリューション エクスプローラーで、ディスク上の共有フォルダーごとに新しいフォルダーを作成します。 次に、作成した各フォルダーを右クリックし、 追加>Existing Item をクリックしてフォルダーを上に移動します。 適切な共有フォルダーを開き、すべてのファイルを選択し、[リンク 追加] をクリック
  • \QuizGame.WindowsPhone\ から \QuizGameClient\ に MainPage.xaml をコピーして、名前空間を QuizGameClient に変更します。
  • \QuizGame.Shared\ から \QuizGameClient\ に App.xaml をコピーして、名前空間を QuizGameClient に変更します。
  • package.appxmanifest で、機能名を internetClient から internetClientServer に変更します。

これで、ビルドと実行ができるようになります。

アダプティブ UI

QuizGameHost Windows 10 アプリは、アプリが広いウィンドウ (大画面のデバイスでのみ可能) で実行されている場合に問題なく表示されます。 ただし、アプリのウィンドウが狭い場合 (小さなデバイスで発生し、大きなデバイスでも発生する可能性があります)、UI は読み取り不可能なほどにスカッシュされます。

アダプティブ Visual State Manager 機能を使用して、この問題を解決できます。これについては、 Case の調査: Bookstore2 で説明しました。 まず、ビジュアル要素のプロパティを設定して、既定では UI が狭い状態でレイアウトされるようにします。 これらの変更はすべて、\View\HostView.xaml で行います。

  • メイン Grid で、最初の RowDefinitionHeight を "140" から "Auto" に変更します。
  • TextBlock を含むGridpageTitleという名前を付け、x:Name="pageTitleGrid"Height="60"を設定します。 これら最初の 2 つの手順は、 RowDefinition の高さを視覚的な状態のセッターを介して効果的に制御できるようにするためです。
  • pageTitleで、Margin="-30,0,0,0"を設定します。
  • コメント <!-- Content -->によって示されるGridで、x:Name="contentGrid"Margin="-18,12,0,0"を設定します。
  • コメント <!-- Options -->のすぐ上にある TextBlockで、Margin="0,0,0,24"を設定します。
  • 既定の TextBlock スタイル (ファイル内の最初のリソース) で、 FontSize setter の値を "15" に変更します。
  • OptionContentControlStyleで、FontSize setter の値を "20" に変更します。 このステップと前のステップは、すべてのデバイスでうまく動作する良いタイプランプを私たちに与えます。 これらは、Windows 8.1 アプリで使用していた "30" よりもはるかに柔軟なサイズです。
  • 最後に、適切な Visual State Manager マークアップをルート Grid に追加します。
<VisualStateManager.VisualStateGroups>
    <VisualStateGroup>
        <VisualState x:Name="WideState">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="548"/>
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Target="pageTitleGrid.Height" Value="140"/>
                <Setter Target="pageTitle.Margin" Value="0,0,30,40"/>
                <Setter Target="contentGrid.Margin" Value="40,40,0,0"/>
            </VisualState.Setters>
        </VisualState>
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

ユニバーサル スタイル

Windows 10 では、ボタンのテンプレートに同じタッチ ターゲットパディングが含まれていないことがわかります。 2つの小さな変更は、これを解決します. まず、QuizGameHost と QuizGameClient の両方で、このマークアップを app.xaml に追加します。

<Style TargetType="Button">
    <Setter Property="Margin" Value="12"/>
</Style>

次に、以下の setter を \View\ClientView.xaml の OptionButtonStyle に追加します。

<Setter Property="Margin" Value="6"/>

この最後の調整により、アプリは動作し、ポートの前と同じように見え、すべての場所で実行される追加の値が追加されます。

まとめ

このケース スタディで移植したアプリは、いくつかのプロジェクト、クラス ライブラリ、および非常に大量のコードとユーザー インターフェイスを含む比較的複雑なアプリでした。 それでも、ポートは簡単でした。 移植の容易さの一部は、Windows 10 開発者プラットフォームと Windows 8.1 および Windows Phone 8.1 プラットフォームの間の類似性に直接起因します。 一部の原因は、元のアプリがモデル、ビュー モデル、ビューを分離するように設計された方法によるものです。