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.
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
Yay! Now we have a good base for the game, next time we’ll add some flowers and bees