Основы примера Marble Maze

В этом разделе описываются основные характеристики проекта Marble Maze, например использование Visual C++ в среде среда выполнения Windows, создание и структурирование проекта Marble Maze. В этом разделе также описывается несколько соглашений, используемых в коде.

Примечание.

Пример кода, соответствующий этому документу, найден в примере игры DirectX Marble Maze.

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

  • Используйте шаблон приложения DirectX 11 (универсальная версия Windows — C++/CX) в Visual Studio, чтобы создать игру UWP DirectX.
  • Среда выполнения Windows предоставляет классы и интерфейсы, чтобы вы могли разрабатывать приложения UWP более современными объектно-ориентированными способами.
  • Используйте ссылки на объекты с символом hat (^) для управления временем существования переменных среда выполнения Windows, Microsoft::WRL::ComPtr для управления временем существования объектов COM и std::shared_ptr или std::unique_ptr для управления временем существования всех остальных объектов C++, выделенных кучей.
  • В большинстве случаев используйте обработку исключений вместо кодов результатов для решения непредвиденных ошибок.
  • Используйте заметки SAL вместе с инструментами анализа кода для обнаружения ошибок в приложении.

Создание проекта Visual Studio

Если вы скачали и извлекли пример, вы можете открыть файл MarbleMaze_VS2017.slnпапке C++ ) в Visual Studio, и перед вами будет код.

Когда мы создали проект Visual Studio для Marble Maze, мы начали работу с существующим проектом. Однако если у вас еще нет существующего проекта, который предоставляет основные функциональные возможности, необходимые игре DirectX UWP, рекомендуется создать проект на основе шаблона приложения Visual Studio DirectX 11 (универсальная версия Windows — C++/CX), так как он предоставляет базовое рабочее трехмерное приложение. Для этого выполните следующие шаги.

  1. В Visual Studio 2019 выберите файл > нового > проекта...

  2. В окне создания проекта выберите приложение DirectX 11 (универсальная windows — C++/CX). Если этот параметр не отображается, возможно, у вас нет необходимых компонентов, см. статью "Изменить Visual Studio 2019", добавив или удалив рабочие нагрузки и компоненты для получения сведений об установке дополнительных компонентов.

New Project

  1. Нажмите кнопку "Далее", а затем введите имя проекта, расположение для хранения файлов и имя решения, а затем нажмите кнопку "Создать".

Одним из важных параметров проекта в шаблоне Приложения DirectX 11 (универсальное приложение Windows — C++/CX) является параметр /ZW, который позволяет программе использовать расширения языка среда выполнения Windows. Этот параметр включен по умолчанию при использовании шаблона Visual Studio. Дополнительные сведения о настройке параметров компилятора в Visual Studio см. в разделе "Параметры компилятора" (C++/CX ).

Обратите внимание, чтопараметр /ZW несовместим с такими параметрами, как /clr. В случае /clr это означает, что вы не можете использовать как платформа .NET Framework, так и среда выполнения Windows из одного проекта Visual C++.

 

Каждое приложение UWP, полученное из Microsoft Store, поставляется в виде пакета приложения. Пакет приложения содержит манифест пакета, содержащий сведения о приложении. Например, можно указать возможности (т. е. необходимый доступ к защищенным системным ресурсам или данным пользователей) приложения. Если вы определяете, что приложению требуются определенные возможности, используйте манифест пакета для объявления необходимых возможностей. Манифест также позволяет указать свойства проекта, такие как поддерживаемые повороты устройств, изображения плиток и экран-заставка. Манифест можно изменить, открыв Package.appxmanifest в проекте. Дополнительные сведения о пакетах приложений см. в разделе "Упаковка приложений".

Создание, развертывание и запуск игры

В раскрывающихся меню в верхней части Visual Studio слева от зеленой кнопки воспроизведения выберите конфигурацию развертывания. Мы рекомендуем задать его как отладку , предназначенную для архитектуры устройства (x86 для 32-разрядной версии x64 для 64-разрядной версии) и локального компьютера. Вы также можете протестировать на удаленном компьютере или на устройстве , подключенном через USB. Затем нажмите зеленую кнопку воспроизведения, чтобы создать и развернуть на устройстве.

