| XNA Game-Themed CS1 Examples ( XGC1 ) | |
|
Release 2.0 (XNA V3.1)
|
|
References:
Goals:
1. Obtain the example code
When the game starts, you'll see a screen that
looks similar to this:
This program is functionally equivalent to 2000.700, so you should read the description for that program before you start in on this tutorial. You are strongly encouraged to review the material from that tutorial, so that you've comfortable with the concepts used in that tutorial, and the details of the code presented in that tutorial, before attempting to do this tutorial.
2. Examining The Program:
Let's examine the
C# source code that produces the behavior we see on-screen
|
public
class Game1 : XNACS1Base
{
private XNACS1Rectangle m_PresentRec; private XNACS1Rectangle m_FutureRec; private float m_PresentValue; // present value of the money private float m_Rate; // interest m_Rate private float m_Years; // number of years #region Constants use in the program// initial values for present, rate and years private const float INIT_RATE = 0.02f; private const float INIT_YEARS = 20.0f; private const float INIT_VALUE = 10.0f; private const float RATE_SCALE_FACTOR = 0.005f; private const float INIT_PRESENT_X = 5.0f; private const float INIT_REC_Y = 5.0f; private const float REC_WIDTH = 10.0f; // Width of the two rectangles #endregion
|
|
protected
override
void
InitializeWorld()
World.SetWorldCoordinate(
new Vector2(0,0),
100.0f);
m_PresentValue = INIT_VALUE;
m_Years = INIT_YEARS;
m_Rate = INIT_RATE;
float futureValue = ComputeFutureValue(); // initialize the rectangle representing present and future values m_PresentRec = InitializeRectangle(m_PresentValue, INIT_PRESENT_X); m_FutureRec = InitializeRectangle(futureValue, m_Years); } |
m_PresentValue = INIT_VALUE;
m_Years = INIT_YEARS;
m_Rate = INIT_RATE;
while this worked fine for that tutorial, we now know how to use
functions and this is a perfect opportunity to replace the (rather
complicated) formula with a simple call to a function, instead. Once
we've defined our ComputeFutureValue function (which we will examine in detail below), we can
instead use the current line of code:
float
futureValue = ComputeFutureValue();
You'll notice how much more clear this code is - instead of trying to sort through the details of a mathematical-formula-written-in-C#, you can immediately see that we're computing the future value of the money here.
m_PresentRec = InitializeRectangle(m_PresentValue, INIT_PRESENT_X);
m_FutureRec = InitializeRectangle(futureValue, m_Years);
|
///
<summary>
/// Computes future value based on instance variables: /// m_Year, m_Rate, and m_PresentValue /// Using the standard compound interest formula /// </summary> /// <returns></returns> private float ComputeFutureValue() { return m_PresentValue * ( float ) Math .Pow((1 + m_Rate), m_Years); } |
All we've done is to update the code so that we're using the new names:
m_P
resentValue
* (
float
)
Math
.Pow((1
+
m_R
ate),
m_Y
ears);
|
///
<summary>
/// Allocate and initialize a rectangle for /// representing present and future values /// </summary> /// <param name="height"> initial height of the rectangle </param> /// <param name="xPosition"> inital lower-left x position of the rectangle </param> /// <returns> A properly initialized rectangle </returns> private XNACS1Rectangle InitializeRectangle( float height, float xPosition) { XNACS1Rectangle rec= new XNACS1Rectangle (); rec.LowerLeft = new Vector2 (xPosition, INIT_REC_Y);rec.Height = height; rec.Width = REC_WIDTH;
return rec; } |
|
protected
override
void
UpdateWorld()
{ if (GamePad.ButtonBackClicked()) this.Exit(); // 1. Update year, rate, and present value based on thumbSticlk UpdateYearRateValue(); // 2. compute the new futureValue according to the formula float futureValue = ComputeFutureValue(); // 3. Update the rectangle representing the presentValue UpdateRectangle(m_PresentRec, m_PresentValue, "present value=" );// 4. Update the rectangle representing the futureValue UpdateRectangle(m_FutureRec, futureValue, "future value=" );// 5. Change futureValue's lower-left corner to show year m_FutureRec.LowerLeft = new Vector2 (m_Years, 5.0f);// 6. Last: update the user with what has happened EchoToTopStatus( "Years=" + m_Years + " m_Rate=" + m_Rate);EchoToBottomStatus( "LeftThumb-Y adjust Present Value; LeftThumb-X adjust m_Rate; RightThumb-Y adjust Years" );} |
UpdateYearRateValue();
float futureValue = ComputeFutureValue();
UpdateRectangle(m_PresentRec, m_PresentValue,
"present value=" );Whereas the second rectangle, that represents the future value of the money, needs an additional step in order to update it. Specifically, we'll need to move the second rectangle so that it's distance along the X axis shows how many years the future value is being calculated for:
// 4. Update the rectangle representing the futureValue
UpdateRectangle(m_FutureRec, futureValue,
"future value=" );// 5. Change futureValue's lower-left corner to show year
m_FutureRec.LowerLeft =
new Vector2 (m_Years, 5.0f);EchoToTopStatus(
"Years=" + m_Years + " m_Rate=" + m_Rate);EchoToBottomStatus(
"LeftThumb-Y adjust Present Value; LeftThumb-X adjust m_Rate; RightThumb-Y adjust Years" );|
///
<summary>
/// Updates m_Year, m_Rate, and m_PresentValue based on /// thumbSticks states. /// </summary> private void UpdateYearRateValue() { float leftThumbY = GamePad.ThumbSticks.Left.Y; float leftThumbX = GamePad.ThumbSticks.Left.X; float rightThumbY = GamePad.ThumbSticks.Right.Y;
// Get user's input, accumulate for: m_Years, m_Rate, and m_PresentValue m_Years = m_Years + rightThumbY; m_Rate = m_Rate + (RATE_SCALE_FACTOR * leftThumbX); m_PresentValue = m_PresentValue + leftThumbY; } |
float leftThumbY = GamePad.ThumbSticks.Left.Y;
float leftThumbX = GamePad.ThumbSticks.Left.X;
float rightThumbY = GamePad.ThumbSticks.Right.Y;
|
///
<summary>
/// change the height and label of "rec" /// </summary> /// <param name="rec"> The rectangle to be changed </param> /// <param name="height"> new height for the rectangle </param> /// <param name="label"> new label for the rectangle </param> private void UpdateRectangle( XNACS1Rectangle rec, float height, String label) { rec.Height = height; rec.Label = label + height; } |
rec will refer to the same rectangle that m_PresentRec does, and therefore will update the first rectangle (that displays the present value of the money). Similarly, when UpdateWorld executes this line:
UpdateRectangle(m_FutureRec, futureValue,
"future value=" );rec will refer to the same rectangle that m_FutureRec does, and therefore will update the second rectangle (that displays the future value of the money).
FURTHER EXERCISES:
Adding Parameters To A Function
For this exercise, you should use the same project that was explained in
the above tutorial.
Right now, ComputeFutureValue works, and works well. However, it
assumes that we're going to be storing the present value, rate and number of
years in instance variables. Change this function so that it takes (as
parameters) the present value, rate and number of years, and then does the
same calculation that it's currently doing. In order to make this
work, you'll need to adjust the parts of the program that call this
function, too.
Adding Parameters To A Function
For this exercise, you should use the same project that was explained in
the above tutorial.
Add two more rectangles to the program, so that you can show how much money
you'll have after
m_Year
years (this is currently being done, in the
above tutorial), then
m_Year
+10 years, and then
m_Year
+ 20
years, with three separate rectangles