XNA Game – Rotation – Download from iTunes – Part 19

I have just finished porting the blog from one host to another. Hence the glut of posts that have come in one day. Since my last post almost one year ago I have successfully released the game on iTunes. The game is completely free so why not download it and give it a try.

When I set out on this journey I was trying to write a game using a TDD approach. I don’t know much about the game industry but in business application programming this is how we approach software. I thought it would be both a great learning exercise and interesting experiment to see how the TDD approach would lend itself to game development. The answer, surprisingly well.

In most cases the first time I ran the code it worked. I can only remember using the debugger in earnest once, which is pretty cool. This shows the value of TDD. It also shows the value of writing good unit tests that cover business logic. Anyone who tells you can write code faster without tests is probably lying, if they say they can write code that meets business requirements without tests faster then they definitely are.

So this brings the Rotation game coding series to a close. Stick with the blog for other coding adventures.

Advertisements

XNA Game – Rotation – Finishing up rotation… – Part 18

This will be the final part of my series on making an XNA game from scratch. I hope you have enjoyed the series and learnt a thing or two along the way.

The last part that I needed to do was adding a count of how many rotations the player has made. Then each time the user rotates (either left or right) to decrement the count. If the user makes a block then the user gets an extra rotation for every square in the block. This gives the player a goal for the game.

Again I sound like a broken record here but hopefully this is hammering the point home for any doubters, by using the single responsibility principle and writing decoupled code this was very easy to implement. All I needed to do was have a new class called the RotationManger whose job it is to keep track of rotations that the player has made. The RotationManager has two methods on it rotation made and block found. One will decrement the rotations as a rotation has been made. The other will simply loop around all of the squares in all of the blocks made and count them and add them onto the total amount of rotations that the player has left.

This is again a very simple class to write. After that is done all that was left was to call it in the correct places which is for when a rotation is made there are two events that are fired rotated right and rotation left events. Then when the player finds a block the blocks found event fires. This for me really does emphasize how if you structure your code correctly then adding to it is very easy. They are like lots of little building blocks that you can stick together to make a sky scraper.

As always you can grab all of the source code from github. This is part18 or at the time of writing the master branch also. If you are unsure how to get the code then check out this page.

There are many ways you could take the game from here like add menus, high scores, sounds etc. I hope I’ve given you a taster of what is possible…

I’d like to thank you for reading my series on rotation the game. As always comments welcome.

XNA Game – Rotation – Scoring & Levels – Part 17

We are nearing the home straight now for our game journey.  We have come a long way and although it might not look that pretty the game functions pretty well.  The next thing to do is program the score and the levels.

To keep track of the score I have written a class called the ScoreManager.  The score manager’s responsibility is solely for keeping track of the score.  It has a method to update the score which takes an IEnumerable of blocks found.  The score then gets updated and an immutable score object is returned back.  The score code is pretty straight forward.  Scoring works by you get one point for each square you make within a block.  If you make multiple blocks at the same time then you get a multiplier bonus of the amount of blocks you made simultaneously.

Another part of the game that is missing is levels.  I have decided that you have to make a set amount of squares in blocks to advance the level.  The LevelManager is a class that is designed to keep up with this.  The logic for the level manager is a little more complex as it has to calculate which level that you are on based on the current score.  As always it is fully unit tested.  Actually when I first wrote the level manager and tests there was a subtle bug with the LevelManager when you got exactly the amount of squares that you required to get to the next level.  This highlights again the importance of TDD.  To fix this bug I wrote a test for it to reproduce the bug and sure enough the test failed.  All I had to do then was fix the LevelManager to make the test pass, the bug was caused by a greater than inside an if instead of a greater than or equal to.  The beauty of using TDD is that now this bug will never come back.

To get the score and level information on the screen I just had to make score and level implement the IDrawableItem interface.  Then all I had to do was add an item drawer for the score and the level.  The code automatically picked the rest up.  This is the beauty of using factories to create classes and to do everything dynamically.  If you had to write all of that code manually it would’ve meant updating several places of code to “know” about the new items.  The code is completely decoupled and doesn’t have any knowledge of the items that it’s drawing.

