Lesson 5: Bust a Move
This lesson focuses on local variables and class-level variables. Class-level variables are also known as Fields. This lesson also shows how to update Fields in the Update method.
Source code for this lesson: http://www.bluerosegames.com/xna101/lessons/XnaLesson5.zip
For this lesson, start with the MyFirstGame project code from after Lesson 3. This means that if you want to use the code as it was after Lesson 4, delete the code which was added to show the second sprite. The Game1.Draw() method should look like this to start:
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.Black);
// TODO: Add your drawing code here
spriteBatch.Begin();
spriteBatch.Draw(spriteTexture, new Vector2(0f, 0f), Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
What if we want to draw the sprite somewhere else? Well we could change the Vector2(0f, 0f) to Vector2(100f, 100f) for example, and this may be fine for a sprite that isn't going to move, but for a moving sprite things need to be more dynamic. The 0f values in the above code are floating point constants (the "f" after the number indicated that it is a floating point number). Floating point numbers are numbers that contain a decimal point, and the approximate range of a floating point number in C# is -3.4E38 to 3.4E38 where E stands for "times 10 to the Nth power". We can replace the Vector2 constant with a Vector2 variable. A variable is a named piece of data of a particular data type. To use a variable, first we have to declare it. So before the spriteBatch.Draw() method call, let's declare a Vector2 variable. Add the following line before the spriteBatch.Draw() call:
Vector2 spriteLocation = new Vector2(0f, 0f);
This gives us a variable named spriteLocation with values of 0f for X, and 0f for Y. In this case we are initializing the spriteLocation variable in the same line of code in which we declare it. Variables can be initialized as part of the declaration, or can be initialized later. All variables must be initialized before they are used for the first time.
Now replace the Vector2 constant in the spriteBatch.Draw() call with the spriteLocation variable, as follows:
spriteBatch.Draw(spriteTexture, spriteLocation, Color.White);
Now if you run the program, you should get the same result as before, since spriteLocation has the same values that the Vector2 constant had.
Now change the line where spriteLocation was declared to the following:
Vector2 spriteLocation = new Vector2(100f, 0f);
and run the program again. You will see that the ball is now shifted over.
Since this variable are declared inside a method block, they are local to the method. This means that every time the Draw() method is called, this variable is re-declared and re-initialized, so there is no way for our code to remember the previous values and assign different values to the variable. To fix this, variables can be declared at the class level. Just like we did before in Lesson 3 with the spriteBatch and spriteTexture objects, we can declare spriteLocation at the class level and then it will be available to all methods in the Game1 object for the life of the object. The variable will be initialized once when the object is created and will keep that value until changed.
So move the spriteLocation declaration (make sure you remove it from the Draw method!) to immediately after the
line at the top of the class. So it should now look like this:
Texture2D spriteTexture;
Vector2 spriteLocation = new Vector2(0f, 0f);
And now add the following lines to the Game1.Update() method immediately after the
// TODO: Add your update logic here
comment:
spriteLocation.X = spriteLocation.X + 1f;
spriteLocation.Y = spriteLocation.Y + 1f;
Now every time the Update method is called, the X value in the spriteLocation object will be set to the value of the current level of X plus 1 and the same goes for Y. Now run the code again. The ball should move slowly diagonally and eventually off the screen.
Notice how the code to change the position of the sprite is in the Game1.Update() method and only the code directly related to drawing the sprite is in the Game1.Draw() method. This is how we will proceed going forward. Keeping the positioning and the drawing code separate will be important as things get more complicated.
Try playing around with the 2 lines that we added to the Update() method and instead of adding 1 each time, try some other values and see what happens.