UWP アプリ フレームワークの定義Define the UWP app framework

中断/再開イベント、ウィンドウのフォーカスの変更、スナップなどの Windows ランタイム プロパティを含め、ゲーム オブジェクトが Windows とやり取りできるようにするためのフレームワークを構築します。Build a framework to let your game object interact with Windows, including Windows Runtime properties like suspend-resume event handling, changes in window focus, and snapping.

このフレームワークを設定するために、まず、アプリ シングルトン (実行中のアプリのインスタンスを定義する Windows ランタイム オブジェクト) が必要なグラフィック リソースにアクセスできるようにするビュー プロバイダーを取得します。To set this framework up, first obtain a view provider so that the app singleton, which is the Windows Runtime object that defines an instance of your running app, can access the graphic resources it needs. Windows ランタイムを通じて、ゲームはグラフィックス インターフェイスに直接接続して、必要なリソースとその処理方法を指定することもできます。Through Windows Runtime, your game also has a direct connection with the graphics interface, allowing you to specify the resources needed and how to handle them.

ビュー プロバイダー オブジェクトは、IFrameworkView インターフェイスを実装します。これには、このゲーム サンプルを作成するために構成する必要がある一連のメソッドが含まれています。The view provider object implements the IFrameworkView interface, which consists of a series of methods that needs to be configured to create this game sample.

アプリ シングルトンが呼び出す次の 5 つのメソッドを実装する必要があります。You'll need to implement these five methods that the app singleton calls:

Initialize メソッドは、アプリケーションの起動時に呼び出されます。The Initialize method is called on application launch. SetWindow メソッドは Initialize の後に呼び出されます。SetWindow method is called after Initialize. 次に、Load メソッドが呼び出されます。And then the Load method is called. Run メソッドはゲームの実行中に呼び出されます。The Run method is when the game is running. ゲームが終了すると、Uninitialize メソッドが呼び出されます。When the game ends, the Uninitialize method is called. 詳しくは、IFrameworkView の API リファレンスを参照してください。For more info, see IFrameworkView API reference.

注意

このサンプルの最新ゲーム コードをダウンロードしていない場合は、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

ユニバーサル Windows プラットフォーム (UWP) DirectX ゲーム用のフレームワークをセットアップし、ゲーム全体のフローを定義するステート マシンを実装します。Set up the framework for a Universal Windows Platform (UWP) DirectX game and implement the state machine that defines the overall game flow.

ビュー プロバイダー ファクトリとビュー プロバイダー オブジェクトを定義するDefine the view provider factory and view provider object

App.cpp 内の main ループを見てみましょう。Let's examine the main loop in App.cpp.

この手順では、ビューのファクトリを作成 (IFrameworkViewSource を実装) し、次に、ビューを定義するビュー プロバイダー オブジェクトのインスタンスを作成 (IFrameworkView を実装) します。In this step, we create a factory for the view (implements IFrameworkViewSource), which in turn creates instances of the view provider object (implements IFrameworkView) that defines the view.

Main メソッドMain method

