#region File Description //----------------------------------------------------------------------------- // ParticleEffect.cs // // Microsoft XNA Community Game Platform // Copyright (C) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- #endregion #region Using Statements using System; using System.Collections.ObjectModel; using System.IO; using System.Xml.Serialization; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Content; #endregion namespace NetRumble { /// /// A multi-emitter particle effect, comprised of multiple particle systems. /// public class ParticleEffect { #region Description Data /// /// The name of the particle effect. /// private string name; /// /// The particle systems in this effect. /// private Collection particleSystems = new Collection(); #endregion #region Graphics Data /// /// The position of the particle effect in the world. /// private Vector2 position; /// /// The gameplay object that the system is following, if any. /// private GameplayObject followObject; [XmlIgnore()] public GameplayObject GameplayObject { get { return followObject; } set { followObject = value; } } #endregion #region Status Data /// /// If true, the particle effect is currently active. /// private bool active = false; [XmlIgnore()] public bool Active { get { return active; } } #endregion #region Initialization Methods /// /// Create a new particle effect. /// public ParticleEffect() { } /// /// Create a new particle effect that is a clone of another one. /// /// public ParticleEffect Clone() { ParticleEffect clone = new ParticleEffect(); // copy the data clone.name = this.name; clone.position = this.position; // copy each system for (int i = 0; i < this.particleSystems.Count; ++i) { clone.ParticleSystems.Add(this.particleSystems[i].Clone()); } return clone; } /// /// Initialize the particle effect. /// /// The contenet manager that owns the texture. public virtual void Initialize(ContentManager content) { // initialize each system for (int i = 0; i < particleSystems.Count; ++i) { particleSystems[i].Initialize(content); } // allow us to start updating and drawing active = true; } /// /// Reset the particle effect. /// public virtual void Reset() { // reset each system for (int i = 0; i < particleSystems.Count; ++i) { particleSystems[i].Reset(); } // allow us to start updating and drawing active = true; } #endregion #region Updating Methods /// /// Update the particle effect. /// /// The amount of elapsed time, in seconds. public virtual void Update(float elapsedTime) { // update the position based on the follow-object, if any if (followObject != null) { if (followObject.Active) { Position = followObject.Position; } else { followObject = null; Stop(false); } } // update each system active = false; for (int i = 0; i < particleSystems.Count; ++i) { if (particleSystems[i].Active) { particleSystems[i].Update(elapsedTime); active = true; } } } #endregion #region Drawing Methods /// /// Draw the particle effect. /// /// The SpriteBatch object used to draw. /// Filters the systems drawn in this pass. public virtual void Draw(SpriteBatch spriteBatch, SpriteBlendMode blendMode) { if (!active) return; // draw each system for (int i = 0; i < particleSystems.Count; ++i) { if (particleSystems[i].BlendMode == blendMode) { particleSystems[i].Draw(spriteBatch); } } } #endregion #region Control Methods /// /// Stop the particle effect. /// /// /// If true, particles are no longer drawn or updated. /// Otherwise, only generation is halted. /// public void Stop(bool immediately) { // stop all of the systems for (int i = 0; i < particleSystems.Count; ++i) { particleSystems[i].Stop(immediately); } // halt updating/drawing of the particles if requested if (immediately) { active = false; } } #endregion #region Serialization Interface public string Name { get { return name; } set { name = value; } } public Vector2 Position { get { return position; } set { position = value; for (int i = 0; i < particleSystems.Count; ++i) { particleSystems[i].Position = position; } } } public Collection ParticleSystems { get { return particleSystems as Collection; } } #endregion #region Static Initialization Methods /// /// Create a new ParticleEffect object from the data in an XML file. /// /// The filename of the XML file. /// A new ParticleEffect object. public static ParticleEffect Load(string filepath) { XmlSerializer serializer = new XmlSerializer(typeof(ParticleEffect)); return (ParticleEffect)serializer.Deserialize(File.OpenRead(filepath)); } #endregion } }