ユーザー インターフェイスの追加Add a user interface

これで、ゲームでは、場所にその 3D ビジュアルが含まれるゲームがプレーヤーにゲームの状態に関するフィードバックを提供できるように、いくつかの 2D 要素を追加することに集中する時間を勧めします。Now that our game has its 3D visuals in place, it's time to focus on adding some 2D elements so that the game can provide feedback about game state to the player. これは単純なメニュー オプションを追加することで実現でき、3-D グラフィックスの上にヘッドアップ ディスプレイのコンポーネントが出力をパイプラインします。This can be accomplished by adding simple menu options and heads-up display components on top of the 3-D graphics pipeline output.

注意

このサンプルの最新ゲーム コードをダウンロードしていない場合は、Direct3D ゲーム サンプルのページに移動してください。If you haven't downloaded the latest game code for this sample, go to Direct3D game sample. このサンプルは、UWP 機能のサンプルの大規模なコレクションの一部です。This sample is part of a large collection of UWP feature samples. サンプルをダウンロードする手順については、「GitHub から UWP のサンプルを取得する」をご覧ください。For instructions on how to download the sample, see Get the UWP samples from GitHub.

目標Objective

Direct2D を使用して、UWP の DirectX ゲームなどを多数のユーザー インターフェイスのグラフィックスと動作を追加します。Using Direct2D, add a number of user interface graphics and behaviors to our UWP DirectX game including:

ユーザー インターフェイスのオーバーレイThe user interface overlay

DirectX ゲームにテキストおよびユーザー インターフェイス要素を表示するさまざまな方法はありますが、ここにフォーカスを使用してDirect2Dします。While there are many ways to display text and user interface elements in a DirectX game, we're going to focus on using Direct2D. 使用することもDirectWriteのテキスト要素です。We'll also be using DirectWrite for the text elements.

Direct2D は、ピクセル ベース プリミティブと効果を描画するために一連の 2D 描画 Api を使用します。Direct2D is a set of 2D drawing APIs used to draw pixel-based primitives and effects. 以降 Direct2D では、ときに、複雑にならないことをお勧めします。When starting out with Direct2D, it's best to keep things simple. 複雑なレイアウトやインターフェイス動作には、時間と計画が必要です。Complex layouts and interface behaviors need time and planning. ゲームには、シミュレーションと戦略ゲームなどに見られるよう、複雑なユーザー インターフェイスが必要な場合は、代わりに XAML の使用を検討してください。If your game requires a complex user interface, like those found in simulation and strategy games, consider using XAML instead.

注意

XAML と DirectX の UWP ゲームでのユーザー インターフェイスの開発方法の詳細については、次を参照してください。ゲームのサンプルを拡張するします。For info about developing a user interface with XAML in a UWP DirectX game, see Extending the game sample.

Direct2D はされていないユーザー インターフェイスまたは HTML と XAML のようなレイアウトを具体的には設計されています。Direct2D isn't specifically designed for user interfaces or layouts like HTML and XAML. これにより、リスト、ボックス、またはボタンのようなユーザー インターフェイス コンポーネントが用意されていません。It doesn't provide user interface components like lists, boxes, or buttons. Div、テーブル、またはグリッドなどのレイアウトのコンポーネントも提供されません。It also doesn't provide layout components like divs, tables, or grids.

このゲームのサンプルについては、2 つの主な UI コンポーネントがあります。For this game sample we have two major UI components.

  1. スコアおよびゲーム内のコントロールのヘッドアップ ディスプレイ。A heads-up display for the score and in-game controls.
  2. オーバーレイのゲームの状態のテキストと一時停止の情報などのオプションを表示するために使用し、レベルがオプションを開始します。An overlay used to display game state text and options such as pause info and level start options.

Direct2D を使ったヘッドアップ ディスプレイUsing Direct2D for a heads-up display

