In XNA game programming, a lot of built-in or customized objects exist in the game data container. When the quantity increases and it becomes onerous for you to manage, you will need a service to make your XNA programming life easier; this recipe will give you the necessary guidance.
In an XNA application, some parts or objects of your game need to be separately updated or drawn, such as radar, player, or monster. Within your XNA game, you need to create separate defined classes for the substances, then build an instance of one of them, initialize it, update it, and finally, render it to the screen within the Draw()
method reserved for game loop calling. Hence, you need to define these kind of classes, which have their own Initialize(), Load/UnloadContent(), Update()
, and Draw()
methods, so that you can easily call them in the XNA game loop.
Again, it is better to inherit these classes from GameComponent
, which promises your classes are added to the Component List, Game.Component
a global objects manager in XNA application. It simplifies the management of the game shared objects to the delight of the XNA programmer
Furthermore, if you are sure your separated class has the rendering ability, DrawableGameComponent
could be the best choice for you because the overridden Draw()
method will be called automatically from DrawableGameComponent
.
1. As an example, define a
Radar
class inherited fromDrawableGameComponent:
public class Radar : DrawableGameComponent { . . . Rectangle destRec; Rectangle playerPositionRec; Vector2 playerVector; List<Vector2> enemiesPosition; Texture2D texture; SpriteBatch spriteBatch; Texture2D texPlayerPosition; public Radar(Texture2D texture, Rectangle rectangle, SpriteBatch spriteBatch, Game game) : base(game) { // Initialize the radar member variables . . . } protected override void Draw(GameTime gameTime) { spriteBatch.Draw(texture, destRec, Color.White); spriteBatch.Draw(texPlayerPosition, playerVector, Color.Red); foreach (Vector2 vec in this.enemiesPosition) { spriteBatch.Draw(texPlayerPosition, vec, Color.Yellow); } base.Draw(gameTime); } protected override void Initialize() { // Initialize the device . . . base.Initialize(); } protected override void LoadContent() { // Load radar and player texture content . . . base.LoadContent(); } protected override void UnloadContent() { base.UnloadContent(); } public override void Update(GameTime gameTime) { // Update the player position . . . base.Update(gameTime); } }
2. Now, that you have defined your
GameComponent
, the next step is to insert theComponent
to theGameComponent
list of theGame
class. Once added, the overridden method will be called automatically:public Game1() { . . . Components.Add(new Radar(this)); }
3. Another way is to initiate the instance first and then pass it to the
Add()
method. The second approach provides the door. Sometimes, you might need to update some public variables of the component. For theRadar
class, you can update the player's position:Radar radar; public Game1() { . . . Components.Add(radar); }
4. The
Draw()
method in theGame
class is a very simple ascribe to theGameComponent
list. TheDraw()
method ofDrawableComponent
belongs to theGameComponent
list and will be called automatically. The code snippet is similar to the following code:protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); base.Draw(gameTime); }