GitHub サンプル コードを読み込んでいる場合は、新しい DirectXApplicationSource を作成します Create a new DirectXApplicationSource if you have the GitHub sample code loaded. (元の DirectX テンプレートを使用している場合は Direct3DApplicationSource を使用します)。これは、IFrameworkViewSource を実装するビュー プロバイダー ファクトリです。(Use Direct3DApplicationSource if you're using the original DirectX template) This is the view provider factory that implements IFrameworkViewSource. ビュー プロバイダー ファクトリの IFrameworkViewSource インターフェイスには、CreateView という単一のメソッドが定義されています。The view provider factory's IFrameworkViewSource interface has a single method, CreateView, defined.

CoreApplication::Run では、Direct3DApplicationSource または DirectXApplicationSource が渡されたときに、アプリ シングルトンによって CreateView メソッドが呼び出されます。In CoreApplication::Run, the CreateView method is called by the app singleton when Direct3DApplicationSource or DirectXApplicationSource is passed.

CreateView は、IFrameworkView を実装するアプリ オブジェクトの新しいインスタンスへの参照を返します。これは、このサンプルでは App クラス オブジェクトです。CreateView returns a reference to a new instance of your app object that implements IFrameworkView, which is the App class object in this sample. App クラス オブジェクトがビュー プロバイダー オブジェクトです。The App class object is the view provider object.

// The main function is only used to initialize our IFrameworkView class.
[Platform::MTAThread]
int main(Platform::Array<Platform::String^>^)
{
    auto directXApplicationSource = ref new DirectXApplicationSource();
    CoreApplication::Run(directXApplicationSource);
    return 0;
}

//--------------------------------------------------------------------------------------

IFrameworkView^ DirectXApplicationSource::CreateView()
{
    return ref new App();
}

ビュー プロバイダーを初期化するInitialize the view provider

ビュー プロバイダー オブジェクトが作成されたら、アプリケーションの起動時に、アプリ シングルトンが Initialize メソッドを呼び出します。After the view provider object is created, the app singleton calls the Initialize method on application launch. このため、メイン ウィンドウのアクティブ化の処理や、ゲームが突然の中断 (とその後に行われる場合がある再開) イベントを処理できることの確認など、UWP ゲームの最も基本的な動作をこのメソッドで処理することが非常に重要です。Therefore, it is crucial that this method handles the most fundamental behaviors of a UWP game, such as handling the activation of the main window and making sure that the game can handle a sudden suspend (and a possible later resume) event.

この時点で、ゲーム アプリは一時停止 (または再開) メッセージを処理できます。At this point, the game app can handle a suspend (or resume) message. ただし、まだ操作するウィンドウはなく、ゲームは初期化されていません。But there's still no window to work with and the game is uninitialized. 必要なことが、あといくつか残っています。There's a few more things that need to happen!

App::Initialize メソッドApp::Initialize method

このメソッドでは、ゲームのアクティブ化、一時停止、再開のためのさまざまなイベント ハンドラーを作成します。In this method, create various event handlers for activating, suspending, and resuming the game.

デバイス リソースへのアクセスを取得します。Get access to the device resources. メモリ リソースが最初に作成されたときに、make_shared 関数を使用して shared_ptr を作成します。The make_shared function is used to create a shared_ptr when the memory resource is created for the first time. make_shared を使用する利点は例外安全性です。An advantage of using make_shared is that it's exception-safe. また、同じ呼び出しを使用して、制御ブロックとリソースにメモリを割り当てて、構築にかかるオーバーヘッドを削減します。It also uses the same call to allocate the memory for the control block and the resource and therefore reduces the construction overhead.

void App::Initialize(
    CoreApplicationView^ applicationView
    )
{
    // Register event handlers for app lifecycle. This example includes Activated, so that we
    // can make the CoreWindow active and start rendering on the window.
    applicationView->Activated +=
        ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &App::OnActivated);

    CoreApplication::Suspending +=
        ref new EventHandler<SuspendingEventArgs^>(this, &App::OnSuspending);

    CoreApplication::Resuming +=
        ref new EventHandler<Platform::Object^>(this, &App::OnResuming);

    // At this point we have access to the device. 
    // We can create the device-dependent resources.
    m_deviceResources = std::make_shared<DX::DeviceResources>();
}

ウィンドウと表示動作を構成するConfigure the window and display behaviors

ここでは、SetWindow の実装を見てみましょう。Now, let's look at the implementation of SetWindow. SetWindow メソッドでは、ウィンドウと表示動作を構成します。In the SetWindow method, you configure the window and display behaviors.

App::SetWindow メソッドApp::SetWindow method

アプリ シングルトンは、ゲームのメイン ウィンドウを表す CoreWindow オブジェクトを提供し、そのリソースとイベントをゲームで使用できるようにします。The app singleton provides a CoreWindow object that represents the game's main window, and makes its resources and events available to the game. 操作するウィンドウができたら、ゲームの基本的な UI コンポーネントとイベントを追加できます。Now that there's a window to work with, the game can now start adding in the basic UI components and events.

次に、マウスとタッチ コントロールの両方で使用できる CoreCursor メソッドを使用してポインターを作成します。Then, create a pointer using CoreCursor method which can be used by both mouse and touch controls.

最後に、(ディスプレイ デバイスが変更された場合に) ウィンドウのサイズ変更、終了、DPI 変更を行うための基本的なイベントを作成します。Lastly, create basic events for window resizing, closing, and DPI changes (if the display device changes). これらのイベントの詳細については、「イベント処理」を参照してください。For more info about the events, go to Event Handling.