次の図は、サンプルのゲームのヘッドアップ ディスプレイを示します。The following image shows the in-game heads-up display for the sample. 単純ですっきり、プレーヤーに 3D の世界を移動して、ターゲットを撮影できるようにします。It's simple and uncluttered, allowing the player to focus on navigating the 3D world and shooting targets. 適切なインターフェイスまたはヘッドアップ ディスプレイをする必要がありますは処理、ゲームでは、イベントに対応してプレイヤーの機能を決して複雑にします。A good interface or heads-up display must never complicate the ability of the player to process and react to the events in the game.

ゲーム オーバーレイのスクリーン ショット

オーバーレイは、次の基本的なプリミティブで構成されます。The overlay consists of the following basic primitives.

  • DirectWrite のプレーヤーに通知する右上隅にあるテキストDirectWrite text in the upper-right corner that informs the player of
    • 成功したヒット数Successful hits
    • プレーヤーが行われたショットの数Number of shots the player has made
    • レベルの残りの期間Time remaining in the level
    • 現在のレベル数Current level number
  • 2 つの十字を形成するために使用する線分の交差しません。Two intersecting line segments used to form a cross hair
  • 2 つの四角形の画面の下隅にある、移動外観コント ローラー境界。Two rectangles at the bottom corners for the move-look controller boundries.

オーバーレイのゲームのヘッドアップ ディスプレイの状態で表示されます、 GameHud::Render のメソッド、 GameHud クラス。The in-game heads-up display state of the overlay is drawn in the GameHud::Render method of the GameHud class. このメソッド内に残りとレベルの数のヒット数の変更を反映するように、Direct2D のオーバーレイを表す、UI が更新されます。Within this method, the Direct2D overlay that represents our UI is updated to reflect the changes in the number of hits, time remaining, and level number.

ゲームが初期化されたかどうかは追加TotalHits()TotalShots()、およびTimeRemaining()に、 swprintf_s バッファーし、印刷の形式を指定します。If the game has been initialized, we add TotalHits(), TotalShots(), and TimeRemaining() to a swprintf_s buffer and specify the print format. 使用して描画できますし、 DrawText メソッド。We can then draw it using the DrawText method. 同じ現在のレベルのインジケーターの描画など ➀、未完了のレベルを表示する空の番号と ➊ など、特定のレベルが完了したことを表示するの塗りつぶされた番号。We do the same for the current level indicator, drawing empty numbers to show uncompleted levels like ➀, and filled numbers like ➊ to show that the specific level was completed.

次のコード スニペットの説明、 GameHud::Renderのメソッドの処理The following code snippet walks through the GameHud::Render method's process for

