Plugging in More Game Components


Before you even noticed it your graphics engine has grown to a respectable size and you have a lot of useful classes right now, which help you to render both 2D and 3D data quite easily, as can be seen in the many unit tests available in most of the classes (see Figure 5-14).

image from book
Figure 5-14

You haven’t used many game components until now and in my opinion it does not make much sense to write the base graphics engine with components. You did not use any Update or Draw methods the way game components are used. Okay, the Model class uses a Render method and the Input class has an Update method, but other than that you did not have any functionality that is compatible with game components. The Render methods in the model and texture classes work quite differently because they expect the user to call them with different values and very often each frame. I guess the Input class could be changed to a game component, but I’m not quite excited about that idea.

Instead let’s think of components, which fit perfectly into the game components model. It would make sense if you have a class that needs to be updated and drawn each frame. Examples for these kinds of classes would be frame per second counters or a camera class, which is still missing from your engine.

Simple Camera Class

You don’t need a complex camera for your unit tests, but it would be nice to move around a little and to have a simple 3D look at the objects you render in your engine unit tests. With the help of the view matrix and the Matrix.CreateLookAt method you can easily create such functionality and set it wherever you need it. Even better would be the use of a game component class to do all this automatically; all you have to do is to create an instance of the camera class in the constructor of the YourGame class, which is derived from the BaseGame class, and suddenly all unit tests and other 3D code will use the new camera class without any extra code because Update is called automatically for each game component you have in the YourGame class.

  public YourGame() {   // Init simple camera   this.Components.Add(new SimpleCamera(this)); } // YourGame() 

The SimpleCamera class has a constructor and an Initialize and Update method, which are both called automatically (see Figure 5-15). The class also has three fields for the x, y, and z position of the camera, which is initialized to (0, 0, 15). Update then changes x and y based on the mouse movement, or if you have a gamepad, based on the right thumb stick movement. Additionally you can zoom in and out with the left thumb stick.

image from book
Figure 5-15

The class is quite simple and it is easy to read through the code of the whole class:

  /// <summary> /// Simple camera class just to move around a little. /// Always focuses on the center and uses the same height. /// </summary> class SimpleCamera : GameComponent {   #region Variables   float x = 0, y = 0;   float zHeight = 15.0f;   #endregion   #region Constructor   public SimpleCamera(BaseGame game)     : base(game)   {   } // SimpleCamera(game)   #endregion   #region Initialize   public override void Initialize()   {     base.Initialize();   } // Initialize   #endregion   #region Update   public override void Update(GameTime gameTime)   {     base.Update(gameTime);     // Update camera position (allow mouse and gamepad)     x += Input.MouseXMovement / 10;     y += Input.MouseYMovement / 10;     x += Input.GamePad.ThumbSticks.Right.X;     y += Input.GamePad.ThumbSticks.Right.Y;     zHeight += Input.GamePad.ThumbSticks.Left.Y;     BaseGame.ViewMatrix = Matrix.CreateLookAt(       new Vector3(x, y, zHeight), Vector3.Zero, Vector3.Up);   } // Update(gameTime)   #endregion } // class SimpleCamera 

The important thing here is the ViewMatrix from the BaseGame class, which is set at the end of the Update method. When rendering a shader in the model class or in any other class like the line managers, you will use this view matrix and make sure that all your 3D data is converted to your view space with this exact matrix until you change it again next frame.

You now have everything together for the TestRenderOurNewGraphicEngine test you wrote at the beginning of this chapter, and if you take a look at all the classes in the project you imported and wrote, it is quite a nice engine that is both easy to use and extensible, which you will explore in the next chapters.

ScreenshotCapturer Class

There is also another helper class in the engine called ScreenshotCapturer, which allows you to take screenshots with the Print-Screen key. It is implemented as a game component too and it is initialized in the BaseGame constructor. The Update method is called automatically and just calls MakeScreenshot if the user just pressed the Print-Screen key:

  public override void Update(GameTime gameTime) {   if (Input.KeyboardKeyJustPressed(Keys.PrintScreen))     MakeScreenshot();   base.Update(gameTime); } // Update(gameTime) 

The MakeScreenshot method creates a temporary texture and stores the back buffer with the help of the ResolveBackBuffer method of the device. The result is then saved to disk with the help of some other helper methods in the class:

  using (Texture2D dstTexture = new Texture2D(   BaseGame.Device, BaseGame.Width, BaseGame.Height, 1,   ResourceUsage.ResolveTarget,   SurfaceFormat.Color,   ResourceManagementMode.Manual)) {   // Get data with help of the resolve method   BaseGame.Device.ResolveBackBuffer(dstTexture);   dstTexture.Save(     ScreenshotNameBuilder(screenshotNum),     ImageFileFormat.Jpg); } // using (dstTexture) 




Professional XNA Game Programming
Professional XNA Programming: Building Games for Xbox 360 and Windows with XNA Game Studio 2.0
ISBN: 0470261285
EAN: 2147483647
Year: 2007
Pages: 138

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net