41
CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Embed Size (px)

Citation preview

Page 1: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

CHAPTER 10Using C# Methods to Solve Problem

XNA Game Studio 4.0

Page 2: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Objectives• Use image manipulation to write a game you might like to

play.

• Discover how to create and use your first C# methods.

• Take a look at test-driven development.

• Make some mistakes and discover how to fix them.

Page 3: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

PLAYING WITH IMAGES

Page 4: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Zooming In on an Image• You change the way that the picture is drawn by changing

the values in jakeRect as the program runs.

• XNA can resize the picture for you so that you can move and scale your picture very easily.

• You start by adding the following Update method to the display program

protected override void Update(GameTime gameTime){// Allows the game to exitif (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)this.Exit();jakeRect.Height++;jakeRect.Width++;base.Update(gameTime);}

Page 5: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Zooming In on an Image• You get a hold of a field in an object by giving the identifier

of the variable a period character ( . ) and then the name of the field you wish to use.

• This is true with a struct.

• Example jakeRect.Height++;

Page 6: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Creating a Zoom-Out• Updating the Drawing Rectangle

• Change the way that you set up the Rectangle, which Describes the part of the image that you’ll draw

protected override void Initialize(){gameSpriteBatch = new SpriteBatch(graphics.GraphicsDevice);jakeRect = new Rectangle(0, 0, 6000, 4500);base.Initialize();}

• This creates a rectangle that’s 6,000 pixels wide and 4,500 pixels high, or 10 times the original image size and much bigger than the screen

Page 7: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0
Page 8: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Creating a Zoom-Out• More of the picture is visible, but it seems to have been stretched for

some reason.

• To understand what’s happening, you need to think first about what you set out to do.

1. You wanted to display only part of the image on the screen. This allows you to show only part of the image so that the player has to guess what the picture is.

2. To achieve this, you made the draw rectangle enormous by multiplying its width and height by 10 so that only part of the drawn image was visible on the screen.

3. You then created an Update method that reduces the width and height of this rectangle by one each time it is called so that the amount of image in the screen increases progressively.

4. You’ve noticed that as this program “zooms out” of the image, it no longer looks right.

Page 9: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

What happened.• You’re reducing the height and width by the same amount

each time. Because the picture is not as high (4,500) as it is wide (6,000), the height is “used up” more quickly, leading to a scrunched picture.

• Fix the problem by reducing each value by a percentage each time rather than bya particular value.

Page 10: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

The Great Programmer Speaks

Page 11: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

CREATING A METHOD TO CALCULATE PERCENTAGES

Page 12: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Putting a Method into Your Game Class

• A method is a block of code that does something for you.

• Each method has an identifier that you use to refer to the method when you call it.

• The details of what information is passed into the method (the telephone call) and the result it delivers (what’s written on the piece of paper) are written in C# as the method header.

• The details of what the method does is called the method body.

Page 13: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Putting a Method into Your Game Class

• The method header gives the identifier for the method, what type of result it returns, and the number and type of any parameters.

• A parameter is used to feed information into a method.

Page 14: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Putting a Method into Your Game Class

• Once the compiler has the header of a method, it knows what the method “looks like” in that it can create the code to use the method.

• This description of a method is often called the signature of the method.

• When you create a method, you decide the type and number of the parameters that the method needs to do its job.

• Some methods have many parameters; others have none.

Page 15: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Putting a Method into Your Game Class

• The method header is followed by the method body, a block of statements that perform the task for which the method was created.

• The body can be a very large number of statements or only one or two.

• If the method delivers a result then the body must contain a statement that returns a value of the type specified in the method header.

• Once the compiler has the body of the method, it knows what statements need to be performed when the method is called.

Page 16: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Calling a Method

height = height - getPercentage(1, height);

• This line of code would use getPercentage to reduce the value of the variable called height by 1 percent.

Page 17: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

What Happens in a Method Call1. It makes a note of where it is in the program so that it can

come back to the right place when the method finishes.

2. It gets the values of any parameters and sets them up for the method to use.

3. It jumps into the method body and performs the statements in the method body.

4. At the end of the method body, or when it reaches a return statement, it goes back and delivers whatever value was expected.

5. Then the program continues running at the statement following the method call.

Page 18: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Returning Nothing Using void• Methods that don’t return a result are given the return

type void.

• This tells the compiler that the method does not deliver any information to the caller

• protected override void Draw(GameTime gameTime)

• If you want a method to return before the end of the method block, you can use the return key word to cause a return at that point.

• If the method returns a value, the return key word must be followed by an expression that delivers a value of the required type.

Page 19: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Testing a Method• The Great Programmer tells you that it’s quite sensible to create “broken”

methods like this; you can use them to decide what the method looks like and then go back and fill in the statements later.

• This is a version of a professional development technique called test-driven development.

• You can also use them to write tests, as follows:

protected override void Draw(GameTime gameTime)

{

if ( getPercentage(10, 800) == 80 )

{

graphics.GraphicsDevice.Clear(Color.Green);

}

else

{

graphics.GraphicsDevice.Clear(Color.Red);

}

base.Draw(gameTime);

}

Page 20: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Designing Tests for getPercentage• A test can prove only that a particular fault is not present.

It can’t prove that there are no faults in the code at all.

• If programmers claim that their code is “fully tested,” usually what they really mean is that they can’t think of a reason it shouldn’t work, and this is not quite the same thing.

• Next is C# code that gives your method a reasonable workout. It is not a particularly comprehensive test, but it will do for now

Page 21: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Designing Tests for getPercentageprotected override void Draw(GameTime gameTime)

{

if ( (getPercentage(0, 0) == 0) && // 0 percent of 0

(getPercentage(0, 100) == 0) && // 0 percent of 100

(getPercentage(50, 100) == 50) && // 50 percent of 100

(getPercentage(100, 50) == 50) && // 100 percent of 50

(getPercentage(10, 100) == 10) ) // 10 percent of 100

{

graphics.GraphicsDevice.Clear(Color.Green);

}

else

{

graphics.GraphicsDevice.Clear(Color.Red);

}

base.Draw(gameTime);

}

Page 22: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Creating the getPercentage Method Body

• Algorithm

1. Calculate the fraction of the amount that you want (this is the percentage divided by 100; in other words, 50 percent would give you 50/100, which is a half).

2. Multiply the incoming amount by this fraction to create the result.

• Code

int getPercentage(int percentage, int inputValue){ int fraction = percentage / 100; int result = fraction * inputValue; return result;}

Page 23: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

DEBUGGING C# PROGRAMS

Page 24: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Debugging with Breakpoints• A breakpoint is a way of marking a particular statement in

your program and saying to XNA Game Studio “When the program reaches this statement, pause it and let me take a look at stuff.”

• How to set a breakpoint• Click on the left margin• XNA Game Studio highlights the line in brown, and a brown dot

appears against the line.

Page 25: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Debugging with Breakpoints

Page 26: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Hitting a Breakpoint• If you now run the program, you see that when it gets to

the line that you’ve marked as a breakpoint, it stops.

Page 27: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Viewing Variables• Rest the mouse pointer over the identifier of the variable

in the code that you’re interested in.

• A box pops up and tells you the value in that variable.

• To run the program a bit further, click the green arrow in the program controls in the top left corner.

Page 28: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Using Floating-Point Numbers in C#• You can use the float type, which can hold floating-point

numbers.

• These are so called because they have a decimal point that can “float” up and down the number, depending on the value being held.

• Change the type of the fraction variable to float in your method

int getPercentage(int percentage, int inputValue){ float fraction = percentage / 100; int result = fraction * inputValue; return result;}

Page 29: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

The Compiler and C# Types• You now get an error message because your program no

longer compiles.

• If you look at your code, notice the wavy blue lines.

• The compiler is saying “Cannot implicitly convert type 'float' to 'int'. An explicit conversion exists (are you missing a cast?).”

Page 30: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

The Compiler and C# Types• If you try to put a floating-point value (with a fractional

part, say, the value 2.9) into a variable of type int (which doesn’t have support for the floating bit), you are in danger of losing information.