void GameHud::Render(_In_ Simple3DGame^ game)
{
    auto d2dContext = m_deviceResources->GetD2DDeviceContext();
    auto windowBounds = m_deviceResources->GetLogicalSize();

    if (m_showTitle)
    {
        d2dContext->DrawBitmap(
            m_logoBitmap.Get(),
            D2D1::RectF(
                GameConstants::Margin,
                GameConstants::Margin,
                m_logoSize.width + GameConstants::Margin,
                m_logoSize.height + GameConstants::Margin
                )
            );
        d2dContext->DrawTextLayout(
            Point2F(m_logoSize.width + 2.0f * GameConstants::Margin, GameConstants::Margin),
            m_titleHeaderLayout.Get(),
            m_textBrush.Get()
            );
        d2dContext->DrawTextLayout(
            Point2F(GameConstants::Margin, m_titleBodyVerticalOffset),
            m_titleBodyLayout.Get(),
            m_textBrush.Get()
            );
    }

    // Draw text for number of hits, total shots, and time remaining
    if (game != nullptr)
    {
        // This section is only used after the game state has been initialized.
        static const int bufferLength = 256;
        static char16 wsbuffer[bufferLength];
        int length = swprintf_s(
            wsbuffer,
            bufferLength,
            L"Hits:\t%10d\nShots:\t%10d\nTime:\t%8.1f",
            game->TotalHits(),
            game->TotalShots(),
            game->TimeRemaining()
            );
        
        // Draw the upper right portion of the HUD displaying total hits, shots, and time remaining
        d2dContext->DrawText(
            wsbuffer,
            length,
            m_textFormatBody.Get(),
            D2D1::RectF(
                windowBounds.Width - GameConstants::HudRightOffset,
                GameConstants::HudTopOffset,
                windowBounds.Width,
                GameConstants::HudTopOffset + (GameConstants::HudBodyPointSize + GameConstants::Margin) * 3
                ),
            m_textBrush.Get()
            );

        // Using the unicode characters starting at 0x2780 ( ➀ ) for the consecutive levels of the game.
        // For completed levels start with 0x278A ( ➊ ) (This is 0x2780 + 10).
        uint32 levelCharacter[6];
        for (uint32 i = 0; i < 6; i++)
        {
            levelCharacter[i] = 0x2780 + i + ((static_cast<uint32>(game->LevelCompleted()) == i) ? 10 : 0);
        }
        length = swprintf_s(
            wsbuffer,
            bufferLength,
            L"%lc %lc %lc %lc %lc %lc",
            levelCharacter[0],
            levelCharacter[1],
            levelCharacter[2],
            levelCharacter[3],
            levelCharacter[4],
            levelCharacter[5]
            );
        // Create a new rectangle and draw the current level info text inside
        d2dContext->DrawText(
            wsbuffer,
            length,
            m_textFormatBodySymbol.Get(),
            D2D1::RectF(
                windowBounds.Width - GameConstants::HudRightOffset,
                GameConstants::HudTopOffset + (GameConstants::HudBodyPointSize + GameConstants::Margin) * 3 + GameConstants::Margin,
                windowBounds.Width,
                GameConstants::HudTopOffset + (GameConstants::HudBodyPointSize+ GameConstants::Margin) * 4
                ),
            m_textBrush.Get()
            );

        if (game->IsActivePlay())
        {
            // Draw the move and fire rectangles
            // Draw the crosshairs
        }
    }
}

この部分にさらに、下のメソッドの重大な GameHud::Render メソッドは、移行を描画を四角形の起動と ID2D1RenderTarget::DrawRectangle、十字線を 2 つの呼び出しを使用して、 ID2D1RenderTarget::DrawLineします。Breaking the method down further, this piece of the GameHud::Render method draws our move and fire rectangles with ID2D1RenderTarget::DrawRectangle, and crosshairs using two calls to ID2D1RenderTarget::DrawLine.

        // Check if game is playing
        if (game->IsActivePlay())
        {
            // Draw a rectangle for the touch input for the move control.
            d2dContext->DrawRectangle(
                D2D1::RectF(
                    0.0f,
                    windowBounds.Height - GameConstants::TouchRectangleSize,
                    GameConstants::TouchRectangleSize,
                    windowBounds.Height
                    ),
                m_textBrush.Get()
                );
            // Draw a rectangle for the touch input of the fire control.
            d2dContext->DrawRectangle(
                D2D1::RectF(
                    windowBounds.Width - GameConstants::TouchRectangleSize,
                    windowBounds.Height - GameConstants::TouchRectangleSize,
                    windowBounds.Width,
                    windowBounds.Height
                    ),
                m_textBrush.Get()
                );

            // Draw two lines to form crosshairs
            d2dContext->DrawLine(
                D2D1::Point2F(windowBounds.Width / 2.0f - GameConstants::CrossHairHalfSize, windowBounds.Height / 2.0f),
                D2D1::Point2F(windowBounds.Width / 2.0f + GameConstants::CrossHairHalfSize, windowBounds.Height / 2.0f),
                m_textBrush.Get(),
                3.0f
                );
            d2dContext->DrawLine(
                D2D1::Point2F(windowBounds.Width / 2.0f, windowBounds.Height / 2.0f - GameConstants::CrossHairHalfSize),
                D2D1::Point2F(windowBounds.Width / 2.0f, windowBounds.Height / 2.0f + GameConstants::CrossHairHalfSize),
                m_textBrush.Get(),
                3.0f
                );
        }

GameHud::Renderメソッドでゲームのウィンドウの論理サイズ格納、windowBounds変数。In the GameHud::Render method we store the logical size of the game window in the windowBounds variable. これを使用して、 GetLogicalSize のメソッド、 DeviceResourcesクラス。This uses the GetLogicalSize method of the DeviceResources class.

