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:
/*
* Copyright (c) 2007, Eric Lebetsamer (http://tehone.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies
* or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
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.
using System;
namespace TehOne.Xna.GameComponents
{
/// <summary>
/// This <c>interface</c> is used to help extend the base <see cref="Microsoft.Xna.Framework.GameComponent"/> object.
/// <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>
/// </summary>
public interface IXnaGameComponent
{
/// <summary>
/// The PreviouslyEnabled property represents the previous value of <see cref="Microsoft.Xna.Framework.GameComponent.Enabled"/> for this <see cref="IXnaGameComponent"/>.
/// </summary>
bool PreviouslyEnabled
{
get;
set;
}
/// <summary>
/// This method is the <see cref="System.EventHandler"/> for the <see cref="Microsoft.Xna.Framework.Game.Activated"/> event.
/// </summary>
/// <param name="sender">The <see cref="System.Object"/> that called this event.</param>
/// <param name="e">The arguments that were passed into this event.</param>
void Game_Activated(object sender, EventArgs args);
/// <summary>
/// This method is the <see cref="System.EventHandler"/> for the <see cref="Microsoft.Xna.Framework.Game.Deactivated"/> event.
/// </summary>
/// <param name="sender">The <see cref="System.Object"/> that called this event.</param>
/// <param name="e">The arguments that were passed into this event.</param>
void Game_Deactivated(object sender, EventArgs args);
}
}
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.
using System;
using Microsoft.Xna.Framework;
namespace TehOne.Xna.GameComponents
{
/// <summary>
/// This <c>partial class</c> is used to extend the base <see cref="Microsoft.Xna.Framework.DrawableGameComponent"/> object.
/// <para>Implements the members of <see cref="IXnaGameComponent"/>.</para>
/// </summary>
public partial class XnaDrawableGameComponent : Microsoft.Xna.Framework.DrawableGameComponent, IXnaGameComponent
{
private bool _previouslyEnabled = true;
/// <summary>
/// The PreviouslyEnabled property represents the previous value of <see cref="Microsoft.Xna.Framework.GameComponent.Enabled"/> for this <see cref="Microsoft.Xna.Framework.GameComponent"/>.
/// </summary>
/// <value>The PreviouslyEnabled property gets/sets the <see cref="_previouslyEnabled"/> data member.</value>
/// <remarks>The value of the <see cref="_previouslyEnabled"/> data member is set when the <see cref="OnEnabledChange(object, EventArgs)"/> event is fired.</remarks>
public bool PreviouslyEnabled
{
get
{
return _previouslyEnabled;
}
set
{
_previouslyEnabled = value;
}
}
/// <summary>
/// The main constructor for <see cref="XnaDrawableGameComponent" />
/// </summary>
/// <param name="game">The <see cref="Microsoft.Xna.Framework.Game" /> instance.</param>
public XnaDrawableGameComponent(Game game)
: base(game)
{
game.Activated += new EventHandler(Game_Activated);
game.Deactivated += new EventHandler(Game_Deactivated);
}
/// <summary>
/// This method is the <see cref="System.EventHandler"/> for the <see cref="Microsoft.Xna.Framework.Game.Activated"/> event.
/// </summary>
/// <param name="sender">The <see cref="System.Object"/> that called this event.</param>
/// <param name="e">The arguments that were passed into this event.</param>
/// <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>
public void Game_Activated(object sender, EventArgs e)
{
this.Enabled = _previouslyEnabled;
}
/// <summary>
/// This method is the <see cref="System.EventHandler"/> for the <see cref="Microsoft.Xna.Framework.Game.Deactivated"/> event.
/// </summary>
/// <param name="sender">The <see cref="System.Object"/> that called this event.</param>
/// <param name="e">The arguments that were passed into this event.</param>
/// <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>
public void Game_Deactivated(object sender, EventArgs e)
{
_previouslyEnabled = this.Enabled;
this.Enabled = false;
}
/// <summary>
/// Allows the game component to perform any initialization it needs to before starting
/// to run. This is where it can query for any required services and load content.
/// </summary>
public override void Initialize()
{
_previouslyEnabled = this.Enabled;
base.Initialize();
}
}
}
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:
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?
1 comments:
viagra soft tabs viagra cialis levitra viagra dosages viagra 100mg free sample pack of viagra buy viagra in canada viagra and cocaine viagra lawyer ohio viagra manufacturer viagra australia viagra cialis levitra viagra dosages free viagra without prescription buy viagra in canada
Post a Comment