To write the text on the screen I had to use a sprite font.  As I am using mono game there are some nuances with how you have to do this as you have to target the xmb file (that is produced by building content) at the correct target framework.  To do this for Windows all I have done is created a real XNA project solution, added a sprite font to the content and then built it.  Then I have gone back to the rotation game solution and manually added the xmb file as a content file to the content directory of the game project.  When the game gets ported to iPhone this process will have to be repeated except of course I will have to build it to target the correct framework.

One more thing that I wanted to point out in this post is that you really see the value of single responsibility principle when you decide to make changes to how the game works.  When I got the game working I decided that rotating the whole axis as far as it could reach (to the edge of the board) was making the game too easy and not much phone.  So I added another implementation of the ISquareSelector interface.  This time instead of selecting squares right from the center to the nearest edge I created another class called SingleSquareSelector that only goes one square in each direction.  All I had to do (after unit testing the class of course) was to switch the registration in the container to use the SingleSquareSelector and the behaviour changed.  The beauty is that to switch back all I have to do is change the registration back.  This really shows the value of having one class for one purpose.

I know I won’t win any awards for design but the gameplay is really getting there.  You can get the game at this point at part17.  If you are unsure of how to do this then you can check the rotation git details page.

XNA Game – Rotation – Who needs letters? – Part 16

I recently watched the film Indie game. Which is a documentary that follows two indie games for xbox 360 being made (Super Meat Boy & Fez). The film is very good and I would highly recommend watching it (especially if you are interested in these blog posts). During the film the guys were saying that the key to a great game is one that is easy to learn and difficult to master. After watching the film I went back and played on rotation and thought that the concept of rotating to make words, although an interesting idea is fiendishly difficult in practice and would’ve definitely put off potential players of the game.

Instead of rotating your selection to make words I have changed the game so that you rotate colours instead. Much simpler! The idea is to match at four squares together in a square (2 rows of 2) of the same colour. When you successfully create a ‘block’ then that disappears and all of the blocks fall down from the top of the screen to fill in the hole created by the block.

This is where you really see the value of TDD and good use of the single responsibility principle. It took me a little under an hour to make the change from letters to colours, I had to alter the applicable tests to make them work with colours. I updated the code so that all of the tests passed. When I ran the game it worked first time! For anyone that doubts the value of TDD (or having tests in general) that is a key example of why they are so good.

I want to talk a little about the problem I had to solve to make blocks falling animation work smoothly. Workflow of what happens when a block is created:

  1. Board changed event gets fired when the player rotates a selection
  2. In the board changed event handler a check is done to see if any blocks are created, If there are new blocks a blocks created event is raised
  3. In the blocks created event handler a new animation is started to colour in the block that is created
  4. When the animation that colours in the blocks finishes it raises a remove blocks found event (more on this later)
  5. The remove blocks found event handler remaps the board in memory and then starts the blocks falling animation
  6. When the blocks falling animation finishes it raises a board changed event
  7. Notice that the whole workflow is decoupled into reusable chunks. By doing it this way I achieve complete code separation where no part of the system has to know a lot about the other parts. Each unit of the system has a specific job to do. The reason that I raise a remove blocks event and not put that logic in the start of the blocks found animation is to achieve this separation. In the future I might want to animation the falling blocks differently but I probably still will wanted the blocks to be removed. I have got that segregation.

I want to explain how the blocks falling animation works as I think the logic for that is quite interesting. Below is the psuedo code of how the whole process works with the classes the code is in in brackets:

Colour in the blocks so that the user knows they have made a block (BlocksFoundAnimation)
Set the offsets for all of the squares that need to fall (RemoveFoundBlocksEventHandler)
Reorganise all of the squares to their correct positions as if they have fallen down (RemoveFoundBlocksEventHandler)
Replace squares that are in blocks with new colours (RemoveFoundBlocksEventHandler)
Start a falling blocks animation (RemoveFoundBlocksEventHandler)
Decrease the y offset of each square until it reaches 0 (RemoveFoundBlocksEventHandler)
Check to see if the falling squares have created any new blocks (BoardChangedEventHandler)
The important thing to note is that the positions of the squares never actually change. All that I do is swap the tiles between them and set a y offset on each of them to give them the illusion that they are falling. The last piece of the puzzle was to update the square drawer or to be more precise the SquareOriginCalculator to take the y offset of the square into account.