auto windowBounds = m_deviceResources->GetLogicalSize();

ゲームのウィンドウのサイズの取得は、UI プログラミングに不可欠です。Obtaining the size of the game window is essential for UI programming. ウィンドウのサイズが 1/96 インチ単位として、DIP が定義されている Dip (デバイス非依存ピクセル) と呼ばれるで与えられます。The size of the window is given in a measurement called DIPs (device independent pixels), where a DIP is defined as 1/96 of an inch. Direct2D スケーリング図面の単位を実際のピクセルが図面が発生したときに Windows ドット/インチ (DPI) 設定を使用して、そいます。Direct2D scales the drawing units to actual pixels when the drawing occurs, doing so by using the Windows dots per inch (DPI) setting. 同様に、描画するとテキストを使用して DirectWriteフォントのサイズの点ではなく、Dip を指定します。Similarly, when you draw text using DirectWrite, you specify DIPs rather than points for the size of the font. DIP は、浮動小数点数として表されます。DIPs are expressed as floating point numbers.

 

ゲームの状態情報を表示します。Displaying game state info

ヘッドアップ ディスプレイ、だけでなくは、ゲームのサンプルは、6 つのゲームの状態を表すオーバーレイが。Besides the heads-up display, the game sample has an overlay that represents six game states. すべての状態の機能を読み取るプレーヤー テキストに大きな黒い長方形プリミティブ。All states feature a large black rectangle primitive with text for the player to read. 非アクティブ状態であるために、コント ローラーの四角形を移動外観や十字線は描画されません。The move-look controller rectangles and crosshairs are not drawn because they are not active in these states.

使用して、オーバーレイを作成、 GameInfoOverlay クラス、ゲームの状態の連携を表示するテキストを切り替えることができます。The overlay is created using the GameInfoOverlay class, allowing us to switch out what text is displayed to align with the state of the game.

状態とオーバーレイのアクション

オーバーレイは、2 つのセクションに分割されます。ステータスアクションします。The overlay is broken up into two sections: Status and Action. 状態にさらに分類がセクションタイトル本文四角形。The Status secton is further broken down into Title and Body rectangles. アクションセクションには 1 つの四角形。The Action section only has one rectangle. 各四角形は、別の目的があります。Each rectangle has a different purpose.

  • titleRectangle タイトルのテキストが含まれています。titleRectangle contains the title text.
  • bodyRectangle 本文のテキストが含まれています。bodyRectangle contains the body text.
  • actionRectangle 特定のアクションを実行するプレーヤーを通知するテキストが含まれています。actionRectangle contains the text that informs the player to take a specific action.

ゲームでは、設定可能な 6 つの状態があります。The game has six states that can be set. 使用して伝達ゲームの状態、状態オーバーレイの部分。The state of the game conveyed using the Status portion of the overlay. 状態四角形は、さまざまな状態に対応するメソッドを使用して更新されます。The Status rectangles are updated using a number of methods corresponding with the following states.

  • 読み込みLoading
  • 初期の開始/高スコア統計Initial start/high score stats
  • レベルの開始Level start
  • ゲームの一時停止Game paused
  • ゲーム オーバーGame over
  • 勝利したゲームGame won

アクションを使用して、オーバーレイの部分を更新、 GameInfoOverlay::SetAction メソッドを次のいずれかに設定するアクション テキストを許可します。The Action portion of the overlay is updated using the GameInfoOverlay::SetAction method, allowing the action text to be set to one of the following.

  • 「... もう一度再生してタップします」"Tap to play again..."
  • 「レベルの読み込み、お待ちください...」"Level loading, please wait ..."
  • "Tap to continue...""Tap to continue ..."
  • なしNone

注意

どちらの方法については、説明でさらに、ゲームの状態を表すセクション。Both of these methods will be discussed further in the Representing game state section.

によって、ゲームでは、何が起こって、状態アクションセクションのテキスト フィールドが調整されます。Depending on the what's going on in the game, the Status and Action section text fields are adjusted. 初期化し、これら 6 つの状態のオーバーレイを描く方法を見てみましょう。Let's look at how we initialize and draw the overlay for these six states.

