XNA Game-Themed CS1 Examples ( XGC1 ) Release 2.0 (XNA V3.1) 2/8/2010
Topic: Topic.2.Input_Output_PrimitiveDataTypes
Example: Ex_10.IntFloatSubtraction

# Math Operators: Subtraction (Integer and Floating-Point)

References:
• Pre-requisite: it is assumed that you have read through the prior tutorials, and are familiar with the concepts covered in those tutorials.
• It may be useful to refer to refer to the diagram illustrating the Draw-Update loop (which explains that your initialization code will be called once, and then the XNACS1Lib will repeatedly call your Update method (after which it will Draw the screen) ), in order to have a clear picture of how your game executes.

Goals:

• In this tutorial, we will:
• Examine the mathematical subtraction operator
• Visually examine the difference between integer and floating point subtraction
• Examine how to convert from a floating-point number to an integer, using "type-casting" (sometimes also just called "casting")
• Examine how to update and change on-screen shapes in response to the player's input

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.

Once we compile and run this project, the program displays four rectangles on the screen, labeled with each rectangle's current height.

At the bottom of the screen there are instructions for playing game.  By using the left thumbstick, you can control the current height of the left-most rectangle (rectangle "A").  By using the right thumbstick, you can control the current height of rectangle "B".  The height of the "Int" rectangle is automatically set to be the difference (subtraction) of the heights of the other two rectangles, when the those rectangles' heights are rounded down to whole numbers .  The height of the final, right-most rectangle, the "Float" rectangle, is the difference (subtraction) of the heights of rectangles A and B This subtraction is done as accurately as possible , as pictured below.  At the top of the screen, the heights of the A and B rectangles are displayed, both as the exact, floating-point height, as a rounded-down, integer height.

Additionally, when player presses the 'Back' button (or the keyboard equivalent), the program will exit.

2. Examining The Program:

Let's examine the C# source code that produces the behavior we see on-screen

• Declaring the instance variables

