# Microsoft XNA Game Studio Creator’s Guide- P8

Chia sẻ: Cong Thanh | Ngày: | Loại File: PDF | Số trang:30

0
75
lượt xem
9

## Microsoft XNA Game Studio Creator’s Guide- P8

Mô tả tài liệu

Microsoft XNA Game Studio Creator’s Guide- P8:The release of the XNA platform and specifically the ability for anyone to write Xbox 360 console games was truly a major progression in the game-programming world. Before XNA, it was simply too complicated and costly for a student, software hobbyist, or independent game developer to gain access to a decent development kit for a major console platform.

Chủ đề:

Bình luận(0)

Lưu

## Nội dung Text: Microsoft XNA Game Studio Creator’s Guide- P8

1. 188 MICROSOFT XNA GAME STUDIO CREATOR’S GUIDE SineCycle() traces a floating-point value through a sine wave’s cycle over time. The function is only executed once per frame but is used to update each Y value for all vertices in the grid. Add this function to your game class: float SineCycle(GameTime gameTime){ // less than full cycle of sine wave retrieves between 0 and 1. // full cycle for sine wave is 2*PI. if (cycleIncrement < 1) cycleIncrement += 0.0000005f * (float)gameTime.ElapsedGameTime.Milliseconds; // adjust when sine wave cycle complete else cycleIncrement = cycleIncrement - 1; return cycleIncrement; } As discussed, SineCycle() is called only once per frame to trace a value on the sine wave over time. The point on the sine wave that is returned is added to the V co- ordinate for each point in the grid. This sum is used for setting the Y value of each point in the grid. The result is a set of oscillating Y values that follow the sine wave as it rises and falls over time. SetWaterHeight() receives the sum of the texture’s V coordinate plus the point in the sine wave over time. This sine wave equation returns a Y value for the co- ordinate that corresponds with the V coordinate: Height = Amplitude = sin(WaveCountPerCycle * PointInCycle * 2π) Add the SetWaterHeight() method to the game class: float SetWaterHeight(float cycleTime){ const float FREQUENCY = 6.0f; // wave count per cycle const float AMPLITUDE = 1.0f/15.0f; // wave height // generates height based on V coord and sine equation return (AMPLITUDE * (float)Math.Sin(FREQUENCY * cycleTime * 2.0f * (float)Math.PI) - 0.4f); }
2. C H A P T E R 1 2 189 Combining Images for Better Visual Effects The X, Y, Z information is the same for both the stationary image layer and the moving image layer. Since the stationary layer is drawn first, the Y value that changes with the sine wave over time can be set for this layer and the changes will apply to both image layers. Adding this code to reset the X, Y, and Z coordinates inside the nested for-loop for UpdateMovingSurface() will create a dynamically changing Y value that simulates the wave for both layers over time: float X = surface1[col + row * NUM_COLS].Position.X; float Y = SetWaterHeight(V + SineCycle(gameTime)); float Z = surface1[col + row * NUM_COLS].Position.Z; surface0[col + row * NUM_COLS].Position = new Vector3(X, Y, Z); surface1[col + row * NUM_COLS].Position = new Vector3(X, Y, Z); When you run this program, it shows the moving dynamic texture and the waves rippling through the object. The effect is actually quite beautiful (see Figure 12-5). You can try building this example, or you can download the completed example from the Solutions folder on this book’s website. There are various ways to combine images for creating exciting graphics effects. Sprites are used to animate a series of image frames that are stored in an image file. Multitexturing can be used to blend two images together and provide more detail or dynamic movement for the texture. FIGURE 12-5 Surf’s up!
3. 190 MICROSOFT XNA GAME STUDIO CREATOR’S GUIDE C HAPTER 12 REVIEW EXERCISES To get the most from this chapter, try out these chapter review exercises. 1. Try the step-by-step examples presented in this chapter, if you have not already done so. 2. For your solution to the SpriteBatch example, remove the code that manually resets the RenderState properties for the GraphicsDevice in the Draw() method. Then, add code to automatically restore the render states after the SpriteBatch object is drawn. Automatically restoring the render states can be done in DrawAnimatedHud() by replacing the SpriteBatch object’s Begin() instruction with code similar to this: spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate,SaveStateMode.SaveState); Try running your code and notice that the output appears to be the same as before. 3. Replace your Begin() statement in Exercise 2 with an instruction similar to the following statement and then run your project: spriteBatch.Begin(); Notice how the ground and all other 3D objects disappear when the render states are not restored. 4. With the solution for the 2D sprite and the original 2D sprite settings, call DrawAnimatedHud() before DrawGround(). Notice that you cannot see the sprite unless the view is changed so the ground is not covering it. 5. Create your own sprite with three or more frames. In the same project, show the sprite as a 2D SpriteBatch object. Display your sprite in the 3D world using a textured sprite. 6. Use multitexturing to make it appear as if moving shadows cast from the clouds are traveling across the ground.
4. CHAPTER 13 Score Tracking and Game Stats
5. able to display status information about players, and their BEING scores, is fundamental to any game dashboard. For exam- ple, you might need to show statistics such as health, fuel level, the current map name, or maybe even the opponents’ names. In the end, your ability to present this in- formation boils down to having access to a font library that can overlay 2D text on your game’s 2D or 3D environment. As you would expect, XNA offers an excellent font library for this purpose. The two examples in this chapter demonstrate how to write text and numeric out- put to the game window. When you are finished (depending on which project you start with), your output will be similar to the window display shown in Figure 13-1. FIGURE 13-1 Text and numeric data drawn in the game window 192
7. 194 MICROSOFT XNA GAME STUDIO CREATOR’S GUIDE If you view the contents of the spritefont file, you will see XML code that stores the font properties. You can adjust these elements to change the size of the font and the spacing between characters, and you can also set the font to be Regular, Bold, Italic, or Bold Italic in the element. To reference a TrueType font on your PC or Xbox 360, you will need to adjust the element value in the spritefont file. In this example we will load a Cou- rier New font, so to do this, you must replace the FontName element with: Courier New Once you have made this adjustment, your XML code will appear in the MyFont.spritefont file as follows: Courier New 14 0 true Regular
8. C H A P T E R 1 3 195 Score Tracking and Game Stats &#32; &#126; For now, aside from changing the FontName, you can leave the default spritefont file settings as they were originally generated. However, you can edit the elements in this file further to change the size, weight (boldness), italics, and other properties if desired. Loading the Font Fonts are drawn using a SpriteFont object, which you must declare at the top of the game class: private SpriteFont spriteFont; The SpriteFont object actually is a sprite, so the corresponding data behind it should be read in the LoadContent() method. This object is loaded by first retriev- ing the font description data from the spritefont file. Since the spritefont file is refer- enced in the Content folder, you do not need to specify a directory when loading it. To load this file with the Load() method, you must pass the name of the spritefont filename without the file extension: spriteFont = Content.Load("MyFont");
9. 196 MICROSOFT XNA GAME STUDIO CREATOR’S GUIDE Ensuring Your Fonts Are Drawn in the Visible Portion of the Window We have already discussed the need to designate a title safe region in Chapter 4. This avoids truncating your graphics when running your games on the Xbox 360. Since fonts are 2D, and you do not want your fonts to be truncated, you will need to display your text in a title-safe region. A TitleSafeRegion() method was used in Chap- ter 4 to generate a rectangle that stores the top, bottom, left, and right margins a r ou nd t he saf e are a. An alte r na t e, b ut si mi l a r, v ers i o n of t h e TitleSafeRegion() method will be used in this chapter to calculate the starting pixel position on the window for each string that is written to it. This new TitleSafeRegion() method receives a string and a SpriteFont object as parameters. It then uses the SpriteFont’s MeasureString() method to retrieve the width and height of the string. The MeasureString() method uses the string to determine the output width and it uses the SpriteFont object to calcu- late the height of the font. Here is the revised version of the TitleSafeRegion() method to conveniently generate margins for the visible display area from game class: Rectangle TitleSafeRegion(string outputString, SpriteFont font){ Vector2 stringDimensions = font.MeasureString(outputString); int stringWidth = (int)stringDimensions.X; // string pixel width int stringHeight = (int)stringDimensions.Y; // font pixel height // some televisions only show 80% of the window const float UNSAFEAREA = 0.2f; const float MARGIN = UNSAFEAREA/2.0f; // calculate title safe bounds for string int top, left, safeWidth, safeHeight; top = (int)(Window.ClientBounds.Height*MARGIN); left = (int)(Window.ClientBounds.Width *MARGIN); safeWidth = (int)((1.0f-UNSAFEAREA)*Window.ClientBounds.Width) - stringWidth; safeHeight = (int)((1.0f-UNSAFEAREA)*Window.ClientBounds.Height) - stringHeight; return new Rectangle(left, top, safeWidth, safeHeight); }