void App::SetWindow(
    CoreWindow^ window
    )
{
    // Codes added to modify the original DirectX template project
    window->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0);

    PointerVisualizationSettings^ visualizationSettings = PointerVisualizationSettings::GetForCurrentView();
    visualizationSettings->IsContactFeedbackEnabled = false;
    visualizationSettings->IsBarrelButtonFeedbackEnabled = false;
    // --end of codes added
    
    m_deviceResources->SetWindow(window);

    window->Activated +=
        ref new TypedEventHandler<CoreWindow^, WindowActivatedEventArgs^>(this, &App::OnWindowActivationChanged);

    window->SizeChanged +=
        ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &App::OnWindowSizeChanged);

    window->VisibilityChanged +=
        ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &App::OnVisibilityChanged);
        
    window->Closed +=
        ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &App::OnWindowClosed);

    DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView();

    currentDisplayInformation->DpiChanged +=
        ref new TypedEventHandler<DisplayInformation^, Platform::Object^>(this, &App::OnDpiChanged);

    currentDisplayInformation->OrientationChanged +=
        ref new TypedEventHandler<DisplayInformation^, Object^>(this, &App::OnOrientationChanged);
    
    // Codes added to modify the original DirectX template project
    currentDisplayInformation->StereoEnabledChanged +=
        ref new TypedEventHandler<DisplayInformation^, Platform::Object^>(this, &App::OnStereoEnabledChanged);
    // --end of codes added
    
    DisplayInformation::DisplayContentsInvalidated +=
        ref new TypedEventHandler<DisplayInformation^, Platform::Object^>(this, &App::OnDisplayContentsInvalidated);
}

ビュー プロバイダーの Load メソッドLoad method of the view provider

メイン ウィンドウが設定された後、アプリ シングルトンは Load を呼び出します。After the main window is set, the app singleton calls Load. このメソッドで一連の非同期タスクを使って、ゲーム オブジェクトを作成し、グラフィックス リソースを読み込み、ゲームのステート マシンを初期化します。A set of asynchronous tasks is used in this method to create the game objects, load graphics resources, and initialize the game’s state machine. ゲームのデータまたはアセットを事前に取得するには、SetWindowInitialize よりも、このメソッドが適しています。If you want to pre-fetch game data or assets, this is a better place for it than in SetWindow or Initialize.

Windows では、非同期タスク パターンを使用して、ゲームが入力の処理を開始するまでにかけることができる時間に制限が設けられているため、ゲームが入力の処理を開始できるように、Load メソッドは迅速に完了するように設計する必要があります。Because Windows imposes restrictions on the time your game can take before it must start processing input, by using the async task pattern, you need to design for the Load method to complete quickly so it can start processing input. 読み込みに時間がかかる場合やリソースが多い場合は、進行状況バーを用意して定期的に更新するようにします。If loading takes awhile or if there are lots of resources, provide your users with a regularly updated progress bar. 開始時の状態やグローバルな値の設定など、ゲームを開始する前に必要な準備を行う場合にも、このメソッドを使用します。This method is also used to do any necessary preparations before the game begins, like setting any starting states or global values.

非同期プログラミングとタスクの並列処理の概念に慣れていない場合は、「C++ での非同期プログラミング」を参照してください。If you are new to asynchronous programming and task parallelism concepts, go to Asynchronous programming in C++.

App::Load メソッドApp::Load method

読み込みタスクが含まれる GameMain クラスを作成します。Create the GameMain class that contains the loading tasks.

void App::Load(
    Platform::String^ entryPoint
    )
{
        if (!m_main)
    {
        m_main = std::unique_ptr<GameMain>(new GameMain(m_deviceResources));
    }
}

