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