WP8 Game Development for Beginners

Embed Size (px)

DESCRIPTION

doc for develope

Citation preview

  • Windows Phone 8 2D Game DevelopmentFor Beginners

    Cao PhongDeveloper Tech Support ManagerNokia, Vietnam

  • Content

    Setting up a basic framework with XNA

    Setting up a basic framework with Direct3D:

    DirectX TK

    Direct3D (native)

    Direct3D with XAML and XAML with Direct3D app

    Porting XNA to Asha Touch

  • XNA vs Direct3D

    XNA

    Pros:- Simple setup and easy to use- Legacy support- Can be quickly ported to Asha

    Touch

    Cons:- Unable to use WP8 APIs: In-app

    purchase, NFC, Bluetooth- Lack of native code support

    Direct3D

    Pros:- Best performance- Leverage on WP8 APIs: In-app

    purchase, NFC, Bluetooth- Native code support- Flexibility to add nice game

    effects

    Cons:- Requiring quite a lot steps to set

    up at the beginning- Fairly complex to use

  • XNAChoose project template

  • Main loop

    protected override void Update(GameTime gameTime){

    // Allows the game to exitif (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)

    this.Exit();

    // TODO: Add your update logic herebase.Update(gameTime);

    }

    protected override void Draw(GameTime gameTime){

    GraphicsDevice.Clear(Color.CornflowerBlue);

    // TODO: Add your drawing code herebase.Draw(gameTime);

    }

  • Fill RectangleTexture2D m_pRectTexture = null;Rectangle m_rect;Color m_color;

    public void FillRect(int color, int x, int y, int w, int h){

    if (m_pRectTexture == null){

    m_pRectTexture = new Texture2D(GraphicsDevice, 1, 1);m_pRectTexture.SetData(new Color[] { Color.White });

    }

    m_rect.X = x;m_rect.Y = y;m_rect.Width = w;m_rect.Height = h;

    m_color.A = (byte)((color & 0xFF000000) >> 24);m_color.R = (byte)((color & 0x00FF0000) >> 16);m_color.G = (byte)((color & 0x0000FF00) >> 8);m_color.B = (byte)((color & 0x000000FF));

    spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque);spriteBatch.Draw(m_pRectTexture, m_rect, m_color);spriteBatch.End();

    }

  • Draw Image

    protected override void Draw(GameTime gameTime){

    GraphicsDevice.Clear(Color.CornflowerBlue);

    // Draw a rectangle (color=red, x=50, y=100, w=100, h=50)FillRect(0xFF0000, 50, 100, 100, 50);

    // Draw an image (x=10, y=10)spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied);spriteBatch.Draw(imgGirl, new Vector2(10, 10), Color.White);spriteBatch.End();

    base.Draw(gameTime);}

    public Texture2D LoadImage(String file){

    try{

    Stream fs = TitleContainer.OpenStream(file);Texture2D img = Texture2D.FromStream(GraphicsDevice, fs);fs.Close();fs = null;return img;

    }catch (Exception e){

    // Handle errorreturn null;

    }}

  • Direct3D

    DirectX TK (Toolkit)There is a collection of helper classes united under the name of DirectX Tool Kit [4] - or in short DirectX TK - started by Shawn Hargreaves. This library contains convenience classes that help write code that uses Direct X. It also contains a tool called MakeSpriteFont that can create fonts to be used in game.

    Download link: http://directxtk.codeplex.com/releases/view/98986

  • Direct3D Choose project template

  • Fill Rectanglevoid GameRenderer::FillRect(int color, int x, int y, int w, int h){

    // Create TextureCD3D11_TEXTURE2D_DESC texDesc(

    DXGI_FORMAT_R8G8B8A8_UNORM,// DXGI_FORMAT1,// width1,// height1,// arraySize1,// mipLevelsD3D11_BIND_SHADER_RESOURCE// bindFlags

    );

    D3D11_SUBRESOURCE_DATA colorData = { 0 };Microsoft::WRL::ComPtr texture;int a[] = {0xFF000000 | ((color & 0xFF) > 8) > 16)}; // argb => abgrcolorData.pSysMem = &a;colorData.SysMemPitch = sizeof(a);colorData.SysMemSlicePitch = 0;m_d3dDevice->CreateTexture2D(&texDesc, &colorData, texture.GetAddressOf());Microsoft::WRL::ComPtr view;m_d3dDevice->CreateShaderResourceView(texture.Get(), 0, &view);

    // Draw In a RectangleRECT rect = {x, y, x + w, y + h}; // left, top, right, bottomspriteBatch->Begin();spriteBatch->Draw(view.Get(), rect, Colors::White);spriteBatch->End();

    }

  • DirectDraw Surface (DDS)DirectDraw Surface file format Filename extension: DDS Data compressed with the lossy S3 Texture Compression (S3TC) algorithm Support phone GPUs and consoles (PSP, PS3, Xbox 360)

    Converting images to .dds files DirectXTex library:

    http://directxtex.codeplex.com/SourceControl/changeset/22746

    NVIDIA Texture Tools:https://developer.nvidia.com/nvidia-texture-tools-adobe-photoshophttps://developer.nvidia.com/content/texture-tools-208-64-bit

    Easy2Convert PNG to DDS:http://www.easy2convert.com/png2dds/

  • Draw Image

    Load resource

    1. Declare texture in GameRenderer.h:ID3D11ShaderResourceView* m_catTexture;

    2. Include DDS loader header in GameRenderer.cpp:#include

    3. Load texture in CreateDeviceResources method:

    void GameRenderer::CreateDeviceResources(){Direct3DBase::CreateDeviceResources();spriteBatch = std::shared_ptr(new SpriteBatch(m_d3dContext.Get()));DX::ThrowIfFailed(CreateDDSTextureFromFile(m_d3dDevice.Get(),

    L"Assets\\CatTexture.dds", NULL, &m_catTexture, NULL));m_loadingComplete = true;

    }

  • Draw Imagevoid GameRenderer::Render(float timeTotal, float timeDelta){

    const float midnightBlue[] = { 0.098f, 0.098f, 0.439f, 1.000f };

    m_d3dContext->ClearRenderTargetView(m_renderTargetView.Get(), midnightBlue);m_d3dContext->ClearDepthStencilView(m_depthStencilView.Get(), D3D11_CLEAR_DEPTH,

    1.0f, 0);

    // Only draw once the resources are loaded (loading is asynchronous).if (!m_loadingComplete){

    return;}

    m_d3dContext->OMSetRenderTargets(1, m_renderTargetView.GetAddressOf(),m_depthStencilView.Get());

    // Fill a rectangleFillRect(0xFF0000, 50, 100, 100, 50);

    // Draw an image (x=10, y=10)spriteBatch->Begin();spriteBatch->Draw(m_catTexture, XMFLOAT2(10, 10));spriteBatch->End();

    }

  • Direct3D App Choose project template

  • 3D Coordinate Systems

    Left-handed versus Right-handed

    DirectX: usually uses Left-handed coordinate system

    OpenGL: usually uses Right-handed coordinate system

  • HLSL (High Level Shader Language) The language used to write shaders for GPUs in DirectX

    SimpleVertexShader.hlsl

    VertexShaderOutput main(VertexShaderInput input){

    VertexShaderOutput output;float4 pos = float4(input.pos, 1.0f);

    // Transform the vertex position into projected space.pos = mul(pos, model);pos = mul(pos, view);pos = mul(pos, projection);output.pos = pos;

    // Pass through the color without modification.output.color = input.color;

    return output;}

    SimplePixelShader.hlsl

    float4 main(PixelShaderInput input) : SV_TARGET{

    return float4(input.color,1.0f);}

  • DirectX Math and HLSLMatrix Vector

    OpenGL Column-major Column vectors

    GLSL Column-major Column vectors

    DirectX Math Row-major Row vectors

    HLSL (by default) Column-major Row vectors

    Solutions:

    Transpose matrices before sending to HLSL

    Use the #pragma pack_matrix directive in shaders:

    #pragma pack_matrix( row_major )

  • DirectX PrimitivesPoint Lists Line Lists Line Strips

    Triangle Lists Triangle Strips

  • Face and Vertex Normal Vectors

    Each face in a mesh has a perpendicular unit normal vector

    The vector's direction is determined by the order in which the vertices are defined and by whether the coordinate system is right- or left-handed

    The face normal points away from the front side of the face

    In Direct3D, only the front of a face is visible

    A front face is one in which vertices are defined in clockwise order.

  • Use row-major in HLSL so that you dont need to transpose matrices from DirectX Math

    1. Add directive in vertex shader:

    Direct3D App (Cont.)

    #pragma pack_matrix( row_major )

    SimpleVertexShader.hlsl

    2. Remove all transpose matrices in CubeRenderer.cpp:void CubeRenderer::CreateWindowSizeDependentResources(){

    Direct3DBase::CreateWindowSizeDependentResources();

    float aspectRatio = m_windowBounds.Width / m_windowBounds.Height;float fovAngleY = 70.0f * XM_PI / 180.0f;if (aspectRatio < 1.0f){

    fovAngleY /= aspectRatio;}

    XMStoreFloat4x4(&m_constantBufferData.projection,XMMatrixTranspose(XMMatrixPerspectiveFovRH(fovAngleY,

    aspectRatio,0.01f,100.0f)));}

    void CubeRenderer::Update(float timeTotal, float timeDelta){

    (void) timeDelta; // Unused parameter.

    XMVECTOR eye = XMVectorSet(0.0f, 0.7f, 1.5f, 0.0f);XMVECTOR at = XMVectorSet(0.0f, -0.1f, 0.0f, 0.0f);XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);

    XMStoreFloat4x4(&m_constantBufferData.view,XMMatrixTranspose(XMMatrixLookAtRH(eye, at, up)));

    XMStoreFloat4x4(&m_constantBufferData.model,XMMatrixTranspose(XMMatrixRotationY(timeTotal * XM_PIDIV4)));

    }

  • Apply orthographic projection for our 2D game framework with Left-handed coordinate system

    Direct3D App

    void CubeRenderer::CreateWindowSizeDependentResources(){

    Direct3DBase::CreateWindowSizeDependentResources();

    XMStoreFloat4x4(&m_constantBufferData.projection,XMMatrixOrthographicOffCenterLH(

    0, // ViewLeftm_windowBounds.Width, // ViewRightm_windowBounds.Height, // ViewBottom0, // ViewTop-1.0f, // NearZ1.0f // FarZ

    );

    }

  • Update view matrix with Left-handed coordinate system

    Direct3D App

    void CubeRenderer::Update(float timeTotal, float timeDelta){

    (void) timeDelta; // Unused parameter.

    XMVECTOR eye = XMVectorSet(0.0f, 0.0f, -1.0f, 0.0f);XMVECTOR at = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f);XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);

    XMStoreFloat4x4(&m_constantBufferData.view, XMMatrixLookAtLH(eye, at, up));XMStoreFloat4x4(&m_constantBufferData.model, XMMatrixIdentity());

    }

  • Disabling Z buffer in 2D mode to enable back-to-front rendering

    Direct3D App

    // Initialize the Direct3D resources required to run.void Direct3DBase::Initialize(CoreWindow^ window){

    m_window = window;

    CreateDeviceResources();CreateWindowSizeDependentResources();

    D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc;ID3D11DepthStencilState* depthDisabledStencilState;

    depthDisabledStencilDesc.DepthEnable = false;depthDisabledStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;depthDisabledStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;depthDisabledStencilDesc.StencilEnable = true;depthDisabledStencilDesc.StencilReadMask = 0xFF;depthDisabledStencilDesc.StencilWriteMask = 0xFF;depthDisabledStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;depthDisabledStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;depthDisabledStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;depthDisabledStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;depthDisabledStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;depthDisabledStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;depthDisabledStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;depthDisabledStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

    // Create the state using the device.m_d3dDevice->CreateDepthStencilState(&depthDisabledStencilDesc, &depthDisabledStencilState);m_d3dContext->OMSetDepthStencilState(depthDisabledStencilState, 1);

    }

    Direct3DBase.cpp

  • Render 3 rectangles using Triangle Lists

    Direct3D App

    VertexPositionColor cubeVertices[] = {

    {XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 1.0f)},{XMFLOAT3(100.0f, 0.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 1.0f)},{XMFLOAT3(100.0f, 100.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 1.0f)},{XMFLOAT3(0.0f, 100.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 1.0f)},{XMFLOAT3(50.0f, 50.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 0.0f)},{XMFLOAT3(150.0f, 50.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 0.0f)},{XMFLOAT3(150.0f, 150.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 0.0f)},{XMFLOAT3(50.0f, 150.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 0.0f)},{XMFLOAT3(100.0f, 100.0f, 0.0f), XMFLOAT3(1.0f, 0.0f, 0.0f)},{XMFLOAT3(200.0f, 100.0f, 0.0f), XMFLOAT3(1.0f, 0.0f, 0.0f)},{XMFLOAT3(200.0f, 200.0f, 0.0f), XMFLOAT3(1.0f, 0.0f, 0.0f)},{XMFLOAT3(100.0f, 200.0f, 0.0f), XMFLOAT3(1.0f, 0.0f, 0.0f)},

    };

    unsigned short cubeIndices[] = {

    0,1,2,0,2,3,4,5,6,4,6,7,8,9,10,8,10,11,

    };

    CubeRenderer.cpp

  • Direct3D App

    0 (0,0) 1 (100,0)

    2 (100,100)3 (0,100)

  • Texture Mapping0 (0,0) 1 (300,0)

    2 (300,300)3 (0,300)

    0.0 1.0

    1.0

    U

    V

    Texturing allows adding photographs and other images onto polygon faces

    The format of the textures are Direct Draw Surface (.dds) files

    In the texel coordinate system, the width value is named "U" and the height value is named "V: The width goes from 0.0 on the left to 1.0 on the right The height goes from 0.0 on the top to 1.0 on the bottom

    Texel Coordinate System

  • Update texture coordinates and render

    VertexPositionTexture cubeVertices[] = {

    {XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 0.0f)},{XMFLOAT3(300.0f, 0.0f, 0.0f), XMFLOAT3(1.0f, 0.0f, 0.0f)},{XMFLOAT3(300.0f, 300.0f, 0.0f), XMFLOAT3(1.0f, 1.0f, 0.0f)},{XMFLOAT3(0.0f, 300.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 0.0f)},

    };

    Map texture to a square having width=300, height=300 and render it at (0, 0):

  • Choosing the right project template for your game

    Direct3DDirect3D with XAML

    XAML with Direct3D

    UI (XAML) No Yes Yes

    Exclusive Features No Yes Yes

    Acts as a XAML control (can be placed anywhere on the screen, above or next to other XAML controls)

    No No Yes

    Features

    Exclusive Features: Background Agents Browser Control Map Control Background Transfer Service Live Tiles Push Notifications The Windows Phone Ad Control Localized resources XAML controls

  • Choosing the right project template for your game for WP8

    Direct3DDirect3D with XAML

    XAML with Direct3D

    Startup time 2 1 1

    Rendering 3 2 1

    Performance

    Unofficial tests: Direct3D with XAML app is 18 20%

    slower than Direct3D app XAML with Direct3D app is 5 7%

    slower than Direct3D with XAML app

    * Note: higher number means faster performance

  • Direct3D with XAML appChoose project template

  • Direct3D with XAML appUses the DrawingSurfaceBackgroundGrid control Render graphics that are displayed across the entire background of your app, behind any XAML

    controls in your UI Must be the root element of the XAML tree and is always the full size of the screen

    Structure Made up of two components: a XAML-based Windows Phone app and a component thats based on

    the Windows Phone Runtime The XAML engine creates and maintains a Direct3D graphics device. Once per frame, the XAML

    engine passes the graphics device and an associated render target to the Windows Phone Runtime component

    Main classes MainPage: hosts your XAML-based UI and your managed code CubeRenderer: where the actual drawing to the shared texture is performed PhoneDirect3DXamlAppComponent: contains touch input handling

  • XAML with Direct3D appChoose project template

  • XAML with Direct3D appUses the DrawingSurface control Render graphics that are displayed behind or inline with XAML controls and content The size and layout of your DrawingSurface are handled just as they are with other XAML controls

    Structure Made up of two components: a XAML-based Windows Phone app and a component thats based on

    the Windows Phone Runtime The Windows Phone Runtime component creates a Direct3D graphics device, which it uses to create

    a Texture that is shared with the XAML app. The Windows Phone Runtime component uses Direct3D to draw onto the Texture. The XAML engine maintains a swap chain that copies the texture to the screen within the bounds of the DrawingSurface control

    Main classes MainPage: hosts your XAML-based UI and your managed code CubeRenderer: where the actual drawing to the shared texture is performed Direct3DInterop: contains touch input handling

  • 35

    Porting 2D XNA Games to Asha Full Touch

  • Minimal porting effort: 1 5 working days

    Leverage on Nokia Store payment system to maximize revenue:

    In-app purchasing with 145 operator billing integrations

    In-app advertising with Nokia Ad Exchange (NAX): 120 ad networks in over 200 countries

    Why porting to Asha Full Touch?

  • Screen Resolution

    480x800 240x400

    All images are scaled down by half

    All coordinates are divided by half

  • Images

    68x74 34x37

  • Coordinates and Alignment

    (x, y) (x / 2, y / 2)

  • XNA & J2ME - C# and Java language

    C# Java

    namespace package

    const final

    bool boolean

    override N/A

  • XNA and Java ME Frameworks

    XNA Java ME

    Microsoft.Xna.Framework.Game javax.microedition.lcdui.Canvasjava.lang.Runnable

    GraphicsDeviceManagerGraphicsDeviceSpriteBatchRenderTarget2D

    Graphics

    protected override void Update(GameTimegameTime)protected override void Draw(GameTimegameTime)

    public void run()public void paint(Graphics g)

    Color int color

    Texture2D Image

  • XNA and Java ME Frameworks

  • Rule #1 All coordinates divided by half

    k_Factor:

    1: Windows Phone

    2: AshaFT

  • Rule #2 Do relative alignment, no hard code

    DON'T's DOs

  • Rule #3 Use J2ME wrapper classes in XNA

  • Rule #3 Use J2ME wrapper classes in XNA

  • 1. Develop or modify XNA source code with J2ME wrapper classes:

    Graphics Image Touch input and media related classes

    2. Resize all images to one half and copy to AshaFT project

    3. Update all coordinates with scale factor =

    4. Replace Microsoft.Xna.Framework.Game by Javax.microedition.lcdui.Canvasand java.lang.Runnable

    5. Remove all wrapper classes, go with the ones in MIDP such as javax.microedition.lcdui.Graphics

    6. Optimize memory and performance

    Porting Steps

  • mcpp preprocessorhttp://mcpp.sourceforge.net/

    Implements all of C90, C99 and C++98 specifications. Provides a validation suite to test C/C++ preprocessor's conformance and

    quality comprehensively. When this validation suite is applied, mcppdistinguishes itself among many existing preprocessors.

    Has plentiful and on-target diagnostics to check all the preprocessing problems such as latent bug or lack of portability in source code.

    Has #pragma directives to output debugging information. Is portable and has been ported to many compiler-systems, including GCC

    and Visual C++, on UNIX-like systems and Windows.

    Has various behavior modes. Can be built either as a compiler-specific preprocessor to replace the

    resident preprocessor of a particular compiler system, or as a compiler-independent command, or even as a subroutine called from some other main program.

    Provides comprehensive documents both in Japanese and in English. Is an open source software released under BSD-style-license.

  • Develop a game fully in XNA

  • Building jar and jad automatically

  • Launch the file with Nokia Java Emulator

  • Thank you!

    https://www.facebook.com/groups/viet.nok.devLets discuss more: