XNA Game-Themed CS1 Examples (XGC1) Release 2.0 (XNA V3.1) 2/8/2010
Topic: Topic.3.ModulesAndFunctions
Example: Ex_4.LocalVars

# Functions and Local Variables

References:

• Pre-requisite: it is assumed that you have read through the prior tutorials, and are familiar with the concepts covered in those tutorials.

Goals:

• In this tutorial, we will:
• Examine how one can use a local variable within a method to help compute some result.

1. Obtain the example code

Download and unzip the zip file and you will see an ExampleProgram folder. Open the ExampleProgram folder, the EXE folder contains the compiled program and you can double click on the .sln file to work with the source code.

When the game starts, you'll see a screen that looks similar to this:

As you can see, there is a single soccer ball on the screen.  Using the right thumbstick, you can move the soccer ball around (if you want, you can even move it off the screen).  The program prints out a simple, purely textual message at the top of the screen, and it prints out the current location of the soccer ball at the bottom of the screen.  As you move the ball around on the screen, you'll notice that the size of the ball changes in proportion to the height of the ball - as you move the ball upwards, it gets bigger, and as you move it downwards, it gets smaller.

2. Making Radius Proportional To Height

Since the source code to this program is nearly identical to the program uses in the previous tutorial, we will only examine the code that's new, or different.

In this tutorial, the size of the soccer ball is dependent on the height of the ball - as the Y value of the soccer ball's center point gets bigger, so does the radius of the circle object that represents the ball.  Because we're no longer looking to randomize the radius, we want the soccer ball's radius to start off at a standard, set size:

• InitializeSoccer():  private void InitializeSoccer() {     // initialize the soccer ball     m_TheSoccer = new XNACS1Circle();     m_TheSoccer.Center = new Vector2(BALL_INIT_X, BALL_INIT_Y);     m_TheSoccer.Radius = BALL_INIT_RADIUS;     m_TheSoccer.Texture = "SoccerBall"; }
• Since the soccer ball's circle object is created and initialized in the InitializeSoccer function, we only need to modify that one function, in order to change how the soccer ball is initialized.
• Since we don't want the soccer ball to start with a random radius, we simply remove the call to the RandomFloat() function, leaving us with:
• PrintMessageToTopStatus(): private void PrintMessageToTopStatus() {     EchoToTopStatus("Change the ball y-location to see it change size!"); }
• The first, minor change that we'll examine is the new message that we're printing at the top of the screen.
• UpdateWorld():
 protected override void UpdateWorld(){     if (GamePad.ButtonBackClicked())         this.Exit();     // Change Ball position with Right Thumb Stick     aBall.CenterX += GamePad.ThumbSticks.Right.X;     aBall.CenterY += GamePad.ThumbSticks.Right.Y;     // Compute the soccer's size based on its y-position     ComputeSoccerSize();     // here is the function that prints!     PrintMessageToTopStatus();     EchoToBottomStatus("Soccer Ball position: " + aBall.Center + " Random Integer=" + GetANumber()); }
• Pretty much all the code in UpdateWorld should be familiar, with the exception of the call to the new function ComputeSoccerSize.  This function we have defined ourselves, below, in the 'utility functions' region of the program
• ComputeSoccerSize():
 /// /// Compute and change the radius of the soccer ball based on /// it's current y-position /// private void ComputeSoccerSize() {     // This a variable "Local" only to this function!     float yPos = m_TheSoccer.CenterY;     // One can also define constants local only to a function     const float RADIUS_SCALE_FACTOR = 0.02f;     m_TheSoccer.Radius = BALL_INIT_RADIUS + (RADIUS_SCALE_FACTOR * yPos); }
• We have decided to calculate the radius of the soccer ball here, in this separate function.  While this is probably simple enough that we could have done this all in the UpdateWorld function, not only does this separate method nicely demonstrate how to use functions, but it would also allow us to put more complicated logic here and not need to worry about changing anything else in the program.
• The first line of executable code in the function declares and initializes the yPos variable:
float yPos = m_TheSoccer.CenterY;
• The first part of this line ( "float yPos" ) declares a new float variable, named yPos.
• The second part of this line ( "m_TheSoccer.CenterY" ) obtains the current Y value of the center of the soccer ball.  You'll notice that we can access the instance variable m_TheSoccer just fine from within this method (function).  Because of that, we can then further access the CenterY property of m_TheSoccer just like normal, too.  We will take that value, and assign it to the new variable that we're declaring here.
• The = is the part of the code that actually assigns the Y value of the circle's center to the yPos variable.
• yPos is a local variable, meaning that we cannot access it outside of this function.
• Notice that we do not need to declare it as being private, or public, etc.
• If we want to, we can also declare local named constants, too:

• Again, you'll notice that we don't put the private/public keyword in front of local named constants (nor for local variables).
• Other than that, it looks exactly like the other named constants we've declared - is has the keyword const, followed by a data type ( float, in this case), followed by a named (RADIUS_SCALE_FACTOR, which follows the naming convention for constants), followed by the starting value = 0.02f;.
• You can only use this constant within this function, and not anywhere else.
• Finally, we calculate the new radius for the circle, based on the height (the Y value of the center point of the circle)
• Notice that we assign the end result to the property of an instance variable (we assign the value to m_TheSoccer.Radius), which once again demonstrates that we can access instance variables from within a method.

FURTHER EXERCISES::

1. Start from a blank starter project (1000.201, if you need it), and re-do the code from memory as much as possible.  On your first try, do what you can, and keep the above code open so that when you get stuck, you can quickly look up what you forgot (and that after you finish a line, so that you can compare your line to the 'correct' line).  On the next try, do the same thing, but try to use the finished code less.  Repeat this until you can type everything, without refering the tutorial's code.
• Repeat this exercise daily for several days, so that you really get the hang of this.  As you go on, periodically review this by re-doing this exercise.
2. Local Variables
For this exercise, you should use the same project that was explained in the above tutorial.
You'll notice that we declare yPos in the ComputeSoccerSize() method as a local variable, meaning that we're not allowed to use that variable anywhere else.  Try doing each of the following, and for each one, see what happens.  Does the program compile? Does it run?  Does it run correctly?
1. Try printing out the value of yPos in the PrintMessageToTopStatus method
2. Try printing out the value of yPos in the UpdateWorld function
3. Try printing out the value of yPos in the GetANumber function
4. Why do you get the results that you're seeing?
3. Instance and Local Variables; Math Formula Review
For this exercise, you should use the same project that was explained in the above tutorial.
Instead of making the radius of the soccer ball depend exclusively on the height, change the code so that it also depends on the distance from the left edge, too.  A formula like