#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 } }