Debug; x64; Local Machine

Управление игрой

Вы можете использовать сенсорный датчик, акселерометр, игровой контроллер или мышь для управления Marble Maze.

  • Используйте панель направления на контроллере, чтобы изменить активный элемент меню.
  • Используйте сенсорный ввод, кнопку "А" или "Пуск" на контроллере или мышь, чтобы выбрать пункт меню.
  • Используйте сенсорный датчик, акселерометр, левый палец или мышь, чтобы наклонить лабиринт.
  • Используйте сенсорный ввод, кнопку "А" или "Пуск" на контроллере или мышь, чтобы закрыть меню, например таблицу высокой оценки.
  • Нажмите кнопку "Пуск" на контроллере или клавише P на клавиатуре, чтобы приостановить или возобновить игру.
  • Чтобы перезапустить игру, нажмите кнопку "Назад" на контроллере или на домашней клавиатуре.
  • Когда таблица с высокой оценкой отображается, используйте кнопку "Назад" на контроллере или на клавиатуре для очистки всех показателей.

Соглашения о коде

Среда выполнения Windows — это программный интерфейс, который можно использовать для создания приложений UWP, которые выполняются только в специальной среде приложений. Такие приложения используют авторизованные функции, типы данных и устройства, а также распределяются из Microsoft Store. На самом низком уровне среда выполнения Windows состоит из двоичного интерфейса приложения (ABI). ABI — это низкоуровневый двоичный контракт, который делает среда выполнения Windows API доступными для нескольких языков программирования, таких как JavaScript, языки .NET и Visual C++.

Для вызова API-интерфейсов среда выполнения Windows из JavaScript и .NET эти языки требуют проекций, относящихся к каждой языковой среде. При вызове API среда выполнения Windows из JavaScript или .NET вы вызываете проекцию, которая, в свою очередь, вызывает базовую функцию ABI. Хотя вы можете вызывать функции ABI непосредственно в C++, корпорация Майкрософт также предоставляет проекции для C++, так как они упрощают использование среда выполнения Windows API, сохраняя высокую производительность. Корпорация Майкрософт также предоставляет расширения языка для Visual C++, которые специально поддерживают проекции среда выполнения Windows. Многие из этих расширений языка похожи на синтаксис языка C++/CLI. Однако вместо целевой среды CLR собственные приложения используют этот синтаксис для целевого среда выполнения Windows. Ссылка на объект или модификатор (^) является важной частью этого нового синтаксиса, так как позволяет автоматически удалять объекты среды выполнения с помощью подсчета ссылок. Вместо вызова таких методов, как AddRef и Release для управления временем существования объекта среда выполнения Windows, среда выполнения удаляет объект, если ни один другой компонент не ссылается на него, например при выходе из область или при установке всех ссылок на nullptr. Еще одной важной частью использования Visual C++ для создания приложений UWP является ссылка на новый ключевое слово. Используйте ссылку, а не новую, чтобы создать объекты среда выполнения Windows со ссылкой. Дополнительные сведения см. в разделе "Система типов" (C++/CX).

Важно!

При создании объектов среда выполнения Windows или создании компонентов среда выполнения Windows необходимо использовать ^ и ссылки на них. Стандартный синтаксис C++ можно использовать при написании основного кода приложения, который не использует среда выполнения Windows.

Marble Maze используется ^ вместе с Microsoft::WRL::ComPtr для управления выделенными кучами объектов и минимизации утечки памяти. Мы рекомендуем использовать ^ для управления временем существования переменных среда выполнения Windows, ComPtr для управления временем существования переменных COM (например, при использовании DirectX) и std::shared_ptr или std::unique_ptr для управления временем существования всех остальных кучи выделенных объектов C++.

 

Дополнительные сведения о расширениях языка, доступных для приложения UWP C++, см. в справочнике по языку Visual C++ (C++/CX).

Обработка ошибок

