#region File Description
//-----------------------------------------------------------------------------
// ParticleEffectManager.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using System;
using System.IO;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
#endregion
namespace NetRumble
{
public class ParticleEffectManager
{
#region Effect Collection Data
///
/// Cache of registered particle effects.
///
private Dictionary> particleEffectCache
= new Dictionary>();
///
/// Active particle effects.
///
private BatchRemovalCollection activeParticleEffects =
new BatchRemovalCollection();
#endregion
#region Graphics Data
///
/// The content manager used to load textures in the particle systems.
///
private ContentManager contentManager;
#endregion
#region Initialization Methods
///
/// Construct a new particle-effect manager.
///
public ParticleEffectManager(ContentManager contentManager)
{
// safety-check the parameters
if (contentManager == null)
{
throw new ArgumentNullException("contentManager");
}
this.contentManager = contentManager;
}
#endregion
#region Updating Methods
///
/// Update the particle-effect manager.
///
/// The amount of elapsed time, in seconds.
public void Update(float elapsedTime)
{
for (int i = 0; i < activeParticleEffects.Count; ++i)
{
if (activeParticleEffects[i].Active)
{
activeParticleEffects[i].Update(elapsedTime);
if (!activeParticleEffects[i].Active)
{
activeParticleEffects.QueuePendingRemoval(
activeParticleEffects[i]);
}
}
}
activeParticleEffects.ApplyPendingRemovals();
}
#endregion
#region Drawing Methods
///
/// Draw all of the particle effects in the manager.
///
/// The SpriteBatch object used to draw.
/// Filters the systems drawn in this pass.
public virtual void Draw(SpriteBatch spriteBatch, SpriteBlendMode blendMode)
{
for (int i = 0; i < activeParticleEffects.Count; ++i)
{
if (activeParticleEffects[i].Active)
{
activeParticleEffects[i].Draw(spriteBatch, blendMode);
}
}
}
#endregion
#region Particle-Effect Creation Methods
///
/// Spawn a new particle effect at a given location
///
/// The effect in question.
/// The position of the effect.
/// The new particle effect.
public ParticleEffect SpawnEffect(ParticleEffectType effectType,
Vector2 position)
{
return SpawnEffect(effectType, position, null);
}
///
/// Spawn a new particle effect at a the position of a given gameplay object
///
/// The effect in question.
/// The gameplay object.
/// The new particle effect.
public ParticleEffect SpawnEffect(ParticleEffectType effectType,
GameplayObject gameplayObject)
{
// safety-check the parameter
if (gameplayObject == null)
{
throw new ArgumentNullException("gameplayObject");
}
return SpawnEffect(effectType, gameplayObject.Position, gameplayObject);
}
///
/// Spawn a new particle effect at a given location and gameplay object
///
/// The effect in question.
/// The position of the effect.
/// The gameplay object.
/// The new particle effect.
public ParticleEffect SpawnEffect(ParticleEffectType effectType,
Vector2 position, GameplayObject gameplayObject)
{
ParticleEffect particleEffect = null;
if (particleEffectCache.ContainsKey(effectType) == true)
{
List availableSystems = particleEffectCache[effectType];
for (int i = 0; i < availableSystems.Count; ++i)
{
if (availableSystems[i].Active == false)
{
particleEffect = availableSystems[i];
break;
}
}
if (particleEffect == null)
{
particleEffect = availableSystems[0].Clone();
particleEffect.Initialize(contentManager);
availableSystems.Add(particleEffect);
}
}
if (particleEffect != null)
{
particleEffect.Reset();
particleEffect.GameplayObject = gameplayObject;
particleEffect.Position = position;
activeParticleEffects.Add(particleEffect);
}
return particleEffect;
}
#endregion
#region Registration Methods
///
/// Register a new type of particle effect with the manager.
///
/// The enumeration associated with this type.
/// The path to the XML file to be deserialized.
/// How many of these to pre-create.
public void RegisterParticleEffect(ParticleEffectType effectType,
string filename, int initialCount)
{
if (!particleEffectCache.ContainsKey(effectType))
{
string filepath = Path.Combine(contentManager.RootDirectory, filename);
ParticleEffect particleEffect = ParticleEffect.Load(filepath);
particleEffect.Initialize(contentManager);
particleEffect.Stop(true);
particleEffectCache.Add(effectType, new List());
particleEffectCache[effectType].Add(particleEffect);
for (int i = 1; i < initialCount; i++)
{
ParticleEffect cloneEffect = particleEffect.Clone();
cloneEffect.Initialize(contentManager);
cloneEffect.Stop(true);
particleEffectCache[effectType].Add(cloneEffect);
}
}
}
///
/// Remove the given particle-effect type from the maanger.
///
/// The enumeration to be cleared against.
public void UnregisterParticleEffect(ParticleEffectType effectType)
{
if (particleEffectCache.ContainsKey(effectType) == true)
{
for (int i = 0; i < particleEffectCache[effectType].Count; ++i)
{
activeParticleEffects.Remove(particleEffectCache[effectType][i]);
}
particleEffectCache.Remove(effectType);
}
}
#endregion
}
}