Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Nota:
Este tema forma parte de la serie de tutoriales Crear un sencillo juego para la Plataforma Universal de Windows (UWP) con DirectX. El tema de ese vínculo establece el contexto de la serie.
El primer paso para desarrollar el juego es crear un proyecto en Microsoft Visual Studio. Después de configurar un proyecto específicamente para el desarrollo de juegos, podría volver a usarlo más adelante como un tipo de plantilla.
Objetivos
- Cree un proyecto en Visual Studio mediante una plantilla de proyecto.
- Comprenda el punto de entrada y la inicialización del juego examinando el archivo de origen de la clase App .
- Mira el bucle del juego.
- Revise el archivo package.appxmanifest del proyecto
.
Creación de un proyecto en Visual Studio
Nota:
Para obtener información sobre cómo configurar Visual Studio para el desarrollo de C++/WinRT, incluida la instalación y el uso de la extensión de Visual Studio de C++/WinRT (VSIX) y el paquete NuGet (que proporcionan junto la plantilla de proyecto y la compatibilidad con la compilación), consulte compatibilidad de Visual Studio con C++/WinRT.
En primer lugar, instale (o actualice a) la versión más reciente de la extensión de Visual Studio de C++/WinRT (VSIX); consulte la nota anterior. A continuación, en Visual Studio, cree un nuevo proyecto basado en la plantilla de proyecto Core App (C++/WinRT). Tenga como destino la versión más reciente disponible con carácter general (es decir, no en versión preliminar) del SDK de Windows.
Revise la clase App para comprender IFrameworkViewSource y IFrameworkView
En el proyecto core App, abra el archivo App.cpp
de código fuente . Ahí está la implementación de la clase App, que representa la aplicación y su ciclo de vida. En este caso, por supuesto, sabemos que la aplicación es un juego. Pero nos referiremos a ella como una aplicación para hablar más generalmente sobre cómo se inicializa una aplicación para la Plataforma universal de Windows (UWP).
La función wWinMain
La función wWinMain es el punto de entrada de la aplicación. Este es el aspecto
int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
{
CoreApplication::Run(winrt::make<App>());
}
Realizamos una instancia de la clase app
En las dos secciones siguientes de este tema se describen las interfaces IFrameworkViewSource e IFrameworkView . Esas interfaces (así como CoreApplication.Run) representan una manera de que la aplicación proporcione Windows con un proveedor de vistas . Windows usa ese proveedor de vistas para conectar la aplicación con el shell de Windows para poder controlar los eventos del ciclo de vida de la aplicación.
Interfaz IFrameworkViewSource
La clase App implementa realmente IFrameworkViewSource, como puede ver en la lista siguiente.
struct App : winrt::implements<App, IFrameworkViewSource, IFrameworkView>
{
...
IFrameworkView CreateView()
{
return *this;
}
...
}
Un objeto que implementa IFrameworkViewSource es un objeto generador de proveedores de vistas. El trabajo de ese objeto es fabricar y devolver un objeto proveedor de vistas.
IFrameworkViewSource tiene el método único IFrameworkViewSource::CreateView. Windows llama a esa función en el objeto que se pasa a CoreApplication.Run. Como puede ver anteriormente, la implementación App::CreateView de ese método devuelve *this
. En otras palabras, el objeto App se devuelve a sí mismo. Dado que IFrameworkViewSource::CreateView tiene un tipo de valor devuelto de IFrameworkView, se deduce que la clase App debe implementar también esa interfaz. Y usted puede ver que lo hace en la lista arriba.
Interfaz IFrameworkView
Un objeto que implementa IFrameworkView es un objeto de proveedor de vistas . Y ahora hemos proporcionado Windows con ese proveedor de vistas. Es el mismo objeto App que creamos en wWinMain. Por lo tanto, la clase
Ahora, Windows puede llamar a las implementaciones de la clase App de los métodos de IFrameworkView. En las implementaciones de esos métodos, la aplicación tiene la oportunidad de realizar tareas como la inicialización, comenzar a cargar los recursos que necesitará, conectar los controladores de eventos adecuados y recibir el CoreWindow que la aplicación usará para mostrar su salida.
Las implementaciones de los métodos de IFrameworkView se llaman en el orden que se muestra a continuación.
- inicializar
- SetWindow
- cargar
- Se genera el evento CoreApplicationView::Activated. Por lo tanto, si opcionalmente se ha registrado para controlar ese evento, entonces se llama a su controlador de OnActivated en este momento.
- Ejecutar
- desinicializar
Y este es el esqueleto de la clase App (en App.cpp
), que muestra las firmas de dichos métodos.
struct App : winrt::implements<App, IFrameworkViewSource, IFrameworkView>
{
...
void Initialize(Windows::ApplicationModel::Core::CoreApplicationView const& applicationView) { ... }
void SetWindow(Windows::UI::Core::CoreWindow const& window) { ... }
void Load(winrt::hstring const& entryPoint) { ... }
void OnActivated(
Windows::ApplicationModel::Core::CoreApplicationView const& applicationView,
Windows::ApplicationModel::Activation::IActivatedEventArgs const& args) { ... }
void Run() { ... }
void Uninitialize() { ... }
...
}
Se trata de una introducción a IFrameworkView. Vamos a profundizar mucho más en estos métodos y cómo implementarlos, en Definir el marco de la aplicación UWP del juego.
Ordenar el proyecto
El proyecto Core App que creaste a partir de la plantilla de proyecto contiene una funcionalidad que debemos organizar ahora. Después, podemos usar el proyecto para volver a crear el juego de galería de disparos (Simple3DGameDX). Realice los siguientes cambios en la clase App en App.cpp
.
- Elimine sus miembros de datos.
- Eliminar OnPointerPressed, OnPointerMovedy AddVisual
- Borra el código de SetWindow.
El proyecto se compilará y ejecutará, pero solo mostrará un color sólido en el área de cliente.
Bucle del juego
Para obtener una idea del aspecto de un bucle de juego, busque en el código fuente del juego de ejemplo Simple3DGameDX que descargó.
La clase App
void Run()
{
m_main->Run();
}
Puedes encontrar GameMain::Run en GameMain.cpp
. Es el bucle principal del juego, y este es un esquema muy aproximado de que muestra las características más importantes.
void GameMain::Run()
{
while (!m_windowClosed)
{
if (m_visible)
{
CoreWindow::GetForCurrentThread().Dispatcher().ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
Update();
m_renderer->Render();
m_deviceResources->Present();
}
else
{
CoreWindow::GetForCurrentThread().Dispatcher().ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
}
}
}
Y esta es una breve descripción de lo que hace este bucle principal del juego.
Si la ventana del juego no está cerrada, envíe todos los eventos, actualice el temporizador y, a continuación, represente y presente los resultados de la canalización de gráficos. Hay mucho más que decir sobre esas preocupaciones, y lo haremos en los temas Definir el marco de la aplicación para UWP del juego, Marco de representación I: Introducción a la representación y Marco de representación II: Representación del juego. Pero esta es la estructura de código básica de un juego DirectX para UWP.
Revise y actualice el archivo package.appxmanifest.
El archivo Package.appxmanifest contiene metadatos sobre un proyecto de UWP. Esos metadatos se usan para empaquetar e iniciar el juego, y para su envío a Microsoft Store. El archivo también contiene información importante que usa el sistema del jugador para proporcionar acceso a los recursos del sistema que el juego necesita para ejecutarse.
Inicie el diseñador de manifiestos
Para obtener más información sobre el archivo de paquete package.appxmanifest y el empaquetado, consulta el Diseñador de Manifiestos . Por ahora, eche un vistazo a la pestaña Capacidades de y examine las opciones proporcionadas.
Si no seleccionas las funcionalidades que usa tu juego, como el acceso a la Internet para el panel global de puntuación alta, no podrás acceder a los recursos ni características correspondientes. Al crear un nuevo juego, asegúrate de seleccionar las funcionalidades necesarias para las API a las que llama el juego.
Ahora echemos un vistazo al resto de los archivos que vienen con el juego de ejemplo Simple3DGameDX .
Revisión de otras bibliotecas importantes y archivos de código fuente
Si tienes intención de crear una plantilla de proyecto de juego para ti, de modo que puedas reutilizarla como punto de partida para proyectos futuros, querrás copiar GameMain.h
y GameMain.cpp
del proyecto Simple3DGameDX que descargaste y añadirlos a tu nuevo proyecto de aplicación principal. Estudie esos archivos, aprenda lo que hacen y quite todo lo que sea específico de Simple3DGameDX. También comente todo aquello que dependa del código que aún no haya copiado. Solo a modo de ejemplo, GameMain.h
depende de GameRenderer.h
. Podrás quitar la marca de comentario mientras copias más archivos de Simple3DGameDX.
Esta es una breve encuesta de algunos de los archivos de Simple3DGameDX que encontrarás útiles para incluir en tu plantilla, si estás haciendo uno. En cualquier caso, son igualmente importantes para entender cómo funciona el propio Simple3DGameDX.
Archivo de origen | Carpeta de archivos | Descripción |
---|---|---|
DeviceResources.h/.cpp | Utilidades | Define la clase DeviceResources de |
DirectXSample.h | Utilidades | Proporciona funciones auxiliares como ConvertDipsToPixels. ConvertDipsToPixels convierte una longitud en píxeles independientes del dispositivo (DIP) a una longitud en píxeles físicos. |
GameTimer.h/.cpp | Utilidades | Define un temporizador de alta resolución útil para juegos o aplicaciones de representación interactiva. |
GameRenderer.h/.cpp | Renderización | Se define la clase GameRenderer, que implementa una canalización de representación básica. |
GameHud.h/.cpp | Renderización | Define una clase para representar una pantalla de cabeza (HUD) para el juego, usando Direct2D y DirectWrite. |
VertexShader.hlsl y VertexShaderFlat.hlsl | Sombreadores | Contiene el código de lenguaje de sombreador de alto nivel (HLSL) para sombreadores de vértices básicos. |
PixelShader.hlsl y PixelShaderFlat.hlsl | Sombreadores | Contiene el código de lenguaje de sombreador de alto nivel (HLSL) para sombreadores de píxeles básicos. |
ConstantBuffers.hlsli | Sombreadores | Contiene definiciones de estructuras de datos para búferes de constantes y estructuras de sombreador utilizadas para pasar las matrices modelo-vista-proyección (MVP) y datos por vértice al sombreador de vértices. |
pch.h/.cpp | No disponible | Contiene C++/WinRT, Windows y DirectX comunes. |
Pasos siguientes
En este punto, hemos mostrado cómo crear un nuevo proyecto para UWP para un juego DirectX, hemos visto algunas de las piezas en él y hemos empezado a pensar en cómo convertir ese proyecto en una especie de plantilla que se puede volver a usar para juegos. También hemos visto algunas de las piezas importantes del juego de ejemplo Simple3DGameDX.
La siguiente sección es Definir el marco de la aplicación UWP del juego. Allí veremos más detenidamente cómo funciona Simple3DGameDX .