GameMain コンストラクターGameMain constructor

  • ゲーム レンダラーを作成して初期化します。Create and initialize the game renderer. 詳細については、次を参照してくださいレンダリング framework i:。レンダリングの概要します。For more information, see Rendering framework I: Intro to rendering.
  • Simple3Dgame オブジェクトを作成して初期化します。Create the initialize the Simple3Dgame object. 詳細については、「メイン ゲーム オブジェクトの定義」を参照してください。For more information, see Define the main game object.
  • ゲームの UI コントロール オブジェクトを作成し、リソース ファイルの読み込み時に進行状況バーを表示するゲーム情報オーバーレイを表示します。Create the game UI control object and display game info overlay to show a progress bar as the resource files load. 詳細については、「ユーザー インターフェイスの追加」を参照してください。For more information, see Adding a user interface.
  • コントローラー (タッチ、マウス、または Xbox ワイヤレス コントローラー) からの入力を読み取ることができるようにコントローラーを作成します。Create the controller so it can read input from the controller (touch, mouse, or XBox wireless controller). 詳細については、「コントロールの追加」を参照してください。For more information, see Adding controls.
  • コントローラーを初期化したら、移動とカメラのそれぞれのタッチ コントロール用に、画面の左下と右下の 2 つの四角形の領域を定義しています。After the controller is initialized, we defined two rectangular areas in the lower-left and lower-right corners of the screen for the move and camera touch controls, respectively. SetMoveRect を呼び出して定義される左下の四角形は、カメラを前後左右に動かすための仮想のコントロール パッドとして使われ、The player uses the lower-left rectangle, defined by the call to SetMoveRect, as a virtual control pad for moving the camera forward and backward, and side to side. SetFireRect メソッドで定義される右下の四角形は、弾を撃つための仮想のボタンとして使われます。The lower-right rectangle, defined by the SetFireRect method, is used as a virtual button to fire the ammo.
  • create_taskcreate_task::then を使用して、リソースの読み込みを 2 つの独立したステージに分割します。Use create_task and create_task::then to break resource loading into two separate stages. Direct3D 11 デバイス コンテキストへのアクセスは、そのデバイス コンテキストが作成されたスレッドに制限されている一方で、オブジェクト作成のための Direct3D 11 デバイスへのアクセスにはスレッドの制限がないため、CreateGameDeviceResourcesAsync タスクは、元のスレッドで実行される完了タスク (FinalizeCreateGameDeviceResources) とは別のスレッドで実行されます。Because access to the Direct3D 11 device context is restricted to the thread the device context was created on while access to the Direct3D 11 device for object creation is free-threaded, this means that the CreateGameDeviceResourcesAsync task can run on a separate thread from the completion task (FinalizeCreateGameDeviceResources), which runs on the original thread. LoadLevelAsyncFinalizeLoadLevel を使うレベル リソースの読み込みにも同様のパターンを使います。We use a similar pattern for loading level resources with LoadLevelAsync and FinalizeLoadLevel.
GameMain::GameMain(const std::shared_ptr<DX::DeviceResources>& deviceResources) :
    m_deviceResources(deviceResources),
    m_windowClosed(false),
    m_haveFocus(false),
    m_gameInfoOverlayCommand(GameInfoOverlayCommand::None),
    m_visible(true),
    m_loadingCount(0),
    m_updateState(UpdateEngineState::WaitingForResources)
{
    m_deviceResources->RegisterDeviceNotify(this);

    m_renderer = ref new GameRenderer(m_deviceResources);
    m_game = ref new Simple3DGame();

    m_uiControl = m_renderer->GameUIControl();

    m_controller = ref new MoveLookController(CoreWindow::GetForCurrentThread());

    auto bounds = m_deviceResources->GetLogicalSize();

    m_controller->SetMoveRect(
        XMFLOAT2(0.0f, bounds.Height - GameConstants::TouchRectangleSize),
        XMFLOAT2(GameConstants::TouchRectangleSize, bounds.Height)
        );
    m_controller->SetFireRect(
        XMFLOAT2(bounds.Width - GameConstants::TouchRectangleSize, bounds.Height - GameConstants::TouchRectangleSize),
        XMFLOAT2(bounds.Width, bounds.Height)
        );

    SetGameInfoOverlay(GameInfoOverlayState::Loading);
    m_uiControl->SetAction(GameInfoOverlayCommand::None);
    m_uiControl->ShowGameInfoOverlay();

    create_task([this]()
    {
        // Asynchronously initialize the game class and load the renderer device resources.
        // By doing all this asynchronously, the game gets to its main loop more quickly
        // and in parallel all the necessary resources are loaded on other threads.
        m_game->Initialize(m_controller, m_renderer);

        return m_renderer->CreateGameDeviceResourcesAsync(m_game);

    }).then([this]()
    {
        // The finalize code needs to run in the same thread context
        // as the m_renderer object was created because the D3D device context
        // can ONLY be accessed on a single thread.
        m_renderer->FinalizeCreateGameDeviceResources();

        InitializeGameState();

        if (m_updateState == UpdateEngineState::WaitingForResources)
        {
            // In the middle of a game so spin up the async task to load the level.
            return m_game->LoadLevelAsync().then([this]()
            {
                // The m_game object may need to deal with D3D device context work so
                // again the finalize code needs to run in the same thread
                // context as the m_renderer object was created because the D3D
                // device context can ONLY be accessed on a single thread.
                m_game->FinalizeLoadLevel();
                m_game->SetCurrentLevelToSavedState();
                m_updateState = UpdateEngineState::ResourcesLoaded;

            }, task_continuation_context::use_current());
        }
        else
        {
            // The game is not in the middle of a level so there aren't any level
            // resources to load.  Creating a no-op task so that in both cases
            // the same continuation logic is used.
            return create_task([]()
            {
            });
        }
    }, task_continuation_context::use_current()).then([this]()
    {
        // Since Game loading is an async task, the app visual state
        // may be too small or not have focus.  Put the state machine
        // into the correct state to reflect these cases.

        if (m_deviceResources->GetLogicalSize().Width < GameConstants::MinPlayableWidth)
        {
            m_updateStateNext = m_updateState;
            m_updateState = UpdateEngineState::TooSmall;
            m_controller->Active(false);
            m_uiControl->HideGameInfoOverlay();
            m_uiControl->ShowTooSmall();
            m_renderNeeded = true;
        }
        else if (!m_haveFocus)
        {
            m_updateStateNext = m_updateState;
            m_updateState = UpdateEngineState::Deactivated;
            m_controller->Active(false);
            m_uiControl->SetAction(GameInfoOverlayCommand::None);
            m_renderNeeded = true;
        }
    }, task_continuation_context::use_current());
}