• The line of code that you’re looking at does just that.

int result = fraction * inputValue;

• When you move that into the result, you’re moving a floating-point value into an integer, which results in data loss. In programming terms, this is called narrowing.

• You’re moving values from a data type with a wide range of values (floating point) into a type with a narrower range of values (integer).

Page 31: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Compilers and Casting• When the compiler sees a statement that narrows a

value, it produces the error message, “Cannot implicitly convert type 'float' to 'int'.”

• The compiler won’t produce output steps that perform the conversion unless you explicitly ask it to.

• The next part of the message gives you some more help. “An explicit conversion exists (are you missing a cast?).”

• This means that the compiler can perform such a conversion, but you need to use a cast to request that the action be performed.

Page 32: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Compilers and Casting• A cast is where you ask the compiler to produce code that

converts a value from one type to another.

• A cast is the name of the type you want (in parentheses).

• int result = (int)(fraction * inputValue);

• Note that not all casts work.

• You can’t convert from a Color to an int by using a cast because the compiler hasn’t been told how to generate code to do this.

Page 33: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Expression Types• There are two kinds of division: those that produce an

integer result and those that produce a floating-point result.

• If the compiler sees an expression that divides an integer by another integer, it performs the integer division even if the result is being put into a floating-point variable.

• If you need to force the compiler to perform floating-point division, and the way you do that is to turn one of the things in the calculation into a floating-point value.

