Rolling dice in XNA – complete code and sample

I saw a post on the Microsoft XNA forums asking for hints on how to get a die rolling on the screen, so I’ve put together a little sample here, for your enjoyment Smile

This small “game” does nothing but roll six dice when you press SPACE, and sums them up for you. 
  Complete code here.

Short presentation of the program

As you can see above, there are six dice, instantiated to different positions in a diagonal line. The program listens for the SPACE bar being pushed. If all dice are stationary at that moment, then all the dice have their Roll() method invoked, which changes their state to Rolling and sets the MsLeftInRoll to 1000 (meaning a roll takes 1 second), and their Update method nudges their CurrentPosition property downward slowly for the full second. When all dice have stopped rolling, their ToString() implementation is used to display the result of the roll onscreen.

The Die class

The Die is a subclass of DrawableGameComponent, which makes Updating and Drawing easier. Just create a new Die object and add it to Game.Components. This will make sure that the Game objects’s Update and Draw calls Update and Draw on each die added.

for (int i = 0; i < 6; i++)
{
    //creates a new die, a bit further to the left and below the previous
    Die die = new Die(this, new Vector2(100 + 120 * i, 100 + 25 * i));

    //adds it to the Game's components, to make sure it gets updated and drawn
    Components.Add(die);
}

Here is the class diagram of the Die:

die_classdiagram

Creating a die

When the Die is created it is passed a reference to the Game object, and its OriginalPosition (where it begins every new roll).

Drawing the die

The die draws itself by finding the source-rectangle to draw from this PNG ( 100 x 600 pixels ) based on the current value of the die.

dice

Here's the math to find the current rectangle.

Rectangle sourceRect =
    new Rectangle(_dieFaceSize * (this.Value - 1) ,0, _dieFaceSize, _dieFaceSize);

_dieFaceSize is 100 pixels in this case, but is set dynamically based on the height of the Texture2D used.

When drawing the die's face, it is moved up and left by half of a _dieFaceSize (50 pixels in this case) so the texture is centered on the CurrentPosition of the Die. A shadow is created by first drawing the face with a semiopaque, black version of the face.

Rolling the die

Rolling the die is pretty straightforward:

//starts the die rolling
public void Roll()
{
    //if the die isn't already rolling
    if (this.State != DieState.Rolling)
    {
        //move it back to its starting position
        this.ReturnToOriginalPosition();

        //start it rolling
        this.State = DieState.Rolling;

        //reset the time to roll
        MsLeftInRoll = _msForRoll;
    }
}

Updating the die

For every Update, the time left in the MsLeftInRoll has the gameTime.ElapsedGameTime.TotalMiliseconds subtracted from it, and if it is below zero, the State of the Die changes to Stationary.

public override void Update(GameTime gameTime)
{
    base.Update(gameTime);

    //if the die is rolling
    if (this.State == DieState.Rolling)
    {
        //subtract the time since last Update from the rolltime
        MsLeftInRoll -= gameTime.ElapsedGameTime.TotalMilliseconds;

        //if time is up
        if (MsLeftInRoll <= 0)
        {
            //set the state to stationary
            this.State = DieState.Stationary;
        }
        else
        {
            //give the die a new value from 1 to 6
            this.Value = _rnd.Next(6) + 1;
            //move the offset a bit down along the Y axis
            this.CurrentPosition += Vector2.UnitY * 2;
        }
    }
} 

Hope this helps somebody when implementing their own diceroller Smile

Leave a Reply