Marble Maze использует обработку исключений в качестве основного способа решения непредвиденных ошибок. Хотя в игровом коде традиционно используются коды ведения журнала или ошибки, такие как значения HRESULT , для указания ошибок обработка исключений имеет два основных преимущества. Во-первых, он может упростить чтение и обслуживание кода. С точки зрения кода обработка исключений является более эффективным способом распространения ошибки в подпрограмму, которая может обрабатывать эти ошибки. Использование кодов ошибок обычно требует, чтобы каждая функция явно распространяла ошибки. Второе преимущество заключается в том, что можно настроить отладчик Visual Studio для разрыва при возникновении исключения, чтобы можно было немедленно остановиться в расположении и контексте ошибки. Среда выполнения Windows также широко использует обработку исключений. Таким образом, используя обработку исключений в коде, можно объединить все ошибки в одну модель.

Рекомендуется использовать следующие соглашения в модели обработки ошибок:

  • Используйте исключения для связи с непредвиденными ошибками.

  • Не используйте исключения для управления потоком кода.

  • Перехватите только исключения, которые можно безопасно обрабатывать и восстанавливать. В противном случае не перехватывать исключение и разрешать приложению завершить работу.

  • При вызове подпрограммы DirectX, возвращающей HRESULT, используйте функцию DX::ThrowIfFailed . Эта функция определена в DirectXHelper.h. ThrowIfFailed создает исключение, если предоставленный HRESULT является кодом ошибки. Например, E_POINTER вызывает исключение ThrowIfFailed для создания Platform::NullReferenceException.

    При использовании ThrowIfFailed поместите вызов DirectX в отдельную строку, чтобы улучшить удобочитаемость кода, как показано в следующем примере.

    // Identify the physical adapter (GPU or card) this device is running on.
    ComPtr<IDXGIAdapter> dxgiAdapter;
    DX::ThrowIfFailed(
        dxgiDevice->GetAdapter(&dxgiAdapter)
        );
    
  • Хотя мы рекомендуем избежать использования HRESULT для непредвиденных ошибок, важно избежать использования обработки исключений для управления потоком кода. Поэтому рекомендуется использовать возвращаемое значение HRESULT при необходимости для управления потоком кода.

Заметки SAL

Используйте заметки SAL вместе с инструментами анализа кода для обнаружения ошибок в приложении.

С помощью языка заметки исходного кода (SAL) можно описать или описать, как функция использует его параметры. Заметки SAL также описывают возвращаемые значения. Заметки SAL работают с средством анализа кода C/C++, чтобы обнаружить возможные дефекты в исходном коде C и C++. К наиболее распространенным ошибкам кодирования, которые обнаруживает данное средство, относятся переполнение буфера, неинициализированная память, разыменования пустых указателей, а также утечки памяти и ресурсов.

Рассмотрим метод BasicLoader::LoadMesh , объявленный в BasicLoader.h. Этот метод используется _In_ для указания того, что имя файла является входным параметром (и поэтому будет считываться только из), _Out_ чтобы указать, что вершинаBuffer и indexBuffer являются выходными параметрами (и поэтому будут записываться только в), а _Out_opt_ также указывать, что vertexCount и indexCount являются необязательными выходными параметрами (и могут быть записаны в). Поскольку vertexCount и indexCount являются необязательными выходными параметрами, они могут быть nullptr. Средство анализа кода C/C++ проверяет вызовы этого метода, чтобы убедиться, что параметры, передаваемые им, соответствуют этим критериям.

void LoadMesh(
    _In_ Platform::String^ filename,
    _Out_ ID3D11Buffer** vertexBuffer,
    _Out_ ID3D11Buffer** indexBuffer,
    _Out_opt_ uint32* vertexCount,
    _Out_opt_ uint32* indexCount
    );

Чтобы выполнить анализ кода в приложении, в строке меню выберите "Выполнить > анализ кода сборки" в решении. Дополнительные сведения об анализе кода см. в статье "Анализ качества кода C/C++ с помощью анализа кода".

Полный список доступных заметок определен в sal.h. Дополнительные сведения см. в заметках SAL.

Следующие шаги

Ознакомьтесь со структурой приложения Marble Maze, чтобы узнать, как структурирован код приложения Marble Maze и как структура приложения DirectX UWP отличается от структуры традиционного классического приложения.