オーバーレイの初期化と描画Initializing and drawing the overlay

6 つステータス状態は、いくつかの点を共通のあるリソースのメソッドを行う必要があるとよく似ています。The six Status states have a few things in common, making the resources and methods they need very similar. - 画面の中央に黒の四角形を使用、すべてが背景と。They all use a black rectangle in the center of the screen as their background. - 表示されるテキストがあるか、タイトルまたは本文テキスト。The displayed text is either Title or Body text. - テキストは、Segoe UI フォントが使用され、バックの四角形の上に描画されます。The text uses the Segoe UI font and is drawn on top of the back rectangle.

ゲームのサンプルでは、オーバーレイを作成するときに影響する 4 つのメソッドがあります。The game sample has four methods that come into play when creating the overlay.

GameInfoOverlay::GameInfoOverlayGameInfoOverlay::GameInfoOverlay

GameInfoOverlay::GameInfoOverlay コンス トラクターに、プレーヤーに情報を表示するに使用するビットマップの画面を維持、オーバーレイを初期化します。The GameInfoOverlay::GameInfoOverlay constructor initializes the overlay, maintaining the bitmap surface that we will use to display info to the player on. コンス トラクターから工場出荷時の取得、 ID2D1Device オブジェクトの作成に使用するように渡される、 ID2D1DeviceContext オーバーレイはオブジェクト自体を描画できます。The constructor obtains a factory from the ID2D1Device object passed to it, which it uses to create an ID2D1DeviceContext that the overlay object itself can draw to. IDWriteFactory::CreateTextFormatIDWriteFactory::CreateTextFormat

GameInfoOverlay::CreateDeviceDependentResourcesGameInfoOverlay::CreateDeviceDependentResources

GameInfoOverlay::CreateDeviceDependentResources メソッドは、テキストの描画に使用されるブラシを作成します。GameInfoOverlay::CreateDeviceDependentResources is our method for creating brushes that will be used to draw our text. これを行うには、取得、 ID2D1DeviceContext2 オブジェクトを作成できるようにし、ジオメトリの描画インクとグラデーションなどの機能とメッシュをレンダリングします。To do this, we obtain a ID2D1DeviceContext2 object which enables the creation and drawing of geometry, plus functionality such as ink and gradient mesh rendering. 一連の色のブラシを使用して作成し ID2D1SolidColorBrush folling の UI 要素を描画します。We then create a series of colored brushes using ID2D1SolidColorBrush to draw the folling UI elements.

  • 四角形の背景に黒のブラシBlack brush for rectangle backgrounds
  • 状態のテキストのブラシを白White brush for status text
  • オレンジ色のブラシをアクション テキストOrange brush for action text

DeviceResources::SetDpiDeviceResources::SetDpi

DeviceResources::SetDpi メソッドは、ウィンドウのインチあたりのドットを設定します。The DeviceResources::SetDpi method sets the dots per inch of the window. このメソッドは、DPI が変更されする必要があるときに呼び出されますゲームのウィンドウのサイズが変更されたときの動作を再調整されます。This method gets called when the DPI is changed and needs to be readjusted which happens when the game window is resized. このメソッドを DPI を更新した後はもDeviceResources::CreateWindowSizeDependentResources たびに、ウィンドウのサイズを変更することを確認して必要なリソースが再作成します。After updating the DPI, this method also callsDeviceResources::CreateWindowSizeDependentResources to make sure necessary resources are recreated every time the window is resized.

GameInfoOverlay::CreateWindowsSizeDependentResourcesGameInfoOverlay::CreateWindowsSizeDependentResources