That’s it for this post. As always you can get the code from the part16 branch on github. Check out the instruction page if you are unsure how to do this.

XNA Game – Rotation – Multi platform anyone? – Part 15

After listening to a recent episode of Hanselminutes where he interviewed the draw a stick man guys, I was made aware of Mono Game. Mono game is an open source implementation of the XNA API on every platform including iOS and Android. This is awesome news as it means that with minimal code changes it should be possible to get my game running on every platform. Just goes to show how the open source community is really thriving.

I have reworked the solution quite a bit to turn it into a mono game project. You will need to visit the mono game site to download the mono game platform to be able to run the latest version of the code. The game still works on Windows 7 as is. Before I implement the code to get the game running on iOS and Android, I need to make a few changes to the project to make it cope with running on different platforms.

The first thing I needed to do was take into account the fact that the game will run at different speeds on different platforms. Luckily the XNA framework provides an easy way to do this as it passes an instance of the GameTime class into the update method. The GameTime class gives you that time that has elapsed between the last call to your update method.

To do animations currently I am moving the object a set amount for each call. Now obviously when I port to other platforms (or even run on a different Windows 7 machine) this code won’t work as if the method is called faster it will speed up the animation and vice versa. For example the code to animate A left rotation is something like:

   
square.Angle += GameConstants.Animation.ANGLE_INCREASE_AMOUNT;

Now to fix this we need to pass the GameTime into the animate method. We can now use a speed to determine how much the animation (and in this case the angle) should move. Speed = distance/time so distance = speed*time. So to calculate the distance to move all we need to do is multiply the time elapsed between update calls by our constant speed. So the example code becomes:

square.Angle = (float)(square.Angle - (GameConstants.Animation.ANGLE_INCREASE_SPEED * gameTime.ElapsedGameTime.TotalMilliseconds));

As you can see we are now using a speed to update the angle. I have updated all of the animations to take speed into account. As per usual a TDD style was used and all of the tests have been updated.

If you want to see the latest version of the code please get the latest from the github and switch to branch part15. You can find more details of how to do that on the rotation git page on this blog.

XNA Game – Rotation – Going event driven – Part 14

 

Firstly astute readers will notice that there is no part 13.  This is because I’m slightly superstitious and would rather skip part 13, call me strange but that’s the way it is.

There were a few problems with the way that I’d written animations.  One being that animations were tightly coupled with the actions that they animated and another being that it was hard to know when an animation had finished so that I could start a new animation.  This will be important in the future when I want to chain animations together.

To solve both of these problems I have moved the animations to an event driven model.  Now when actions happen like the selection being rotated, events get raised out and something else can listen to it.  This means that the action is totally decoupled from the animation.

To implement events I first defined an IGameEvent interface.  This is just a marker interface that all game events have to implement.  I then defined an IEventHandler<T> interface where T has to implement IGameEvent and there is one method on the interface Handle(T gameEvent).  Next I defined the EventDispatcher.  The job of the event dispatcher is to dispatch events to the correctly handlers.  It takes in it’s constructor an event handler factory that can return a collection of event handlers that can handle a certain event.  Note that it is possible for multiple handlers to handle the same event.

The next stage is simply to wire up all of these classes.  One interesting design decision that I have made is to define a static GameEvents class that has one method Raise.  The raise method calls dispatch on the event dispatcher to dispatch the event.  The event dispatcher is assigned to raise when the IoC container is built.  I have done this for a number of reasons.  Firstly it means that during testing I can swap out the event dispatcher for a action event dispatcher that simply calls a lambda expression that you can pass in.  Secondly it means that at any place in the game I can raise out a game event by calling the static Raise method.  It also means that I don’t have to inject the GameEvents class into every class.

As always there are many unit tests (that were written first) to test all of the code described above.  If you want to check out the latest code you can do so by pulling down the source from github and looking at the part 14 branch.  If you are unsure how to do that the follow the steps on this page.

 

XNA Game – Rotation – Discovering whether words have been made – Part 12

 

In this post I am going to go through the code that I have designed and written to detect if the player has made a word.  As stated in previous blog posts the player can make a word either vertically or horizontally.  The word has to have a minimum length.

