Tuesday, March 20, 2007

Xbox Live Arcade Approval Process

Via: http://www.gamedevblog.com/2007/03/some_answers.html

It's an interesting little read. Get a little insight on what it may take to get your XNA game onto XBLA

To get an Xbox Live Arcade game approved, there's various stages and greenlight meetings you have to get through. First you've got to get somebody there excited enough to get it into a greenlight meeting in the first place.

The next stage is the "Concept Greenlight"

The next stage is a due diligence meeting

Coming up later is the certification or TRC - the "technical requirements checklist"


Read more!

Monday, March 19, 2007

Changed Rss/Atom Feed

I have changed my feed over from the built in Blogger rss/atom feeds, to use FeedBurner instead. If you have subscribed to my blog, you may want to update your feed with the new address: http://feeds.feedburner.com/TehOne

Please let me know if you have any problems with the new feed.

Thanks. Read more!

Activity

I haven't had much time to work on my XNA stuff lately or make a any new posts. I'm in the middle of moving out of 2 homes and into a new one. So, this has monopolized a lot of my free time. Hopefully I'll be able to get to work a little more once I get into the new place after the first week April. Things I have been working on are a Texture2DManager, a Sprite DrawableGameComponent and a SpriteLayer DrawableGameComponent. After these are done, I plan to work on some Transition effects stuff.

Well, just wanted to put this news out there (not that anyone is paying attention anyways). This blog isn't dead already or anything like that.

Read more!

Tuesday, March 13, 2007

Looking for Shaders?

If your looking for HLSL Shaders here is a great place to try to find one that fits your needs. NVidia has released a large library of "ready to go" HLSL shaders that you can download and use in your project. This license applies.

http://developer.download.nvidia.com/shaderlibrary/webpages/shader_library.html

I personally don't have any experience with shaders. I have always thought they were only for 3D games. But now I have seen some 2D games where they are used for effects and also things like adding a bit of "depth" to the 2D game with water etc... An example can be seen here (by Ska Software):

Since seeing that shaders can be used in 2D games with great results, I will be spending more time exploring them. I was probably going to try to use sprites/textures for adding some "pop" to any games I developed. But now that I have seen shaders in 2D games, I think I'll explore using them instead. Only time will tell. In any case, this is a great resource. Read more!

Thursday, March 08, 2007

Mouse2D GameComponent

Here is my Mouse2D DrawableGameComponent. I started out just wanting to be able to put a custom Mouse pointer/cursor on the screen instead of the windows mouse. From there the code just seemed to keep evolving more and more. After I got my custom pointer on the screen, I wanted to then place a Texture2D where it clicked (this was mostly for debugging etc, but I think turned out to be useful for other things). I could see this feature being used in map editors maybe, or something where you want to give the user the ability to design what they see on the screen.

Well, from there I just kept adding more and more to the code. Instead of just placing a Texture2D where a click occurred, I wanted to create an event system for the clicks. So, I started adding this in. Then, instead of just tracking clicks, I decided to track when the button is released as well. I also added events for the Mouse scroll wheel as well. Then I created events for when the Mouse was moved. After all that I decided that I should pass back some useful information from the events. So, when the MouseMoved event is fired, we pass back MouseMovedEventArgs which contains the Movement property which is a Vector2 that represents how much the Mouse has moved in the X and Y direction since the last update.

As well as adding some useful information into the events for Mouse movement, I also wanted to add some information on the Mouse button clicks and releases. So the ClickEventArgs class was then created. This contains the Click and PreviousClick properties. By using these, you can figure out how a click occured, and how much the user moved the Mouse before they release the button. This could be useful for drag and drop type of actions (maybe for selecting units in an rts style game) etc. It can also be used to find out how much time in between the click and the release of the button. There are event handlers for each Mouse button and it's state, and for the scroll wheel changes and for the mouses movement.

I called this DrawableGameComponent Mouse2D because it was developed with 2D games in mind (since I have zero 3D game developing skills). I'm not familiar with 3D enough yet to know if this class would need to be changed in order to be affective for 3D game projects. Well, I think that gives enough of an introduction to this. Now I'll post some code. Since the code for Mouse2D is a bit long, especially with the xml comments etc), I won't be putting code from it in this blog post. You will have to download the code in order to view it. Instead, I'm going to post some sample code of how you might use it in a game.