GameInfoOverlay::CreateWindowsSizeDependentResources メソッドは、すべての描画が行われる場所。The GameInfoOverlay::CreateWindowsSizeDependentResources method is where all our drawing takes place. メソッドの手順の概要を次に示します。The following is an outline of the method's steps.

  • UI テキスト セクションに次の 3 つの四角形が作成、タイトル本文、およびアクションテキスト。Three rectangles are created to section off the UI text for the Title, Body, and Action text.

    m_titleRectangle = D2D1::RectF(
        GameInfoOverlayConstant::SideMargin,
        GameInfoOverlayConstant::TopMargin,
        overlaySize.width - GameInfoOverlayConstant::SideMargin,
        GameInfoOverlayConstant::TopMargin + GameInfoOverlayConstant::TitleHeight
        );
    m_actionRectangle = D2D1::RectF(
        GameInfoOverlayConstant::SideMargin,
        overlaySize.height - (GameInfoOverlayConstant::ActionHeight + GameInfoOverlayConstant::BottomMargin),
        overlaySize.width - GameInfoOverlayConstant::SideMargin,
        overlaySize.height - GameInfoOverlayConstant::BottomMargin
        );
    m_bodyRectangle = D2D1::RectF(
        GameInfoOverlayConstant::SideMargin,
        m_titleRectangle.bottom + GameInfoOverlayConstant::Separator,
        overlaySize.width - GameInfoOverlayConstant::SideMargin,
        m_actionRectangle.top - GameInfoOverlayConstant::Separator
        );
    
  • ビットマップがという名前が作成m_levelBitmapを使用してアカウントを現在の DPI を考慮してCreateBitmapします。A Bitmap is created named m_levelBitmap, taking the current DPI into account using CreateBitmap.

  • m_levelBitmap 2D のレンダー ターゲットを使用して、として設定されて ID2D1DeviceContext::SetTargetします。m_levelBitmap is set as our 2D render target using ID2D1DeviceContext::SetTarget.

  • 黒を使用して行われたすべてのピクセルのビットマップがオフになって ID2D1RenderTarget::Clearします。The Bitmap is cleared with every pixel made black using ID2D1RenderTarget::Clear.

  • ID2D1RenderTarget::BeginDraw 描画を開始すると呼びます。ID2D1RenderTarget::BeginDraw is called to initiate drawing.

  • DrawTextに格納されているテキストを描画するために呼び出されるm_titleStringm_bodyString、およびm_actionString、対応するを使用して approperiate 四角でID2D1SolidColorBrushします。DrawText is called to draw the text stored in m_titleString, m_bodyString, and m_actionString in the approperiate rectangle using the corresponding ID2D1SolidColorBrush.

  • ID2D1RenderTarget::EndDraw ですべての描画操作を停止するために呼び出されるm_levelBitmapします。ID2D1RenderTarget::EndDraw is called to stop all drawing operations on m_levelBitmap.

  • 使用して、もう 1 つのビットマップが作成されたCreateBitmapというm_tooSmallBitmap環境設定の表示が小さすぎるため、ゲームのかどうかのみ表示される、フォールバックとして使用します。Another Bitmap is created using CreateBitmap named m_tooSmallBitmap to use as a fallback, showing only if the display configuration is too small for the game.

  • 描画するためのプロセスを繰り返しますm_levelBitmapm_tooSmallBitmap、今度は、文字列をのみ描画Paused本文。Repeat process for drawing on m_levelBitmap for m_tooSmallBitmap, this time only drawing the string Paused in the body.

今すぐ、オーバーレイの 6 つの状態のテキストを入力する 6 つのメソッドだけです。Now all we need are six methods to fill the text of our six overlay states!

ゲームの状態を表すRepresenting game state

対応するメソッドが、各ゲームでは、6 つのオーバーレイの状態、 GameInfoOverlayオブジェクト。Each of the six overlay states in the game has a corresponding method in the GameInfoOverlay object. これらのメソッドは、さまざまなオーバーレイを描画して、ゲーム自体に関する明示的な情報をプレイヤーに伝えます。These methods draw a variation of the overlay to communicate explicit info to the player about the game itself. この通信で表される、タイトル本文文字列。This communication is represented with a Title and Body string. 初期化時とでのリソースとこの情報のレイアウトは、既にサンプル構成されているため、 GameInfoOverlay::CreateDeviceDependentResources メソッドだけで済みますを提供するにはオーバーレイ状態固有の文字列。Because the sample already configured the resources and layout for this info when it was initialized and with the GameInfoOverlay::CreateDeviceDependentResources method, it only needs to provide the overlay state-specific strings.

