Bizzy Bees XNA to DirectX/DirectXTK – Part 3
This is part of a blog series… if you came here directly you might want to read the introduction first.
Drawing the Scene
Now we have all our assets and it’s time to draw them on the screen.
In order to draw something we’ll need
a) something to draw – which is going to be our dds sprites (or textures)
b) a start position
In our game we’ll draw the following things on the screen
- The Background at 0,0 where 0,0 is the top left corner
- The Flowers and Bees but we’ll get to those later
- The Foreground at 0,0 as well. We can look at it as a puppet show where the foreground will sit on top of the area where we draw the flowers so that when they drop down they will clip behind the edges of the foreground texture
- The HUD (Heads Up Display) which will be a HUD background painted at 7,7 (7 pixels from the top and 7 pixels from the left). When painting the HUD we’ll also print out the score, the level name (in this case MARATHON), some game instructions as well as bees indicating how many lives we have left.
- A GAME OVER text on top of the whole scene when the game is lost
Getting things started in the BizzyBeeGame class
1. Add the following methods and member variables in the BizzyBeeGame.h file
private:
shared_ptr<SpriteBatch> spriteBatch;
//Textures
ComPtr<ID3D11ShaderResourceView> backgroundTexture;
ComPtr<ID3D11ShaderResourceView> foregroundTexture;
ComPtr<ID3D11ShaderResourceView> hudBackgroundTexture;
ComPtr<ID3D11ShaderResourceView> flowerMapTexture;
ComPtr<ID3D11ShaderResourceView> beeMapTexture;
ComPtr<ID3D11ShaderResourceView> lifeBeeTexture;
//Fonts
shared_ptr<SpriteFont> hudFont;
void ResetGame();
//Draw functions
void DrawBackground();
void DrawFlowers();
void DrawBees();
void DrawForeground();
void DrawHUD();
void DrawGameOver();
void DrawString(const wchar_t* text, Vector2 position, XMVECTOR color);
void DrawString(const wchar_t* text, Vector2 position, XMVECTOR color, float scale);
Right under #include “Direct3DBase.h” add the following using directives in order to be able to use things like shared_ptr, Vector2 etc.
using namespace std;
using namespace DirectX::SimpleMath;
using namespace DirectX;
using namespace Microsoft::WRL;
So now we have defined
- pointers to all the textures and fonts we’ll use.
- a sprite batch which we will use to draw items to the screen
- a number of draw methods where we will actually draw all the items described above
- Two drawstring methods (one for regular text and one if we want to scale the text). Typically you would create different sprite fonts for different text sizes but I am doing it this way for simplicity. Scaling a font will make it a bit grainy.
2. In BizzyBeeGame.cpp implement all the new methods but let them be empty for now
3. In the BizzyBeeGame::Render method add the folloiwng code to start drawing the scene. Note that all the drawing has to occur between spriteBatch->Begin() and spriteBatch->End()
//Draw the scene
spriteBatch->Begin();
DrawBackground();
DrawFlowers();
DrawBees();
DrawForeground();
DrawHUD();
spriteBatch->End();
4. So far so good, but nothing gets drawn on the screen : ) We’ll have to set up the spriteBatch and load our textures and fonts first in BizzyBeeGame::CreateWindowSizeDependentResources
auto device = m_d3dDevice.Get();
auto context = m_d3dContext.Get();
spriteBatch.reset(new SpriteBatch(context));
//TODO: Load textures
DX::ThrowIfFailed(CreateDDSTextureFromFile(device, L"Assets\\Content\\Background.dds", nullptr, backgroundTexture.ReleaseAndGetAddressOf()));
DX::ThrowIfFailed(CreateDDSTextureFromFile(device, L"Assets\\Content\\Foreground.dds", nullptr, foregroundTexture.ReleaseAndGetAddressOf()));
DX::ThrowIfFailed(CreateDDSTextureFromFile(device, L"Assets\\Content\\HUD.dds", nullptr, hudBackgroundTexture.ReleaseAndGetAddressOf()));
DX::ThrowIfFailed(CreateDDSTextureFromFile(device, L"Assets\\Content\\FlowerMap.dds", nullptr, flowerMapTexture.ReleaseAndGetAddressOf()));
DX::ThrowIfFailed(CreateDDSTextureFromFile(device, L"Assets\\Content\\BeeMap.dds", nullptr, beeMapTexture.ReleaseAndGetAddressOf()));
DX::ThrowIfFailed(CreateDDSTextureFromFile(device, L"Assets\\Content\\AnimatedBee.dds", nullptr, lifeBeeTexture.ReleaseAndGetAddressOf()));
//TODO: Load fonts
hudFont.reset(new SpriteFont(device, L"Assets\\Content\\MyFont.spriteFont"));
//TODO: Initialize the game
ResetGame();
The code here is pretty straight forward, just keep in mind that this loads from the Assets\Content folder on disk, independently of how the filters are set up in the project.
5. Now we have the assets so let’s start drawing them. The BizzyBeeGame::DrawBackground method will look like this, which means, we draw the backgroundTexture at position 0,0.
spriteBatch->Draw(backgroundTexture.Get(), Vector2(0, 0));
6. Implement BizzyBeeGame::DrawForeground the same way but with the foregroundTexture
7. For the HUD we need to print some things so let’s first implement the DrawString methods
void BizzyBeeGame::DrawString(const wchar_t* text, Vector2 position, XMVECTOR color){
DrawString(text, position, color, 1.0f);
}
void BizzyBeeGame::DrawString(const wchar_t* text, Vector2 position, XMVECTOR color, float scale){
hudFont->DrawString(spriteBatch.get(), text, position, color, 0.0f, g_XMZero, scale);
}
8. Implement the DrawHUD method, and draw the background, the level name (MARATHON) and instructions (COLLECT RAINBOW FLOWERS). The text is blue and the level name is slightly smaller than the instruction text
void BizzyBeeGame::DrawHUD(){
spriteBatch->Draw(hudBackgroundTexture.Get(), Vector2(7, 7));
DrawString(L"MARATHON", Vector2(40, 10), Colors::Blue, 0.7f);
DrawString(L"COLLECT RAINBOW FLOWERS", Vector2(45, 115), Colors::Blue);
}
9. Compile and run. you should now se something like this on the screen
It’s not terribly exciting quite yet but in the next few steps we’ll add on all the game components