The first thing that I needed to do was add a new property to the Square class CanUseInWord.  This is a bool that says whether that square can be used as a part of a word.  The reason for adding this is that I am currently thinking that I am going to have squares falling down from outside of the board, this will allow the player to see which squares will enter the board when they make a word.  I need a way to tell if the square can be used as a part of a word.  This will also allow me to put the game into a different mode that I have an idea about (more on that in later posts).  All of the squares that are selectable ie all of the ones that get filled with letters are eligible to be used in a word so currently I have set that property using the same logic.  I have obviously added a unit test for that in the board creation specs.

Next I need to design a collection to hold all of the possible words that the user can play.  This collection is hidden behind the interface IWordList which has one property Words which returns an IEnumerable<string>.  I have designed a factory to populate the word list, the default factory implementation populates the word list from a file.

Now that I can create a word list so I know all of the possible words a player can play, I need a way to check those words against every possible word in the board.  To do this I have designed an interface IWordChecker that has one method Check.  Check returns an IEnumerable<IWord> which is all of the words which have been found (if any) and it takes an IEnumerable<IEnumerable<Square>> (ie either all of the board’s columns or rows).  IWord is a simple interface that allows me to represent a collection of squares as a word.  It has two properties one which contains the string value that the list of squares represent and another which is the total value of those letters in points.

All of the above code is unit tested but I have left out the unit tests as they are straight forward.  If you wish to see them you can grab the code from github and check them out.  The interesting unit tests are the ones around checking for the existence of words in the board ie testing WordChecker.  I have designed 6 unit tests to do this:

1.  Check that if you have a set of squares that make a known word but all of the squares are squares in which the squares cant be used in a word then make sure that no words are returned.

2.  Check that a word is returned when a known word is in the list of squares that are passed in

3.  Check that two words are returned when two words are in the list of squares that are passed in (simulating two words being made in one row or column)

4.  Check that two words are returned when two words are in the list of squares and the words share letters e.g. HOUSEED should return HOUSE and SEED both words sharing the S and E

5.  Check that two words are returned when two words are in different lists in the lists of squares that are passed in (simulating that two words are made in two different rows or columns)

6.  Check that if there are no matching words in the lists that are passed in then no words are returned

To implement the code to check every possible word in the grid we first need to extract every possible word of a certain length.  We can do this with the following code

private IEnumerable<IWord> GetWordsOfLength(IEnumerable<Square> squares, int length)
{

    for (int i = 0; i + length <= squares.Count();  i++)
    {

        var currentWordSquares = squares.Skip(i).Take(length);

        if (currentWordSquares.All(s => s.CanUseInWord))
            yield return new Word(currentWordSquares);
    }
}

This private method works first by looping through all of the numbers from 0 to the total number of squares minus length of the words you are searching for.  Inside the loop the first thing we do is we skip to the starting square for the loop.  e.g. for the first iteration we will start at square 0.  The take statement then takes as many squares as we want this of course is the length of the word.  Next we check to make sure that all of those squares can be used in the word.  If all of those squares can be used in the word then we return that as a word from the grid.

public IEnumerable<IWord> Check(IEnumerable<IEnumerable<Square>> squares)
{
    var foundWords = new List<IWord>();

    foreach (var squareList in squares)
    {
        for (int j = GameConstants.MIN_WORD_LENGTH; j <= squareList.Count(); j++)
        {

            var words = GetWordsOfLength(squareList, j);

            foundWords.AddRange(words.Where(w => _wordList.Words.Contains(w.ToString())));

        }

    }

    return foundWords;
}

The method above completes the code for checking every word and passes all of the unit tests.  This code is pretty simple.  All we are doing is iterating around each list of squares ie basically looping around all of the rows or columns.  For each list of squares we loop around getting every word in that list of every length starting at the minimum word length and ending at the number of squares in the list (as obviously its impossible to have a word longer than that).  Once we have returned every possible word contained in that list all we have to do now is simply check to see if any of those words are in our word list and if so add them to the results.

That is all the code we need to implement word checking.  It’s good when a complex problem like this gets solved with a few simple lines of code.  It shows that we have broken our classes down and given them single responsibilities.  Because we have designed our unit tests upfront we have got confidence that our code works.  That is the beauty of TDD.

As always you can download the latest version of the code on Github.  Switch to the part12 branch to see the code at this point.  As always comments welcome.  Instructions on how to download the code from github or get in contact can be found on this page.