状態オーバーレイの部分は、次の方法の 1 つの呼び出しで設定されます。The Status portion of the overlay is set with a call to one of the following methods.

ゲームの状態Game state メソッドを設定します。Status set method 状態フィールドStatus fields
読み込みLoading GameInfoOverlay::SetGameLoadingGameInfoOverlay::SetGameLoading TitleTitle
リソースの読み込みLoading Resources
本文Body
段階的に出力します"."を読み込み中のアクティビティを暗示します。Incrementally prints "." to imply loading activity.
初期の開始/高スコア統計Initial start/high score stats GameInfoOverlay::SetGameStatsGameInfoOverlay::SetGameStats TitleTitle
ハイ スコアHigh Score
本文Body
レベルに # が完了しましたLevels Completed #
合計ポイント #Total Points #
合計ショット #Total Shots #
レベルの開始Level start GameInfoOverlay::SetLevelStartGameInfoOverlay::SetLevelStart TitleTitle
レベルLevel #
本文Body
レベルの目標の説明。Level objective description.
ゲームの一時停止Game paused GameInfoOverlay::SetPauseGameInfoOverlay::SetPause TitleTitle
ゲームの一時停止Game Paused
本文Body
なしNone
ゲーム オーバーGame over GameInfoOverlay::SetGameOverGameInfoOverlay::SetGameOver TitleTitle
ゲームは終わりましたGame Over
本文Body
レベルに # が完了しましたLevels Completed #
合計ポイント #Total Points #
合計ショット #Total Shots #
レベルに # が完了しましたLevels Completed #
高 # のスコア付けHigh Score #
勝利したゲームGame won GameInfoOverlay::SetGameOverGameInfoOverlay::SetGameOver TitleTitle
あなたの勝ちです。You WON!
本文Body
レベルに # が完了しましたLevels Completed #
合計ポイント #Total Points #
合計ショット #Total Shots #
レベルに # が完了しましたLevels Completed #
高 # のスコア付けHigh Score #

GameInfoOverlay::CreateWindowSizeDependentResources メソッド、サンプルは、オーバーレイの特定のリージョンに対応する 3 つの四角形領域を宣言します。With the GameInfoOverlay::CreateWindowSizeDependentResources method, the sample declared three rectangular areas that correspond to specific regions of the overlay.

これらの領域を念頭に置いて、状態に固有のメソッドの 1 つである GameInfoOverlay::SetGameStats と、オーバーレイの描画方法を確認してみましょう。With these areas in mind, let's look at one of the state-specific methods, GameInfoOverlay::SetGameStats, and see how the overlay is drawn.

void GameInfoOverlay::SetGameStats(int maxLevel, int hitCount, int shotCount)
{
    int length;

    auto d2dContext = m_deviceResources->GetD2DDeviceContext();

    d2dContext->SetTarget(m_levelBitmap.Get());
    d2dContext->BeginDraw();
    d2dContext->SetTransform(D2D1::Matrix3x2F::Identity());
    d2dContext->FillRectangle(&m_titleRectangle, m_backgroundBrush.Get());
    d2dContext->FillRectangle(&m_bodyRectangle, m_backgroundBrush.Get());
    m_titleString = "High Score";

    d2dContext->DrawText(
        m_titleString->Data(),
        m_titleString->Length(),
        m_textFormatTitle.Get(),
        m_titleRectangle,
        m_textBrush.Get()
        );
    length = swprintf_s(
        wsbuffer,
        bufferLength,
        L"Levels Completed %d\nTotal Points %d\nTotal Shots %d",
        maxLevel,
        hitCount,
        shotCount
        );
    m_bodyString = ref new Platform::String(wsbuffer, length);
    d2dContext->DrawText(
        m_bodyString->Data(),
        m_bodyString->Length(),
        m_textFormatBody.Get(),
        m_bodyRectangle,
        m_textBrush.Get()
        );

    // We ignore D2DERR_RECREATE_TARGET here. This error indicates that the device
    // is lost. It will be handled during the next call to Present.
    HRESULT hr = d2dContext->EndDraw();
    if (hr != D2DERR_RECREATE_TARGET)
    {
        // The D2DERR_RECREATE_TARGET indicates there has been a problem with the underlying
        // D3D device.  All subsequent rendering will be ignored until the device is recreated.
        // This error will be propagated and the appropriate D3D error will be returned from the
        // swapchain->Present(...) call.   At that point, the sample will recreate the device
        // and all associated resources.  As a result, the D2DERR_RECREATE_TARGET doesn't
        // need to be handled here.
        DX::ThrowIfFailed(hr);
    }
}

