1. How to Create Your
First
Windows 8 Metro-style Game
Chas. Boyd
Principal Program Manager
Microsoft Corporation
2. Three Presentations Today
Step by Step through Game Development
1) How to set up the game
2) How to code it <- You are here
3) How to optimize it
3. Agenda
Quick summary of the platform
Step through the process of development
from a programmer’s perspective:
App Initialization
Opening a Window
Rendering Graphics
Loading and Saving
Adding Input Controls
Adding Sound Effects
Adding an Art Pipeline
This talk’s sample code is in C++
5. Metro style apps Desktop apps
View
DX XAML HTML / CSS
C
Controller
C C#
Model
JavaScript HTML C #
C++ VB JavaScript
C++ V
WinRT APIs B
System Services
Communication Graphics Devices
& Data & Media & Printing
.NE
Application Model Internet
Win32 T
Explorer SL
Kernel
Windows Kernel Services
6. Your Killer Game
Movies & Cut Connected
Graphics Game Input Audio Local Services Tools
Scenes Services
DirectX Pointer Windows Visual
Direct3D WASAPI PLM
Video Point Live Studio
Media Windows Asset
Direct2D Sensor API XAudio2 AppData
Foundation Store Viewers
Asset
HTML XInput Contracts Xbox LIVE
Processors
XAML
7. Windows Runtime
All WinRT APIs are native
WinRT APIs feel natural in C++, C#/VB, and JavaScript
Reuse of portable C++ code just works
WinRT APIs provide rich access to devices, OS, and
services
HTML5/CSS/JavaScript and XAML are great for Metro style
apps
Providing a rich set of controls
Native DirectX is great for Metro style apps
8. Updated C++ language support
File->New Project templates for native DirectX C++
apps
DirectX HLSL shader compilation and syntax
highlighting
Packaging compiled HLSL shaders into the .appx
package
Support for other asset types in MSBuild and previewer
21. 3D Graphics via Direct3D 11
3D Graphics uses the same API as on Desktop/Classic
WinRT API set includes only the latest DirectX 11 syntax
DirectX 11 API supports multiple hardware generations
via FeatureLevels: Feature_Level_9, Feature_Level_10, Feature_Level_11
Direct3D 11 updated for Windows 8
22. Creating a swap chain
CoreWindow // app’s core window
ComPtr ID3D11Device1 // renderer
ComPtr IDXGISwapChain1 // front/back buffers of
RT
// Obtain the final swap chain for this window from the DXGI factory.
// the Direct3D device that will render to it
// IUnknown interface on our core window
// double or triple buffered, stereo, etc.
nullptr // allow on all displays
// the resulting swap chain object
23. void myApp::Render()
{
m_d3dContext->OMSetRenderTargets( // rebind every frame!
1,
m_renderTargetView.GetAddressOf(),
m_depthStencilView.Get() );
if (!m_loadingComplete) // only draw the cube once it's loaded
return; // (this is async)
m_d3dContext->IASetVertexBuffers(
0, 1,
m_vertexBuffer.GetAddressOf(),
&stride,
&offset );
m_d3dContext->IASetIndexBuffer(
m_indexBuffer.Get(),
DXGI_FORMAT_R16_UINT, 0 );
26. Process Lifetime Management
Suspend/Resume
User suspending
Running Suspended Terminated
Launches Low Memory
App App App
App resuming
27. using namespace Concurrency;
float f = 1.0f;
task<int>([=]() // task defined with capturing lambda
{
return foo(f);
}).then([](int x) // continuation lambda argument is return value of previous
{
bar(x);
}).then(baz); // continuation using existing function baz()
32. Mouse and Touch Input
win->PointerPressed += ref new TypedEventHandler<CoreWindow^,PointerEventArgs^>
(this, &LonLatController::OnPointerPressed);
void LonLatController::OnPointerPressed(
_In_ CoreWindow^ sender,
_In_ PointerEventArgs^ args
)
{
float2 position = float2( // position of contact
args->CurrentPoint->Position.X,
args->CurrentPoint->Position.Y
);
m_lonLatLastPoint = position; // save for use in controller
m_lonLatPointerID = args->CurrentPoint->PointerId;
}
33. // Arrow keys or WASD example
auto upKeyState = window->GetKeyAsyncState(VirtualKey::Up);
auto wKeyState = window->GetAsyncKeyState(VirtualKey::W);
if (upKeyState & CoreVirtualKeyStates::Down ||
wKeyState & CoreVirtualKeyStates::Down)
{
m_playerPosition.y += 1.0f;
}
34.
35. using Windows::Devices::Sensors;
// Get current reading from sensor
OrientationSensorReading^ orientationReading = m_orientationsensor->GetCurrentReading();
SensorQuaternion^ quat = orientationReading->Quaternion;
// Transform quaternion from device orientation space to world space
// Orientation space is Z-up, right-handed coordinate system
// World space is Y-up, left-handed coordinate system
XMVECTOR orientationQuat = XMVectorSet(-quat->X, quat->Z, quat->Y, -quat->W);
// Create a rotation matrix from the quaternion
// This matrix can be used to rotate an object inside the scene to match
// the rotation of the device
XMMATRIX rotXMMatrix = XMMatrixRotationQuaternion(orientationQuat);
36. Windows 8 supports Xbox360 -compatible controller
Check out new ControllerSketch sample
Demonstrates game controller usage from JavaScript app
37. if ( m_xinputState.Gamepad.wButtons & XINPUT_GAMEPAD_A )
{
m_aButtonWasPressed = true;
}
else if ( m_aButtonWasPressed )
{
m_aButtonWasPressed = false; // Trigger once, only on button release
TriggerSoundEffect();
}
38. if (abs(thumbLeftX) < XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
thumbLeftX = 0;
SHORT thumbLeftY = inputState.Gamepad.sThumbLY;
if (abs(thumbLeftY) < XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
thumbLeftY = 0;
combinedTiltX += (float)thumbLeftX / 32768.0f;
combinedTiltY += (float)thumbLeftY / 32768.0f;
40. // Create the XAudio2 engine and mastering voice on the default audio device
// Load all audio data for the sound effect into a single in-memory buffer
new
// Create a single source voice for a sound effect
// Trigger sound effect: queue in-memory buffer for playback and start the voice
44. Pro Dev Hints
Find commands in the IDE via the search textport
Set up a multi-monitor dev PC with a touch
monitor as the primary
To work with the samples, set a breakpoint inside
the DX:: macro in DirectSample.h line 18
45. Time to Act
Biggest opportunity. Ever.
Windows 8 Consumer Preview is now available.
Check out the store.
Go build great games.
http://dev.windows.com