We need to declare our instance variables before we can use them.

 public class Game1 : XNACS1Base {         private XNACS1Rectangle aRec;     private XNACS1Rectangle bRec;     private XNACS1Rectangle intRec;     private XNACS1Rectangle floatRec;
• We'll need to keep track of each of the rectangles that we see on-screen, so we declare each of them here.
• Because what we're doing is sufficiently simple, we can use local variables for everything else that we want to calculate.  As a result, we don't need to declare anything else here.
• InitializeWorld():

We told C# to create instance variables for our Game1 in the code that's described above.  It's important that we give our variables well-defined values before we use them, like so:

 protected override void   InitializeWorld() {     World. SetWorldCoordinate( new Vector2 (0,0), 100.0f);     aRec = new XNACS1Rectangle ();     aRec.LowerLeft = new Vector2 (10.0f, 20.0f);     aRec.Height = 15.2f;     aRec.Width = 20.0f;     bRec = new XNACS1Rectangle ();     bRec.LowerLeft = new Vector2 (30.0f, 20.0f);     bRec.Height = 8.5f;     bRec.Width = 20.0f;     floatRec = new XNACS1Rectangle ();     floatRec.LowerLeft = new Vector2 (70.0f, 20.0f);     floatRec.Height = aRec.Height - bRec.Height;     // floatRec.Height = 6.7f;     floatRec.Width = 20.0f;     intRec = new XNACS1Rectangle ();     intRec.LowerLeft = new Vector2 (50.0f, 20.0f);     intRec.Width = 20.0f;     int aHeightInInt;     aHeightInInt = ( int )aRec.Height;     int bHeightInInt = ( int )bRec.Height;     intRec.Height = aHeightInInt - bHeightInInt; }
• Again, we have the exact same sequence of steps that we used in previous tutorials, repeated here, in order to set up the first two rectangles.
• Simply repeating the code we've previously used works well here, since we can pretty much pick any starting height for the rectangles that we want.  As long as all three rectangles fit on-screen, it will be easy for the player to figure out what's going on.
• Note that we need to be very careful, especially when cutting and pasting , to make sure that we're using the variable names that are correct for this program !
• Looking at the third rectangle ('floatRec' - the one whose height we get by subtracting the height of rectangle B from the height of rectangle A), you'll notice that the floatRec object is created in the normal way, and the location and width are set the same way, but that the Height is actually set up to be the difference of the other two:

floatRec.Height = aRec.Height - bRec.Height;

If we look at this part by part, we see that it breaks down into a series of simple steps, based on the order of operations for the various operators.

1. There are two operators: the subtraction operator (as indicated by the - symbol), and the assignment operator (as indicated by the = symbol).  The assignment operator is executed last, so subtraction therefore goes first.  Assignment operators normally go last, so that all the other math can happen, and then the results of that math can be assigned to a variable.
2. In order to do the addition, C# needs to know what the values of aRec.Height and bRec.Height are.  Let's assume that C# will work from left to right.
3. floatRec.Height = aRec.Height - bRec.Height;
C# will retrieve the value of the aRec's height, which is 15.2f.  So, mentally, we can think about the line being transformed into:
floatRec.Height = 15.2f - bRec.Height;
4. floatRec.Height = 15.2f - bRec.Height ;
C# will retrieve the value of the bRec's height, which is 8.5f.  So, mentally, we can think about the line being transformed into:
floatRec.Height = 15.f - 8.5f ;
5. floatRec.Height = 15.2f - 8.5f;
Having retrieved the two values, C# can now do the subtraction operation, which will yield the value 6.7f.
floatRec.Height =
6.7f ;
6. floatRec.Height = 6.7f;
Once the subtraction operator has finished, all that's left is to do the assignment operation, which will put the floating-point number 6.7 into the Height property of the floatRec rectangle.
• We could have also done this with the code that's been commented out ( floatRec.Height = 6.7f; ).  The advantage of this second, commented-out approach is that we don't have to know how to do subtraction in C# to do it.  The major disadvantage is that if we were to change the starting height for aRec or bRec, then we would have to remember to change this line, too.  While this isn't too tough in this small program, we want to build up skills, techniques, and a mind-set that will help us avoid making errors in the future, so we prefer to use the first approach, wherein C# automatically calculates the correct height for us.
• Note that this rectangle is actually drawn on the screen as the right-most rectangle, even though we're initializing it third.
• Looking at the fourth rectangle ('intRec' - the one whose height we get by subtracting the height of rectangle B from the height of rectangle A, using rounded-down integer numbers, rather than exact float numbers ), you'll notice that the intRec object is created in the normal way, and the location and width are set the same way, but that the Height is actually set up to be the difference of the other two, after we've converted the other heights to be integers .  If we look at this part by part, we see that it breaks down into a series of simple steps:
• The first thing that the program does is declare an int eger to hold the (rounded-down) value of rectangle A's height:

int aHeightInInt;

After that, the program then assigns the aRec's Height to this integer variable.  However, aRec.Height is actually a floating point number (i.e., it can keep track of digits to the right of the decimal point) but the int eger variable that we just created can only hold whole numbers.  In order to convert from a float to a int , C# will have to drop all the digits after the decimal point.  However, dropping the digits to the right of the decimal point will cause the program to "lose" information during the conversion process.  If this is what the programmer is intending to do then it's ok, but C# wants to make sure that the programmer understands that this conversion will (probably) result in the loss of some information.  We tell C# that we understand this, and that we're ok with this, by putting the ( int ) before the float , like so:

aHeightInInt = ( int )aRec.Height;

Let's step through this, in order to see what it's doing:

1. aHeightInInt = (int ) aRec.Height ;
C# will retrieve the value of the aRec's height, which is 15.2f.  So, mentally, we can think about the line being transformed into:
aHeightInInt = (int ) 15.2f ;
2. aHeightInInt = ( int ) 15.2f;
Once C# has the value of aRec.Height, it can now convert it into an integer, which is what the ( int ) does. When we use this technique to convert numbers, C# does this conversion by rounding down: effectively, it truncates the number so that it has no digits after the decimal place.  Mentally, we think of the line being transformed into:
aHeightInInt = 15 ;
3. aHeightInInt = 15;
At this point, all that remains is to assign 15 (which is an integer value) into aHeightInInt, which is an int .
• We could have also done directly ( aHeightInInt = 15; ), but just like other places where we could hard-code a number directly into our program , we see that it's advantageous to instead have C# figure out what the value should be, instead.
• Converting data from one type to another in the way we just saw is called type-casting, or casting, or type-coercion .  There are other ways to convert data from one form to another, but we won't examine them here.
• The next line does the same thing, in the exact same way, in order to convert the height of rectangle B into an integer.  The only thing that's different is that we're composing this single line from what we did on two, separate lines above:
int bHeightInInt = ( int )bRec.Height;
• The final line subtracts the integer value of rectangle B's height fro the integer value of rectangle A's height, and then assigns that difference to be the Height of rectangle intRec:
intRec.Height = aHeightInInt - bHeightInInt;
• One very subtle point out this: after doing the subtraction (15 - 8 = 7), the program then assigns 8 (which is an integer) to intRec.Height, which is a float.  This is ok, and does NOT require a ( float ) , to convert the integer to a floating point number, since a float is more precise than an int , and therefore C# can safely convert from an int to a float without to worry about losing any digits.
• You should be able to step through this line of code, in the exact same way that we've stepped through the other lines of code, so that you can explain (step by step) exactly how this line of code executes.
• Note that this rectangle is actually drawn on the screen as the rectangle that is third from the left, even though we're initializing it fourth.
• You should go through each of the above lines, and make sure that you're clear on what each and every line does.
• UpdateWorld():  protected override void UpdateWorld() {     if (GamePad.ButtonBackClicked())         this .Exit();     float aHeight = aRec.Height;     float bHeight = bRec.Height;     float leftThumbY = GamePad.ThumbSticks.Left.Y;     float rightThumbY = GamePad.ThumbSticks.Right.Y;         // obtain the integer values for A and B heights     int aHeightInInt = ( int )aHeight;     int bHeightInInt = ( int )bHeight;     // Accumulate height for A and B     aHeight = aHeight + leftThumbY;     bHeight = bHeight + rightThumbY;     // float substraciton for floatRec     floatRec.Height = aHeight - bHeight;     // update the label, too:     floatRec.Label = "Float(A-B) H=" + floatRec.Height;         // int subtraction for intRec     intRec.Height = aHeightInInt - bHeightInInt;     // update the label, too:     intRec.Label = "Int(A-B) H=" + intRec.Height;     // assign A and B's height to aRec and bRec     aRec.Height = aHeight;     bRec.Height = bHeight;     // update the labels, too:     aRec.Label = "A Height=" + aRec.Height;     bRec.Label = "B Height=" + bRec.Height;     // After this method ends, the rectangles will continue to exist,     // but the local variables leftThumbY, rightThumbY, aHeight, bHeight,     // aHeightInInt and bHeightInInt will cease to exist.     EchoToTopStatus( "A-Height(float=" + aRec.Height +         " int=" + ( int )aRec.Height + ") " +         "B-Height(float=" + bRec.Height+         " int=" + ( int )bRec.Height + ")" );     EchoToBottomStatus( "LeftThumb-Y adjust A-Height; RightThumb-Y adjust B-Height" ); }
• As per normal, our game will check if the user presses the 'Back' button.  If we're going to exit, there's no sense in doing any work prior to exiting, so we check if we need to exit as the first two lines in the method
• Since most textbooks present arithmetic ("math") operators using local variables, we'll be using local variables here, too.  The hope is that your textbook will provide a solid background explanation, and this tutorial will explain the video-game specific stuff, and that what's left will be just a couple lines of code that are both explained in your textbook and shown here.
• In order to make our program look more like what you're seeing in your textbook, we will use the basic strategy of copying all the numbers that we need into local variables, then doing the math (like you're seeing in your textbook), then copy the numbers out of the local variables and back into the rectangle(s), in order to update the rectangles.
• We start by creating copies (in local variables) of the numbers that we'll need.  We basically need to know two things: the current height of rectangles A and B, and how much the thumbsticks are being pushed.  From that, we can figure out what the new heights of the other two rectangles should be.
• Let's start by creating local variables that will hold copies of the numbers in the thumbsticks and the rectangles' heights::

float aHeight = aRec.Height;

float bHeight = bRec.Height;

// obtain the integer values for A and B heights

int aHeightInInt = ( int )aHeight;

int bHeightInInt = ( int )bHeight;

• Since the first two pairs of lines are pretty much identical to what was done in the previous tutorial, you should understand all this.  Notice that we're keeping the first four variables in floating-point number form.
• The last two lines obtain the floating-point value of the height of the respective rectangles, convert those values to integers (by dropping all digits after the decimal point), and then assigning that integer value to the variable, as was described above.
• You'll notice that we're duplicating the names of the local variables: the names of the aHeightInInt and bHeightInInt variables names are exactly identical to the names of the aHeightInInt and bHeightInInt variables in the InitializeWorld method.  This is ok, because all the variables are local variables: even though they have the same names, these variables are completely separate from the variables that were declared in the other method.
• Once we've got our local copies of the data, we can now calculate the new heights of the A and B rectangles:

// Accumulate height for A and B

aHeight = aHeight + leftThumbY;

bHeight = bHeight + rightThumbY;

• Next, we will calculate the new height of the the 'floating point number' rectangle, using the subtraction & assignment operators.  Since you've seen most of this before, we will assign the result directly to the rectangle's Height property, thus updating the rectangle.  While we're at it, we will also update the label on the rectangle so that the rectangle is accurately labeled with the new height (and with the word Float to remind us that this rectangle's height was calculated as accurately as possible, using floating-point numbers:)

// float substraciton for floatRec

floatRec.Height = aHeight - bHeight;

// update the label, too:

floatRec.Label = "Float(A-B) H=" + floatRec.Height;

• Next, we will do the same thing for the intRec, except that this time we will use the rounded-off INTEGER values, not the exact, floating point values.  Also, we will update the label with the new (integer) height (and with the word Int to remind us that this rectangle's height was calculated using integer numbers)
// int subtraction for intRec

intRec.Height = aHeightInInt - bHeightInInt;

// update the label, too:

intRec.Label = "Int(A-B) H=" + intRec.Height;

• At this point, we've done all the calculations that we wanted to do. However, all the calculations ended up putting their results into local variables.  So before the method ends, we need to copy all these values back into the rectangles that we see on the screen.

// assign A and B's height to aRec and bRec

aRec.Height = aHeight;

bRec.Height = bHeight;

These should all be fairly straightforward - we simply take the local variable that is storing the new height of a rectangle, and then assign that value to the Height property of the appropriate rectangle.

• Lastly, we need to update the labels on the A and B rectangles, so that they accurately reflect the new height of the rectangles.

// update the labels, too:

aRec.Label = "A Height=" + aRec.Height;

bRec.Label = "B Height=" + bRec.Height;

• In order to try and be helpful, we also echo a brief message to the bottom status bar, telling the user how to play the game.  We also echo the current heights of the A and B rectangles to the top of the screen, specifying both the current, exact, floating-point heights, as well as the rounded-down integer heights.

EchoToTopStatus( "A-Height(float=" + aRec.Height +

" int=" + ( int )aRec.Height + ") " +

"B-Height(float=" + bRec.Height+

" int=" + ( int )bRec.Height + ")" );

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. Exploring Errors: Type casting
Using the same project that the above tutorial makes use of, try assigning a floating point number to an integer variable, but without using the typecasting .  For example:
int bHeightInInt = bHeight;

What error do you get?  Make sure to take careful note of this error, in case you accidentally make this mistake in the future, and you need to figure out what the error is, based on the error message(s).

3. Understanding The Code
Using the program that the above tutorial discusses, you can make the height of A (or B) negative.  When you do this, what happens?  Why?