| XNA Game-Themed CS1 Examples ( XGC1 ) | |
|
Release 2.0 (XNA V3.1)
|
|
Goals:
1. Obtain the example 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.
Let's examine the
C# source code that produces the behavior we see on-screen
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 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 =
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; } |
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.
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;
- 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 ;- 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 ;- 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.
|
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" ); } |
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;
floatRec.Height = aHeight - bHeight;
// update the label, too:
floatRec.Label = "Float(A-B) H=" + floatRec.Height;
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;
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.
// update the labels, too:
aRec.Label = "A Height=" + aRec.Height;
bRec.Label = "B Height=" + bRec.Height;
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" );
FURTHER EXERCISES::
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).