• You can do this by casting again:

float fraction = (float) percentage / 100;

Page 34: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

The Great Programmer Speaks

Page 35: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Stopping the Zoom

• You need to find a way to stop the zoom when the image is the same size as the screen.

• Just change the size of the sprite rectangle while it’s wider than the screen.

if (jakeRect.Width > graphics.GraphicsDevice.Viewport.Width){

jakeRect.Width =jakeRect.Width - getPercentage(1, jakeRect.Width);jakeRect.Height =jakeRect.Height - getPercentage(1, jakeRect.Height);

}

Page 36: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Zooming from the Center• If you want to zoom in on the center of the image, you

need to move the upper-left corner of the draw rectangle up and to the left moving the display area into the middle of the image.

Page 37: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Zooming from the Center• For the method to work properly, it has to know the width of the texture that

is to be used, so all the work must be performed in the LoadContent method.

protected override void LoadContent(){// Create a new SpriteBatch, which can be used to draw textures.spriteBatch = new SpriteBatch(GraphicsDevice);jakeTexture = this.Content.Load<Texture2D>("jake");int displayWidth = GraphicsDevice.Viewport.Width;int displayHeight = GraphicsDevice.Viewport.Height;int scaledWidth = jakeTexture.Width * 10;int scaledHeight = jakeTexture.Height * 10;jakeRect = new Rectangle(

-(scaledWidth / 2) + (displayWidth / 2),-(scaledHeight / 2) + (displayHeight / 2),scaledWidth, scaledHeight);

}

Page 38: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Zooming from the Center• Now that you’ve put the viewing rectangle in the center of

the screen, you need to move the draw position each time you scale the image.

• It turns out that if the width of the rectangle changes by X-amount, the position of the upper-left corner must move to the right by half of X to keep the rectangle centered with respect to the display area.

int widthChange = getPercentage(1, jakeRect.Width);int heightChange = getPercentage(1, jakeRect.Height);jakeRect.Width = jakeRect.Width - widthChange;jakeRect.Height = jakeRect.Height - heightChange;jakeRect.X = jakeRect.X + (widthChange / 2);jakeRect.Y = jakeRect.Y + (heightChange / 2);

Page 39: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Zooming from the Center• The problem with this zoom program is that although it

works fine, when the zoom finishes, the image is not lined up properly with the display.

• The X and Y draw positions, which should be 0 when you’ve fully zoomed out of the image, still hold negative values at the end of the zoom.

• The problem lies with the following two statements

jakeRect.X = jakeRect.X + (widthChange / 2);jakeRect.Y = jakeRect.Y + (heightChange / 2);

Page 40: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0

Zooming from the Center• if the width change were 101, the change to the value of X

would be 50, not 50.5.

• This calculation is repeated many times, and eventually this lack of precision leads to an answer that’s incorrect.

• The only way to solve this problem is to change the data type you’re using to hold all the values.

• Change your variable type to float.

• Errors in values that build up over time, sometimes called cumulative errors, are something that programmers often need to address.

Page 41: CHAPTER 10 Using C# Methods to Solve Problem XNA Game Studio 4.0