Bizzy Bees Step 2: Drawing the scene (XNA Walkthrough)

This is part of a walkthrough series on creating a game (Bizzy Bees) in XNA

Overview
Step 1: Setting the stage (projects and assets)
Step 2: Drawing the scene
Step 3: Adding flowers
Step 4: Making things move
Step 5: Adding some bees to the mix
Step 6: User interaction
Step 7: Rounding it up

Getting something on the screen

In order to get anything on the screen in XNA you need to actually draw a texture from code every frame in the Draw method, as opposed to dragging and dropping something on a design surface.
For this you need two things

1. Something to draw  (the texture)

2. A position to draw it to (a position – Vector2)

In our case we are going to draw three things to the screen

  • The background, called GameScreenBackground, and we are going to draw this at position 0, 0 which means that we are starting at the top of the screen
  • The foreground, called GameScreenForeground, also at position 0,0
  • The score board (HUD) called HUDBackground, and this will be positioned 7 pixels in from the left and the top at 7,7

 

Loading the Textures

First, let’s create the textures and load them

1. Open game1.cs where all our game logic will be and add the following 3 member variables to the Game1 class, they will hold the texture objects so you can draw them later

         Texture2D backgroundTexture; Texture2D foregroundTexture; Texture2D hudTexture;

2. In the LoadContent method, load the textures from the content project using the content pipeline

             backgroundTexture = Content.Load<Texture2D>("GameScreenBackground");
            foregroundTexture = Content.Load<Texture2D>("GameScreenForeground");
            hudTexture = Content.Load<Texture2D>("HUDBackground");

Since we are doing this through the content pipeline we get some nice effects.  For example, if we happen to load the same texture again later, the content pipeline will know about this and not re-load it.

Drawing the Textures on the screen

Now it’s time to draw these on the screen and this is done in the draw function.  The Draw function starts by clearing the screen with a CornflowerBlue. This is so we wont get any remainders of the last draw shining through in case we draw transparent or semitransparent images.

In XNA we draw using something called a SpriteBatch.  I think of this as a new sketch pad… We start the drawing session by calling SpriteBatch.Begin, and end the drawing session by calling SpriteBatch.End. In between these calls we add methods to draw the textures to the surface. 

NOTE! The order here is important as these images will be layered on top of eachother.

Add the following code to the Draw method and create a DrawHUD method

  protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin();
            spriteBatch.Draw(backgroundTexture, Vector2.Zero, Color.White);
            //TODO: Draw flowers and bees here             spriteBatch.Draw(foregroundTexture, Vector2.Zero, Color.White);
            DrawHUD();
            spriteBatch.End();

            base.Draw(gameTime);
        }
  
  private void DrawHUD()
        {
            spriteBatch.Draw(hudTexture, new Vector2(7, 7), Color.White);
            //TODO: Print out game score and draw a flower on the HUD //TODO: Print out instructions //TODO: Print out goal message         }

There are several variations to Draw that let you scale, rotate or skew the image, but the easiest and most common one takes the texture you want to draw, the position where you want to draw it and a color. 

You can think of the color as a light that you are shining on the image.  If you shile a semitransparent yellow, the image will turn sligtly yellowish etc.  If you just want it to stay as is, just use Color.White.

That is all there is to it… hmm… or maybe not…  if you try to run the application now in the emulator or your phone, you will end up with a weird looking user interface, pretty far from what we want.

badback

This is because by default, XNA games run in landscape mode, but this is easily changed by chaning the PreferredBackBufferHeight and Width in the Game1 constructor

             graphics.PreferredBackBufferHeight = 800;
            graphics.PreferredBackBufferWidth = 480;

Adding instructions and score output – Drawing Text

Before we get ready for some flowers and bees, let’s deal with the instructions and scoring as well.

XNA doesn’t really have a way to print text in the traditional sense. What you do instead is to add a sprite font, or rather an image for each and every character in that font, and draw those images.
Does it sound like it will be a bit of a annoying chore?  Turns out it is actually pretty easy so don’t fret.

1. Right click on the contet project and select Add/New Item and choose Sprite Font, let’s call it LargeMenufFont.spritefont.  In order to choose the font that you want it to be, open it in the editor (it’s just an XML file) and change the FontName and Size to the font and size you want.  For this one we can choose Showcard Gothic and 21

2. Do the same thing two more times for MediumMenuFont and SmallMenuFont using Showcard Gothic 16 and 14

3. Add the following member variables to the Game1 class to hold the fonts and the score

  int score = 0;
        SpriteFont largeFont;
        SpriteFont mediumFont;
        SpriteFont smallFont;

4. Load the fonts, just like you did the textures in the LoadContent method

             largeFont = Content.Load<SpriteFont>("LargeMenuFont");
            mediumFont = Content.Load<SpriteFont>("MediumMenuFont");
            smallFont = Content.Load<SpriteFont>("SmallMenuFont");

5. In the DrawHUD method you can now use the fonts to draw the strings, very similarly to how you draw images.  Here we can make some good use of that color too, to color the different text strings.

             spriteBatch.Draw(hudTexture, new Vector2(7, 7), Color.White);
            //Print out game score and level
            spriteBatch.DrawString(mediumFont, "Marathon", new Vector2(40, 10), Color.Blue);
            spriteBatch.DrawString(largeFont, score.ToString(), new Vector2(127, 45), Color.Yellow);
            //TODO: Draw a flower on the HUD
            //Print out instructions
            spriteBatch.DrawString(smallFont, "Match flowers and bees", new Vector2(210, 10), Color.Yellow);
            spriteBatch.DrawString(smallFont, "Rainbow flowers match", new Vector2(206, 30), Color.Yellow);
            spriteBatch.DrawString(smallFont, "with all bees", new Vector2(260, 50), Color.Yellow);
            //Print out goal message
            spriteBatch.DrawString(largeFont, "Collect Rainbow Flowers", new Vector2(50, 115), Color.Blue);

TIP! If you want text with a shadow you can draw the same text twice, first in black slightly offsetted, and then in the color you want

backwithHUD

Yay! Now we have a good base for the game, next time we’ll add some flowers and bees