Ok, now on to the code. (code license)


Ok, to start, you would just create a new Widows Game using XNA GSE. You should now have a project with a Game1.cs file in it. This is the base for starting your XNA game. You should end up with something like the below for the first few lines of your new Game1.cs file:
Show Plain Text
Show Line #
Alternating Lines
Hide Comments
  1. #region Using Statements
  2. using System;
  3. using System.Collections.Generic;
  4. using Microsoft.Xna.Framework;
  5. using Microsoft.Xna.Framework.Audio;
  6. using Microsoft.Xna.Framework.Content;
  7. using Microsoft.Xna.Framework.Graphics;
  8. using Microsoft.Xna.Framework.Input;
  9. using Microsoft.Xna.Framework.Storage;
  10. #endregion
  11.   
  12. namespace WindowsGame1
  13. {
  14.   /// <summary>
  15.   /// This is the main type for your game
  16.   /// </summary>
  17.   public class Game1 : Microsoft.Xna.Framework.Game
  18.   {
  19.     GraphicsDeviceManager graphics;
  20.     ContentManager content;
  21.     
  22.     public Game1()
  23.     {
  24.       graphics = new GraphicsDeviceManager(this);
  25.       content = new ContentManager(Services);
  26.     }

Ok, so, we'll change the above to this:
Show Plain Text
Show Line #
Alternating Lines
Hide Comments
  1. #region Using Statements
  2. using System;
  3. using System.Collections.Generic;
  4. using Microsoft.Xna.Framework;
  5. using Microsoft.Xna.Framework.Audio;
  6. using Microsoft.Xna.Framework.Content;
  7. using Microsoft.Xna.Framework.Graphics;
  8. using Microsoft.Xna.Framework.Input;
  9. using Microsoft.Xna.Framework.Storage;
  10. using TehOne.Xna.GameComponents;
  11. #endregion
  12.   
  13. namespace WindowsGame1
  14. {
  15.   /// <summary>
  16.   /// This is the main type for your game
  17.   /// </summary>
  18.   public class Game1 : Microsoft.Xna.Framework.Game
  19.   {
  20.     GraphicsDeviceManager graphics;
  21.     ContentManager content;
  22.     
  23.     MousePointer2D mousePointer;
  24.     
  25.     public Game1()
  26.     {
  27.       graphics = new GraphicsDeviceManager(this);
  28.       content = new ContentManager(Services);
  29.       
  30.       mousePointer = new MousePointer2D(this);
  31.       
  32.       this.Components.Add(mousePointer);
  33.     }

Basically, what we did was, we added a field to the class to hold our Mouse2D object. Then, in the constructor, we instantiated the Mouse2D object and stored it in our newly created field. Then, we add the object to the Game.Components collection. If you were to build the game now, you should see a mouse cursor/pointer on the screen. The Texture2D being used for the Mouse is an embedded resource in the TehOne.Xna.GameComponents dll. If you want to use your own Texture2D, then you would set the PointerAssetName in the constructor, like below:
Show Plain Text
Show Line #
Alternating Lines
Hide Comments
  1. public Game1()
  2. {
  3.   graphics = new GraphicsDeviceManager(this);
  4.   content = new ContentManager(Services);
  5.   
  6.   mousePointer = new MousePointer2D(this);
  7.   
  8.   this.Components.Add(mousePointer);
  9.   
  10.   mousePointer.PointerAssetName = @"Content\Sprites\YourMouseAsset";
  11. }

As long as the PointerAssetName that you set exists, then you will now see your custom pointer on the screen if you rebuild the project. If the PointerAssetName that you set doesn't exist, the Mouse2D will still use it's internal Texture2D for the mouse. That is unless you set CanUseInteralAssets property to false. If you did set that to false, and your PointerAssetName you set doesn't exist, then you will get an exception thrown.

Now, to show how to hook into the events. This is a very simple example (to keep this post shorter). A more complete example is included in the code download. This shows you how to move a sprite when the mouse moves. I currently only having it moving from left to right for the sake of example (boundry detection is not being done either). What we are doing is adding a method to be fired when the mouse moves. Then we wire this event into the MouseMoved event of the Mouse2D object.
Show Plain Text
Show Line #
Alternating Lines
Hide Comments
  1. public class Game1 : Microsoft.Xna.Framework.Game
  2. {
  3.   GraphicsDeviceManager graphics;
  4.   ContentManager content;
  5.   
  6.   MousePointer2D mousePointer;
  7.   
  8.   private SpriteBatch _spriteBatch;
  9.   private Texture2D _sprite;
  10.   private Vector2 _spritePosition = new Vector2(0, 0);
  11.   
  12.   public Game1()
  13.   {
  14.     graphics = new GraphicsDeviceManager(this);
  15.     content = new ContentManager(Services);
  16.     
  17.     mousePointer = new MousePointer2D(this);
  18.     
  19.     this.Components.Add(mousePointer);
  20.     
  21.     mousePointer.PointerAssetName = @"Content\Sprites\YourMouseAsset";
  22.     
  23.     mousePointer.MouseMoved += new MousePointer2D.MouseMovedHandler(mousePointer_MouseMoved);
  24.   }
  25.   
  26.   void mousePointer_MouseMoved(object sender, MousePointer2D.MouseMovedEventArgs e)
  27.   {
  28.     _spritePosition.X = mousePointer.Position.X;
  29.   }
  30.   
  31.   protected override void LoadGraphicsContent(bool loadAllContent)
  32.   {
  33.     if(loadAllContent)
  34.     {
  35.       _spriteBatch = new SpriteBatch(graphics.GraphicsDevice);
  36.       _sprite = content.Load<Texture2D>(@"Content\Sprites\YourSpriteName");
  37.     }
  38.   }
  39.   
  40.   protected override void Draw(GameTime gameTime)
  41.   {
  42.     device.Clear(Color.CornflowerBlue);
  43.     _spriteBatch.Begin();
  44.     _spriteBatch.Draw(_sprite, _spritePosition, Color.White);
  45.     _spriteBatch.End();
  46.     base.Draw(gameTime);
  47.   }

For the last example, I'll wire up some events for the scroll wheel and a left click. First we need to create our methods for each, and then wire them up to the proper events. For the ScrollChanged event, we create a mousePointer_ScrollChanged method and when it is fired, we check to see which way the scroll wheel was moved (up or down). And then we set our sprites Y position based on it. For the LeftButtonPressed event, we create the mousePointer_LeftButtonClicked method and when it is fired we move the our sprites postion to the postion where the click occured.
Show Plain Text
Show Line #
Alternating Lines
Hide Comments
  1. public Game1()
  2. {
  3.   graphics = new GraphicsDeviceManager(this);
  4.   content = new ContentManager(Services);
  5.   
  6.   mousePointer = new MousePointer2D(this);
  7.   
  8.   this.Components.Add(mousePointer);
  9.   
  10.   mousePointer.PointerAssetName = @"Content\Sprites\YourMouseAsset";
  11.   
  12.   mousePointer.MouseMoved += new MousePointer2D.MouseMovedHandler(mousePointer_MouseMoved);
  13.   mousePointer.ScrollChanged +=new MousePointer2D.ScrollChangedHandler(mousePointer_ScrollChanged);
  14.   mousePointer.LeftButtonPressed += new MousePointer2D.ClickHandler(mousePointer_LeftButtonClicked);
  15. }
  16. void mousePointer_MouseMoved(object sender, MousePointer2D.MouseMovedEventArgs e)
  17. {
  18.   _spritePosition.X = mousePointer.Position.X;
  19. }
  20. void mousePointer_ScrollChanged(object sender, MousePointer2D.ScrollChangedEventArgs e)
  21. {
  22.   if (e.Direction == MousePointer2D.ScrollChangedEventArgs.ScrollDirection.Up)
  23.     _spritePosition.Y -= _sprite.Height;
  24.   if (e.Direction == MousePointer2D.ScrollChangedEventArgs.ScrollDirection.Down)
  25.     _spritePosition.Y += _sprite.Height;
  26. }
  27. void mousePointer_LeftButtonClicked(object sender, MousePointer2D.ClickEventArgs e)
  28. {
  29.   _spritePosition = e.Click.Position;
  30. }


As always, I would really appreciate some feeback on this. I'm sure people can make use of this code (especially beginers). And I'm even more sure that it can be improved with input from others (especially those with more experience then me). Read more!

Tuesday, March 06, 2007

New Source Code Formatting

Well, after some talking back and forth with ziggy about the code formatting I was using, I have decided to change it. Luckily for me, the page I was using to do the formatting, also has the source code available. I have taken the code and modified it with a look and features that I wanted. You can check out how the code looks by checking out my articles where I posted code, and you can view the tool here... http://tehone.com/utils/SourceFormat/ I'm open to opinions on the code format and I'll be posting the modified source soon. Read more!

Monday, March 05, 2007

Dream-Build-Play’s main competition has gone live.

As well as the new creators website being launched, the kind folks over at the official xna team blog also released the information below. I must say, those are some pretty fantastic prizes. Unfortunately for me, I don't think my skills are up to entering the contest. But, I'll have a lot of fun watching/reading (and hopefully seeing the source code eventually) what others are up to. I guess Ultrahead didn't have to stay tuned very long. Too bad he went to sleep i bet, and let me snap up this information first.

Dream-Build-Play’s main competition has gone live. Fame, fortune and a chance at global envy await you in our Dream-Build-Play competition. The grand prize is a $10,000, an awesome Alienware PC with a smokin’ fast AMD FX processor and ATI graphics card, 3D modeling software, Xbox 360, XNA Creators Club subscription tokens and an amazingly cool Xbox Live Arcade publishing contract for your chance to get your game published on Xbox Live Arcade. Do you have what it takes to win all that and more? Then get started on making your dream game using XNA Game Studio Express and head on over to http://www.dreambuildplay.com to enter it into the contest.
Read more!

XNA Creators site launched

A new site for XNA "Creators" has been put up by our friends at Microsoft. I took a brief look at the site and I think it's great. I think it has some bugs (wouldn't let me log in, something about not having a gamer tag even though i do have one). But, overall, the site looks great and it already has a few nice things on it. The first, a new starter kit. I think this is fantastic, we can never have too many examples check out. Another of interest to me, is a sample for font rendering in XNA. I have been hoping we would get this without having to wait too long and it looks like its coming. Not sure when, but they look like they could release it the way it is, or at least in the near future. There are other resources on the site too and hopefully they will be very active with the site and keep posting updates/code/tutorials/starter kits etc. I think the biggest winner here will be the community.

From the article:

The XNA Creators Club Online community site is open for business! Head on over to http://creators.xna.com and register for the XNA Creators Club Online community. You’ll find some great content such as: * A brand new starter kit! (Marblets) * Several samples including a skinning (animation) sample using the XNA Framework Content Pipeline! * Downloadable sample games. New developer forums. * Video tutorials. * Much, much, more!
Read more!

Saturday, March 03, 2007

Framerate GameComponent

Updated Again: Reformatted source again. Should be the last time. Check out this post for details.

Updated: Removed line numbers in code snippets after some constructive criticism from ziggy.

Here is my implementation of a Framerate (FPS) GameComponent. It is a DrawableGameComponent even though in it's current form it doesn't actually draw anything to the screen. Since there is currently no built in font/text rendering in XNA, this component currently only updates the game window title with the current FPS. It can be easily adapted to draw the framerate to the screen by using something like Nuclex.Fonts or BitmapFonts. But to keep implementation as simple as possible, this is left out of this component for now. This component exposes a CurrentFramerate property that you can use in your Game code to easily draw the FPS to the screen without having to recompile the TehOne.Xna.GameComponents code.

This Framerate component isn't that dissimilar to other framerate GameComponents that you may have seen out there. The main difference is that it has a base class of TehOne.Xna.GameComponents.XnaDrawableGameComponent instead of the regular DrawableGameComponent provided by Microsoft. To see the reason behind this, read up on my previous post here. There are two other main differences from this and other framerate components that you may have seen on the web.

  • The first difference:
  • This class exposes a CurrentFramerate property that you can then use in your game. I did this for two reasons: To allow you to have easy access to the current FPS from your game, so you can render text without having to integrate it into this component (and having to recompile it). And, the other reason is that now you can write code in your game that uses the FPS for some sort of logic. I was thinking that this would be useful for something like smoothing out animation based on the current FPS, or smoothing out movement or something else along those lines.
  • The second difference:
  • This class has an UpdateFrequency property. This property allows you to set how often you want to calculate the FPS. I don't know about you, but most of the games I play update the FPS more then once a second. So, I thought that I would implement this feature. You can set the frequency to anything higher then 99 as long as it is divisible by 100. This property is based on milliseconds, so if you want to update your FPS every 10th of a second, then you would set this property to 100. Likewise, if you want to update your FPS every other second, you would set this property to 2000.

Ok, now on to the code. (code license)

Show Plain Text
Show Line #
Alternating Lines
Hide Comments
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using Microsoft.Xna.Framework;
  5.   
  6. namespace TehOne.Xna.GameComponents
  7. {
  8.     /// <summary>
  9.     /// This is a <see cref="XnaDrawableGameComponent"/> that is used to calculate and display the current framerate (FPS, FramesPerSecond) of the game.
  10.     /// <para>Extends <see cref="XnaDrawableGameComponent"/> so that we can use it's <see cref="XnaDrawableGameComponent.PreviouslyEnabled"/> property and take advantage of it auto-enabling and disabling when the game is focused/not-focused.</para>
  11.     /// </summary>
  12.     public partial class Framerate : XnaDrawableGameComponent
  13.     {
  14.         private double _fps = 0;
  15.         private float _elapsedRealTime = 0;
  16.         private string _gameWindowTitle;
  17.         private ushort _updateFrequency = 1000;
  18.         private float _updateFrequencyRatio;
  19.   
  20.         /// <summary>
  21.         /// The CurrentFramerate property represents the current frames per second (FPS) for the game.
  22.         /// </summary>
  23.         /// <value>The CurrentFramerate property gets the <see cref="_fps"/> data member.</value>
  24.         public double CurrentFramerate
  25.         {
  26.             get
  27.             {
  28.                 return _fps;
  29.             }
  30.         }
  31.   
  32.         /// <summary>
  33.         /// The UpdateFrequency property represents, in milliseconds, how often we are updating the <see cref="_fps"/> count.
  34.         /// </summary>
  35.         /// <value>The UpdateFrequency property gets/sets the <see cref="_updateFrequency"/> data member.</value>
  36.         /// <remarks>
  37.         /// This is used to set how often we are calculating the frames per second count.
  38.         /// <para>The default value is <b><c>1000</c></b>.</para>
  39.         /// </remarks>
  40.         /// <exception cref="System.ArgumentOutOfRangeException">This exception will be thrown when the <b><c>value</c></b> is set less then <b><c>100</c></b> or when <b><c>value</c></b> is not divisible by <b><c>100</c></b>.</exception>
  41.         public ushort UpdateFrequency
  42.         {
  43.             get
  44.             {
  45.                 return _updateFrequency;
  46.             }
  47.             set
  48.             {
  49.                 if(value % 100 != 0 || value < 100)
  50.                     throw new ArgumentOutOfRangeException("UpdateFrequency", value, "The UpdateFrequency for the Framerate must is based on milliseconds and must be must be a positive number that is greater then or equal to 100, and the number must be divisable by 100.");
  51.   
  52.                 _updateFrequency = value;
  53.   
  54.                 // Figure out the new ratio, this way we are reporting the correct frames per second even when we are not calculating ever second.
  55.                 _updateFrequencyRatio = 1000 / (float)_updateFrequency;
  56.             }
  57.         }
  58.   
  59.         /// <summary>
  60.         /// The main constructor for the class.
  61.         /// </summary>
  62.         /// <param name="game">The <see cref="Microsoft.Xna.Framework.Game" /> instance for this <see cref="XnaDrawableGameComponent"/> to use.</param>
  63.         /// <remarks>Sets the <see cref="_gameWindowTitle"/> data member to the value of <see cref="Microsoft.Xna.Framework.GameWindow.Title"/>.</remarks>
  64.         public Framerate(Game game) : base(game)
  65.         {
  66.             // Save the original game window title
  67.             _gameWindowTitle = game.Window.Title;
  68.   
  69.             // We are basing the ratio on 1 second (1000 milliseconds)
  70.             _updateFrequencyRatio = 1000 / (float)_updateFrequency;
  71.         }
  72.   
  73.         /// <summary>
  74.         /// Allows the game component to perform any initialization it needs to before starting
  75.         /// to run.  This is where it can query for any required services and load content.
  76.         /// </summary>
  77.         public override void Initialize()
  78.         {
  79.             base.Initialize();
  80.         }
  81.   
  82.         /// <summary>
  83.         /// Allows the game component to update itself.
  84.         /// </summary>
  85.         /// <param name="gameTime">Provides a snapshot of timing values.</param>
  86.         public override void Update(GameTime gameTime)
  87.         {
  88.             base.Update(gameTime);
  89.   
  90.             if (!this.Enabled)
  91.                 return;
  92.   
  93.             // The total real time in milliseconds since the last Update().
  94.             float elapsed = (float)gameTime.ElapsedRealTime.TotalMilliseconds;
  95.   
  96.             // Adds the Update() elapsed real time to the cumulative elapsed real time.
  97.             _elapsedRealTime += elapsed;
  98.   
  99.             // If the elapsed time is greater than our update frequency then: calculate the framerate, and reduce the elapsed real time count.
  100.             if(_elapsedRealTime > _updateFrequency)
  101.             {
  102.                 _fps = (_updateFrequency / elapsed) * _updateFrequencyRatio; // calculate the framerate
  103.                 _elapsedRealTime -= _updateFrequency; // adjust the elapsedRealTime
  104.             }
  105.         }
  106.   
  107.         /// <summary>
  108.         /// This is called when the game should draw itself.
  109.         /// </summary>
  110.         /// <param name="gameTime">Provides a snapshot of timing values.</param>
  111.         public override void Draw(GameTime gameTime)
  112.         {
  113.             base.Draw(gameTime);
  114.   
  115.             if (!this.Visible || !this.Enabled)
  116.                 return;
  117.   
  118.             this.Game.Window.Title = _gameWindowTitle + " FPS: " + _fps.ToString("F");
  119.         }
  120.   
  121.         /// <summary>
  122.         /// This method is the <see cref="System.EventHandler"/> for the <see cref="Microsoft.Xna.Framework.GameComponent.EnabledChanged"/> event.
  123.         /// </summary>
  124.         /// <param name="sender">The events sender</param>
  125.         /// <param name="args">The events arguments.</param>
  126.         protected override void OnEnabledChanged(object sender, EventArgs args)
  127.         {
  128.             if(!this.Enabled)
  129.                 this.Game.Window.Title = _gameWindowTitle;
  130.   
  131.             base.OnEnabledChanged(sender, args);
  132.         }
  133.   
  134.         /// <summary>
  135.         /// This method is the <see cref="System.EventHandler"/> for the <see cref="Microsoft.Xna.Framework.GameComponent.EnabledChanged"/> event.
  136.         /// </summary>
  137.         /// <param name="sender">The events sender</param>
  138.         /// <param name="args">The events arguments.</param>
  139.         protected override void OnVisibleChanged(object sender, EventArgs args)
  140.         {
  141.             if (!this.Visible)
  142.                 this.Game.Window.Title = _gameWindowTitle;
  143.   
  144.             base.OnVisibleChanged(sender, args);
  145.         }
  146.     }
  147. }


Ok, so now we need to put this into our game. Add a member to your class for the Framerate. It should look something like this:
Show Plain Text
Show Line #
Alternating Lines
Hide Comments
  1. public class Game1 : Microsoft.Xna.Framework.Game
  2.     {
  3.         ContentManager content;
  4.         GraphicsDeviceManager graphics;
  5.   
  6.         Framerate framerate;


Now we need to instantiate the Framerate and add it to the Game.Components collection. This is done in your constructor for your game. It should look something like this:
Show Plain Text
Show Line #
Alternating Lines
Hide Comments
  1. public Game1()
  2.         {
  3.             graphics = new GraphicsDeviceManager(this);
  4.             content = new ContentManager(Services);
  5.             
  6.             framerate = new Framerate(this);
  7.             framerate.UpdateFrequency = 100;
  8.   
  9.             this.Components.Add(framerate);


Note: We also set the UpdateFrequency to 100 which will cause our FPS to be calculated every 10th of a second instead of the default of every once per second.

Well, that is pretty much all there is to it. If you have done everything correctly, when you launch your (windowed) game, you should see the framerate in the window title.

Read more!

Thursday, March 01, 2007

Enabling-Disabling GameComponents when a game is Activated-Deactivated

Updated Again: Reformatted source again. Should be the last time. Check out this post for details.

Updated: Removed line numbers in code snippets after some constructive criticism from ziggy.

For my GameComponents, I wanted a graceful way to Disabled and then Re-Enable them when the Game is Activated and when it is Deactivated. The important thing for me was to Disable all of the GameComponents when the Game gets Deactivated and then when the Game is Activated, I want to Re-Enable the GameComponents that were already Enabled prior to the Game being Deactivated.

The best way I saw to do this, was to extend the GameComponent class. So, that's what I have done for all (not that there is a lot yet, only 2 so far) of my custom GameComponents.

So, here you'll find the code that I used to accomplish this. Maybe in a future version of XNA this will be included into the GameComponent class.

All of the code on this site is subject to this license:

  1. /*
  2. * Copyright (c) 2007, Eric Lebetsamer (http://tehone.com)
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights to
  7. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  8. * the Software, and to permit persons to whom the Software is furnished to do so,
  9. * subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in all copies
  12. * or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  15. * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  16. * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  17. * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  18. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  19. * USE OR OTHER DEALINGS IN THE SOFTWARE.
  20. */


Ok, now on to the code. (code license)
I chose to first create an Interface. I created this because I needed to extend both GameComponent and also DrawableGameComponent, but I wanted to extend both of them in the same way and wanted to make sure each new extended class would adhere to a set of rules about its structure. If you are not familiar with Interfaces, see this great post on jsedlak.org for an introduction about them.

So, let's start with the Interface code. It's a pretty simple Interface, not much going on. Remember, we are only extending the GameComponent class to add 3 things: a way to keep track of the previous Enabled state, an EventHandler for Game.Activated, and an EventHandler for Game.Deactivated. Ideally, by using an Interface, I leave the ability to easily add other features later if needed and still make sure that my new extended classes adhere to a structure.
Show Plain Text
Show Line #
Alternating Lines
Hide Comments
  1. using System;
  2.   
  3. namespace TehOne.Xna.GameComponents
  4. {
  5.     /// <summary>
  6.     /// This <c>interface</c> is used to help extend the base <see cref="Microsoft.Xna.Framework.GameComponent"/> object.
  7.     /// <para>We add the <see cref="PreviouslyEnabled"/> field and an <see cref="System.EventHandler"/> method for handling the <see cref="Microsoft.Xna.Framework.GameComponent.EnabledChanged"/> event.</para>
  8.     /// </summary>
  9.     public interface IXnaGameComponent
  10.     {
  11.         /// <summary>
  12.         /// The PreviouslyEnabled property represents the previous value of <see cref="Microsoft.Xna.Framework.GameComponent.Enabled"/> for this <see cref="IXnaGameComponent"/>.
  13.         /// </summary>
  14.         bool PreviouslyEnabled
  15.         {
  16.             get;
  17.             set;
  18.         }
  19.   
  20.         /// <summary>
  21.         /// This method is the <see cref="System.EventHandler"/> for the <see cref="Microsoft.Xna.Framework.Game.Activated"/> event.
  22.         /// </summary>
  23.         /// <param name="sender">The <see cref="System.Object"/> that called this event.</param>
  24.         /// <param name="e">The arguments that were passed into this event.</param>
  25.         void Game_Activated(object sender, EventArgs args);
  26.   
  27.         /// <summary>
  28.         /// This method is the <see cref="System.EventHandler"/> for the <see cref="Microsoft.Xna.Framework.Game.Deactivated"/> event.
  29.         /// </summary>
  30.         /// <param name="sender">The <see cref="System.Object"/> that called this event.</param>
  31.         /// <param name="e">The arguments that were passed into this event.</param>
  32.         void Game_Deactivated(object sender, EventArgs args);
  33.     }
  34. }


Ok, so from here, we need to create 2 classes that implement the Interface we just created and extend a base class from the XNA framework. One that extends GameComponent and one that extends DrawableGameComponent. The 2 new classes are basically exactly the same. The only difference is the base class which they extend.

Show Plain Text
Show Line #
Alternating Lines
Hide Comments
  1. using System;
  2. using Microsoft.Xna.Framework;
  3.   
  4. namespace TehOne.Xna.GameComponents
  5. {
  6.     /// <summary>
  7.     /// This <c>partial class</c> is used to extend the base <see cref="Microsoft.Xna.Framework.DrawableGameComponent"/> object.
  8.     /// <para>Implements the members of <see cref="IXnaGameComponent"/>.</para>
  9.     /// </summary>
  10.     public partial class XnaDrawableGameComponent : Microsoft.Xna.Framework.DrawableGameComponent, IXnaGameComponent
  11.     {
  12.         private bool _previouslyEnabled = true;
  13.   
  14.         /// <summary>
  15.         /// The PreviouslyEnabled property represents the previous value of <see cref="Microsoft.Xna.Framework.GameComponent.Enabled"/> for this <see cref="Microsoft.Xna.Framework.GameComponent"/>.
  16.         /// </summary>
  17.         /// <value>The PreviouslyEnabled property gets/sets the <see cref="_previouslyEnabled"/> data member.</value>
  18.         /// <remarks>The value of the <see cref="_previouslyEnabled"/> data member is set when the <see cref="OnEnabledChange(object, EventArgs)"/> event is fired.</remarks>
  19.         public bool PreviouslyEnabled
  20.         {
  21.             get
  22.             {
  23.                 return _previouslyEnabled;
  24.             }
  25.             set
  26.             {
  27.                 _previouslyEnabled = value;
  28.             }
  29.         }
  30.   
  31.         /// <summary>
  32.         /// The main constructor for <see cref="XnaDrawableGameComponent" />
  33.         /// </summary>
  34.         /// <param name="game">The <see cref="Microsoft.Xna.Framework.Game" /> instance.</param>
  35.         public XnaDrawableGameComponent(Game game)
  36.             : base(game)
  37.         {
  38.             game.Activated += new EventHandler(Game_Activated);
  39.             game.Deactivated += new EventHandler(Game_Deactivated);
  40.         }
  41.   
  42.         /// <summary>
  43.         /// This method is the <see cref="System.EventHandler"/> for the <see cref="Microsoft.Xna.Framework.Game.Activated"/> event.
  44.         /// </summary>
  45.         /// <param name="sender">The <see cref="System.Object"/> that called this event.</param>
  46.         /// <param name="e">The arguments that were passed into this event.</param>
  47.         /// <remarks>When this <see cref="System.EventHandler"/> is fired, we set our <see cref="Microsoft.Xna.Framework.GameComponent.Enabled"/> value to be the value of the <see cref="_previouslyEnabled"/> data member.</remarks>
  48.         public void Game_Activated(object sender, EventArgs e)
  49.         {
  50.             this.Enabled = _previouslyEnabled;
  51.         }
  52.   
  53.         /// <summary>
  54.         /// This method is the <see cref="System.EventHandler"/> for the <see cref="Microsoft.Xna.Framework.Game.Deactivated"/> event.
  55.         /// </summary>
  56.         /// <param name="sender">The <see cref="System.Object"/> that called this event.</param>
  57.         /// <param name="e">The arguments that were passed into this event.</param>
  58.         /// <remarks>When this <see cref="System.EventHandler"/> is fired, we set our <see cref="_previouslyEnabled"/> data member value to be the value of <see cref="Microsoft.Xna.Framework.GameComponent.Enabled"/>. Then, we set our <see cref="Microsoft.Xna.Framework.GameComponent.Enabled"/> state to <b><c>false</c></b>.</remarks>
  59.         public void Game_Deactivated(object sender, EventArgs e)
  60.         {
  61.             _previouslyEnabled = this.Enabled;
  62.             this.Enabled = false;
  63.         }
  64.   
  65.         /// <summary>
  66.         /// Allows the game component to perform any initialization it needs to before starting
  67.         /// to run.  This is where it can query for any required services and load content.
  68.         /// </summary>
  69.         public override void Initialize()
  70.         {
  71.             _previouslyEnabled = this.Enabled;
  72.   
  73.             base.Initialize();
  74.         }
  75.     }
  76. }


Ok, so that is all we need. Now, when we create a custom GameComponent or DrawableGameComponent we will just have it extend from one of these 2 new classes. As an example:
Show Plain Text
Show Line #
Alternating Lines
Hide Comments
  1. public partial class Framerate : XnaDrawableGameComponent


That's all there is too it. Now any GameComponent that use XnaGameComponent as it's base class, or any DrawableGameComponent that use XnaDrawableGameComponent as it's base class, will automatically be disabled when the Game is Deactivated and they will re-enable (if they were enabled before the Deactivate) themselves when the Game is Activated.


I hope this code proves usefull for others. Any comments/suggestions/feedback?
Read more!