ビュー プロバイダーの Run メソッドRun method of the view provider

以前の 3 つのメソッド:初期化、 __SetWindow__と__ロード__ステージを設定します。The earlier three methods: Initialize, SetWindow, and Load have set the stage. 次に、ゲームは Run メソッドに進んで、楽しいゲームを開始できます。Now the game can progress to the Run method, starting the fun! ゲームの状態間の移行に使われるイベントのディスパッチと処理が行われます。The events that it uses to transition between game states are dispatched and processed. ゲーム ループの循環に応じてグラフィックスが更新されます。Graphics are updated as the game loop cycles.

App::RunApp::Run

プレイヤーがゲーム ウィンドウを閉じると終了する while ループを開始します。Start a while loop that terminates when the player closes the game window.

サンプル コードは、ゲーム エンジンのステート マシンの次の 2 つのいずれかの状態に移行します。The sample code transitions to one of two states in the game engine state machine: * 非アクティブ化:ゲーム ウィンドウが非アクティブ化される (フォーカスを失う) か、スナップされます。Deactivated: The game window gets deactivated (loses focus) or snapped. この場合、ゲームではイベントの処理を中断し、ウィンドウがフォーカスまたはスナップを解除されるまで待機します。When this happens, the game suspends event processing and waits for the window to focus or unsnap. * TooSmall:ゲームでは、独自の状態を更新し、表示するためのグラフィックスをレンダリングします。TooSmall: The game updates its own state and renders the graphics for display.

ゲームにフォーカスがある場合、メッセージ キューに到達する各イベントを処理する必要があるため、CoreWindowDispatch.ProcessEventsProcessAllIfPresent オプションで呼び出す必要があります。When your game has focus, you must handle every event in the message queue as it arrives, and so you must call CoreWindowDispatch.ProcessEvents with the ProcessAllIfPresent option. 他のオプションでは、メッセージ イベントの処理に遅延が発生することがあり、この場合、ゲームが応答しなくなったように見えるか、タッチ動作の反応が遅くて "敏感" でないように見える可能性があります。Other options can cause delays in processing message events, which can make your game feel unresponsive, or result in touch behaviors that feel sluggish and not "sticky".

ゲームが表示されていないときや中断またはスナップ状態のときにリソースを循環させてどこにも到達しないメッセージをディスパッチすることは回避する必要があるため、When the game is not visible, suspended or snapped, you don't want it to consume any resources cycling to dispatch messages that will never arrive. ゲームでは ProcessOneAndAllPending を使う必要があります。この結果、イベントが取得されるまではブロックが行われ、その後、そのイベントと、そのイベントの処理中にプロセス キューに到達した他のイベントが処理されます。In this case, your game must use ProcessOneAndAllPending, which blocks until it gets an event, and then processes that event and any others that arrive in the process queue during the processing of the first. ProcessEvents キューの処理が完了したらすぐに返します。ProcessEvents then immediately returns after the queue has been processed.