Direct2D デバイス コンテキストを使用している、 GameInfoOverlayオブジェクトが初期化されて、このメソッドは黒の背景ブラシを使用してでタイトルと本文の四角形を塗りつぶします。Using the Direct2D device context that the GameInfoOverlay object initialized, this method fills the title and body rectangles with black using the background brush. また、白のテキスト ブラシを使って、"High Score" 文字列用のテキストをタイトルの四角形に描画し、ゲームの状態の最新情報が含まれている文字列を本文の四角形に描画します。It draws the text for the "High Score" string to the title rectangle and a string containing the updates game state information to the body rectangle using the white text brush.

後続の呼び出しによって、アクションの四角形が更新された GameInfoOverlay::SetAction メソッドから、 GameMainオブジェクトで、必要なゲームの状態情報を提供します。によってGameInfoOverlay::SetAction 「タップして続行」など、player を適切なメッセージを確認します。The action rectangle is updated by a subsequent call to GameInfoOverlay::SetAction from a method on the GameMain object, which provides the game state info needed by GameInfoOverlay::SetAction to determine the right message to the player, such as "Tap to continue".

選択された特定の州のオーバーレイ、 GameMain::SetGameInfoOverlay このようなメソッド。The overlay for any given state is chosen in the GameMain::SetGameInfoOverlay method like this:

void GameMain::SetGameInfoOverlay(GameInfoOverlayState state)
{
    m_gameInfoOverlayState = state;
    switch (state)
    {
    case GameInfoOverlayState::Loading:
        m_uiControl->SetGameLoading();
        break;

    case GameInfoOverlayState::GameStats:
        m_uiControl->SetGameStats(
            m_game->HighScore().levelCompleted + 1,
            m_game->HighScore().totalHits,
            m_game->HighScore().totalShots
            );
        break;

    case GameInfoOverlayState::LevelStart:
        m_uiControl->SetLevelStart(
            m_game->LevelCompleted() + 1,
            m_game->CurrentLevel()->Objective(),
            m_game->CurrentLevel()->TimeLimit(),
            m_game->BonusTime()
            );
        break;

    case GameInfoOverlayState::GameOverCompleted:
        m_uiControl->SetGameOver(
            true,
            m_game->LevelCompleted() + 1,
            m_game->TotalHits(),
            m_game->TotalShots(),
            m_game->HighScore().totalHits
            );
        break;

    case GameInfoOverlayState::GameOverExpired:
        m_uiControl->SetGameOver(
            false,
            m_game->LevelCompleted(),
            m_game->TotalHits(),
            m_game->TotalShots(),
            m_game->HighScore().totalHits
            );
        break;

    case GameInfoOverlayState::Pause:
        m_uiControl->SetPause(
            m_game->LevelCompleted() + 1,
            m_game->TotalHits(),
            m_game->TotalShots(),
            m_game->TimeRemaining()
            );
        break;
    }
}

ゲーム全体に表示される内容の切り替えの方法があるし、ゲーム、ゲームの状態に基づいてプレーヤー テキスト情報を通知するためにようになります。Now the game has a way to communicate text info to the player based on game state, and we have a way of switching what's displayed to them throughout the game.

次のステップNext steps

次のトピックの「コントロールの追加」では、プレイヤーがこのゲーム サンプルを操作する方法と、入力によってゲームの状態がどのように変わるかについて説明します。In the next topic, Adding controls, we look at how the player interacts with the game sample, and how input changes game state.