Поделиться через


Расширение образца игры

Примечание.

Этот раздел является частью серии руководств по созданию простой игры универсальная платформа Windows (UWP) с помощью DirectX. Эта ссылка задает контекст для ряда.

Чтобы скачать версию этой игры, использующую XAML для наложения, см . пример игры DirectX и XAML. Обязательно прочитайте файл readme там для получения сведений о создании примера.

На этом этапе мы рассмотрели ключевые компоненты базовой игры универсальная платформа Windows (UWP) DirectX 3D. Вы можете настроить платформу для игры, включая поставщик представлений и конвейер отрисовки, и реализовать базовый цикл игры. Вы также можете создать базовый пользовательский интерфейс наложения, включить звуки и реализовать элементы управления. Вы находитесь на пути к созданию игры самостоятельно, но если вам нужна дополнительная помощь и информация, ознакомьтесь с этими ресурсами.

Использование XAML для наложения

Одним из вариантов, которые мы не обсуждали в глубине, является использование XAML вместо Direct2D для наложения. XAML имеет множество преимуществ по сравнению с Direct2D для рисования элементов пользовательского интерфейса. Самое важное преимущество заключается в том, что это делает включение Windows 10 внешний вид и чувствовать себя в вашей игре DirectX удобнее. Многие распространенные элементы, стили и поведение, определяющие приложение UWP, тесно интегрированы в модель XAML, что делает его гораздо меньше работы для разработчика игр для реализации. Если собственный игровой дизайн имеет сложный пользовательский интерфейс, рассмотрите возможность использования XAML вместо Direct2D.

С помощью XAML мы можем сделать игровой интерфейс, похожий на Direct2D, сделанный ранее.

XAML

Наложение XAML

Direct2D

Наложение D2D

Хотя они имеют аналогичные конечные результаты, существует ряд различий между реализацией интерфейсов Direct2D и XAML.

Функция XAML Direct2D
Определение наложения Определяется в XAML-файле \*.xaml. После понимания XAML создание и настройка более сложных наложений упрощается по сравнению с Direct2D. Определяется как коллекция примитивов Direct2D и строк DirectWrite , которые помещаются вручную и записываются в целевой буфер Direct2D.
Элементы пользовательского интерфейса Элементы пользовательского интерфейса XAML берутся из стандартных элементов, которые являются частью среда выполнения Windows API XAML, включая Windows::UI::Xaml и Windows::UI::Xaml::Controls. Код, который обрабатывает поведение элементов пользовательского интерфейса XAML, определяется в файле кода, Main.xaml.cpp. Простые фигуры можно нарисовать как прямоугольники и многоточие.
Изменение размера окна Естественно обрабатывает события изменения размера и просмотра состояния, преобразуя наложение соответствующим образом. Необходимо вручную указать, как перераскрыть компоненты наложения.

Еще одна большая разница включает в себя цепочку буферов. Не нужно присоединять цепочку буферов к объекту Windows::UI::Core:CoreWindow . Вместо этого приложение DirectX, включающее XAML, связывает цепочку буферов при создании нового объекта SwapChainPanel.

В следующем фрагменте кода показано, как объявить XAML для SwapChainPanel в файле DirectXPage.xaml .

<Page
    x:Class="Simple3DGameXaml.DirectXPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Simple3DGameXaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <SwapChainPanel x:Name="DXSwapChainPanel">

    <!-- ... XAML user controls and elements -->

    </SwapChainPanel>
</Page>

Объект SwapChainPanel задается как свойство Content текущего объекта окна, созданного при запуске одноэлементным приложением.

void App::OnLaunched(_In_ LaunchActivatedEventArgs^ /* args */)
{
    m_mainPage = ref new DirectXPage();

    Window::Current->Content = m_mainPage;
    // Bring the application to the foreground so that it's visible
    Window::Current->Activate();
}

Чтобы подключить настроенную цепочку буферов к экземпляру SwapChainPanel, определенному XAML, необходимо получить указатель на базовую собственную реализацию интерфейса ISwapChainPanelNative и вызвать ISwapChainPanelNative::SetSwapChainChain на нем, передавая настроенную цепочку буферов.

Следующий фрагмент кода из DX::D eviceResources::CreateWindowSizeDependentResources подробно описано для взаимодействия DirectX/XAML:

        ComPtr<IDXGIDevice3> dxgiDevice;
        DX::ThrowIfFailed(
            m_d3dDevice.As(&dxgiDevice)
            );

        ComPtr<IDXGIAdapter> dxgiAdapter;
        DX::ThrowIfFailed(
            dxgiDevice->GetAdapter(&dxgiAdapter)
            );

        ComPtr<IDXGIFactory2> dxgiFactory;
        DX::ThrowIfFailed(
            dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory))
            );

        // When using XAML interop, the swap chain must be created for composition.
        DX::ThrowIfFailed(
            dxgiFactory->CreateSwapChainForComposition(
                m_d3dDevice.Get(),
                &swapChainDesc,
                nullptr,
                &m_swapChain
                )
            );

        // Associate swap chain with SwapChainPanel
        // UI changes will need to be dispatched back to the UI thread
        m_swapChainPanel->Dispatcher->RunAsync(CoreDispatcherPriority::High, ref new DispatchedHandler([=]()
        {
            // Get backing native interface for SwapChainPanel
            ComPtr<ISwapChainPanelNative> panelNative;
            DX::ThrowIfFailed(
                reinterpret_cast<IUnknown*>(m_swapChainPanel)->QueryInterface(IID_PPV_ARGS(&panelNative))
                );
            DX::ThrowIfFailed(
                panelNative->SetSwapChain(m_swapChain.Get())
                );
        }, CallbackContext::Any));

        // Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and
        // ensures that the application will only render after each VSync, minimizing power consumption.
        DX::ThrowIfFailed(
            dxgiDevice->SetMaximumFrameLatency(1)
            );
    }

Дополнительные сведения об этом процессе см. в разделе DirectX и ВЗАИМОДЕЙСТВИЯ XAML.

Пример

Чтобы скачать версию этой игры, использующую XAML для наложения, см . пример игры DirectX и XAML. Обязательно прочитайте файл readme там для получения сведений о создании примера.

В отличие от версии примера игры, описанной в остальных разделах, версия XAML определяет свою платформу в файлах App.xaml.cpp и DirectXPage.xaml.cpp вместо App.cpp и GameInfoOverlay.cpp соответственно.