XNA Game – Rotation – Starting the Graphics – Part 9

The next stage in the game is to plumb in the graphics and start to link up the XNA game so that it initialises and draws the board.

When you create a new XNA game project in Visual Studio it creates you a game class that inherits from Microsoft.Xna.Framework.Game.  This class gives you the basic game pipeline that you can easily add your code into.  Below is a listing of the class (with the methods that we are interested in).

public class RotationGame : Microsoft.Xna.Framework.Game
{
    protected override void LoadContent()
    {
    }

    protected override void Update(GameTime gameTime)
    {
    }

    protected override void Draw(GameTime gameTime)
    {
    }
}

Here is an explanation of what the methods are for:

LoadContent: where you put all of your code to initially load all of your graphics that you are going to need in the game.  I believe that the XNA framework behind the scenes loads your content into RAM providing fast access during the game.

Update: where you put all of your game logic.  This method is for updating the state of the game, reading inputs from the user and reacting to them.

Draw: where you put all of your code to draw the graphics onto the screen.

The first thing that I had to do was create a tile graphic that I can draw onto the screen.  I made a design decision to make all of the tiles in the game 40 pixels by 40 pixels.  I then cracked open paint and created a tile for every letter, a blank tile and a tile that can never contain a letter.  When naming the files I gave each letter a standard name which was StandardTile + LetterName ie for C the file name is “StandardTileC”.  The reason for this will become apparent later.

As I’m now starting to use the XNA framework to make my game come alive, I am conscious of the fact that I don’t want to couple the game to the XNA framework.  My goal is to have a clear separation.  What I ideally want is for the game logic and libraries to expose a set of interfaces to send inputs to and receive outputs from.  This way I can plug in an implementation for the XNA framework for now and in the future it should be more straight forward to use something like Mono Touch so I can bring the game to the iPhone and iPad.

To move towards the end goal of not tying myself to the XNA framework I have added a new class library called Rotation.Drawing.  The rule of thumb for now is that any class that references the XNA framework goes into this class library.  This way I am forced to think about separation as I go along and it will make it easier to clearly see what needs reworking to make the code even more loosely coupled.

My idea to keep the code loosely coupled is to have an interface class IDrawable item.  Any class marked with this in the main library is drawable and needs drawing on the screen.  At the moment I am only concentrating on drawing the squares of the board so I have marked the Square class as IDrawable.  I have designed another interface IGetDrawableItems.  Any class that implements this provides a way to return a collection of all of its drawable items.  The Board class implements this interface and simply returns all of it’s squares.

Now I have a way of easily extracting out all of the classes that need drawing, I need a way of drawing them to the screen.  To do this I have another interface IItemDrawer.  This interface has two methods on it CanDraw and Draw.  The idea is to have an implementation of this interface for each type that I want to draw.  The implementation will return true for CanDraw for the type that it can draw and implement draw to draw that item to the screen.

As the only drawable item I have at the moment is a square, I have just implemented the square item drawer.  The square item drawer draws the square and tile to the screen.  Remember when I said that I named the tile images using predictable file names, well the reason for that is that the square item drawer can get the current tile and use that to build the file name of which letter to draw onto the screen.

I am using the factory pattern to create my ItemDrawers.  I have a factory called ItemDrawererFactory that is responsible for choosing the correct item drawer based on the drawable item that you give it.

All of this means that the basic work flow for drawing the board is:

1.  Call get drawable items to get all of the things that we need to draw

2.  For each drawable item call the ItemDrawerFactory to create us an Item Drawer for that item

3.  Call draw on the Item Drawer passing in the drawable item

That’s it!  I love the way by using patterns and keeping our classes simple and focused you can implement powerful solutions in a few simple steps.

To get a board to draw on the screen all we need to do is plug all of the classes together that we have designed so far to spin up a new board and fill it with letters.  Here is the code:

_board = new BoardFactory().Create();
var boardFiller = new BoardFiller(new StandardTileFactory(new LetterLookup()));
boardFiller.Fill(_board);

Then we just need to implement the workflow detailed above the get the item drawers and draw each item, to do that the first bit of code to get the drawables (step 1 in the work flow) can go in load content as for now it only needs to be called once.  Here is the code:

_itemDrawerFactory = new ItemDrawerFactory(new List<IItemDrawer>{ new SquareDrawer()});
_drawableItems = _board.GetDrawables();

Now all that needs to be done is implement steps 2 and 3 of the work flow in the Draw method of the game:

foreach (var drawable in _drawableItems)
{
    var drawer = _itemDrawerFactory.Create(drawable);
    drawer.Draw(spriteBatch, _textureLoader, drawable);
}

For now I am using manual constructor injection rather than using an IoC container just to get things up and running.  

Well it’s certainly a start but I think the designers out there will definitely be sleeping easy!  Pretty cool to finally see my vision for the game being rendered onto the screen.

At the moment the code to fire things up is hard coded, clunky and not optimal.  The main purpose of this post was just to get the graphics being drawn to the screen.  The other thing I don’t like is that the draw code is being called every frame (60 times per second) for every square (all 81 of them) even though they aren’t changing.  It would be nice if draw was only called if that part of the screen needs updating.  I have a really cool idea for how to implement that but that’s for a future post so stay tuned.

As always you can get the source code down it’s on github.  I have also marked this post with branch name part9, so if you are reading this in the future you can switch to that branch to see what I was up to at this point. Git commands to do so are:

If you don’t have the source code:

git clone git@github.com:kevholditch/Rotation.git
git checkout -b part9 origin/part9

If you have the code on cloned already then issue the following git commands:

git fetch
git checkout -b part9 origin/part9

As always comments & suggestions invited, until next time…