void App::Run()
{
    m_main->Run();
}

void GameMain::Run()
{
    while (!m_windowClosed)
    {
        if (m_visible)
        {
            switch (m_updateState)
            {
            case UpdateEngineState::Deactivated:
            case UpdateEngineState::TooSmall:
                if (m_updateStateNext == UpdateEngineState::WaitingForResources)
                {
                    WaitingForResourceLoading();
                    m_renderNeeded = true;
                }
                else if (m_updateStateNext == UpdateEngineState::ResourcesLoaded)
                {
                    // In the device lost case, we transition to the final waiting state
                    // and make sure the display is updated.
                    switch (m_pressResult)
                    {
                    case PressResultState::LoadGame:
                        SetGameInfoOverlay(GameInfoOverlayState::GameStats);
                        break;

                    case PressResultState::PlayLevel:
                        SetGameInfoOverlay(GameInfoOverlayState::LevelStart);
                        break;

                    case PressResultState::ContinueLevel:
                        SetGameInfoOverlay(GameInfoOverlayState::Pause);
                        break;
                    }
                    m_updateStateNext = UpdateEngineState::WaitingForPress;
                    m_uiControl->ShowGameInfoOverlay();
                    m_renderNeeded = true;
                }

                if (!m_renderNeeded)
                {
                    // The App is not currently the active window and not in a transient state so just wait for events.
                    CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
                    break;
                }
                // otherwise fall through and do normal processing to get the rendering handled.
            default:
                CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
                Update();
                m_renderer->Render();
                m_deviceResources->Present();
                m_renderNeeded = false;
            }
        }
        else
        {
            CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
        }
    }
    m_game->OnSuspending();  // exiting due to window close.  Make sure to save state.
}

ビュー プロバイダーの Uninitialize メソッドUninitialize method of the view provider

ユーザー最終的にゲーム セッションを終了したら、クリーンアップする必要があります。When the user eventually ends the game session, we need to clean up. Uninitialize はまさにそのような用途に使います。This is where Uninitialize comes in.

Windows 10 で、アプリのプロセスを強制終了しないアプリ ウィンドウを閉じるとが、代わりにアプリの単一の状態をメモリに書き込みます。In Windows 10, closing the app window doesn't kill the app's process, but instead it writes the state of the app singleton to memory. システムでこのメモリの再利用が必要になった際に、リソースの特別なクリーンアップなどの特別な処理が必要な場合は、そのクリーンアップ用のコードをこのメソッドに入れてください。If anything special must happen when the system must reclaim this memory, including any special cleanup of resources, then put the code for that cleanup in this method.

アプリ。UninitializeApp:: Uninitialize

void App::Uninitialize()
{
}

ヒントTips

ゲームを開発するときは、これらのメソッドの近くにスタートアップ コードを設計してください。When developing your own game, design your startup code around these methods. 各メソッドの基本的な推奨事項を次に示します。Here's a simple list of basic suggestions for each method:

  • メイン クラスの割り当てと基本的なイベント ハンドラーの接続には Initialize を使います。Use Initialize to allocate your main classes and connect up the basic event handlers.
  • メイン ウィンドウの作成とウィンドウ固有のイベントの接続には SetWindow を使います。Use SetWindow to create your main window and connect any window-specific events.
  • その他のセットアップの処理と非同期のオブジェクト作成やリソース読み込みには Load を使います。Use Load to handle any remaining setup, and to initiate the async creation of objects and loading of resources. 一時ファイルまたは一時データを作成する必要がある場合は (手続き的に生成されるアセットなど)、その処理もこのメソッドで行います。If you need to create any temporary files or data, such as procedurally generated assets, do it here too.

次のステップNext steps

ここでは、DirectX を使った UWP ゲームの基本的な構造について説明します。This covers the basic structure of a UWP game with DirectX. このチュートリアルの他の部分で参照するので、ここで説明した 5 つのメソッドを覚えておいてください。Keep these five methods in mind as we'll reference them in other parts of this walkthrough. 次に、「ゲームのフロー管理」で、ゲームを続行するために、ゲームの状態とイベント処理を管理する方法について詳しく説明します。Next, we'll take an in-depth look at how to manage game states and event handling to keep the game going under Game flow management.