ParticleEffect.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // ParticleEffect.cs
  4. //
  5. // Microsoft XNA Community Game Platform
  6. // Copyright (C) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #endregion
  9. #region Using Statements
  10. using System;
  11. using System.Collections.ObjectModel;
  12. using System.IO;
  13. using System.Xml.Serialization;
  14. using Microsoft.Xna.Framework;
  15. using Microsoft.Xna.Framework.Graphics;
  16. using Microsoft.Xna.Framework.Content;
  17. #endregion
  18. namespace NetRumble
  19. {
  20. /// <summary>
  21. /// A multi-emitter particle effect, comprised of multiple particle systems.
  22. /// </summary>
  23. public class ParticleEffect
  24. {
  25. #region Description Data
  26. /// <summary>
  27. /// The name of the particle effect.
  28. /// </summary>
  29. private string name;
  30. /// <summary>
  31. /// The particle systems in this effect.
  32. /// </summary>
  33. private Collection<ParticleSystem> particleSystems =
  34. new Collection<ParticleSystem>();
  35. #endregion
  36. #region Graphics Data
  37. /// <summary>
  38. /// The position of the particle effect in the world.
  39. /// </summary>
  40. private Vector2 position;
  41. /// <summary>
  42. /// The gameplay object that the system is following, if any.
  43. /// </summary>
  44. private GameplayObject followObject;
  45. [XmlIgnore()]
  46. public GameplayObject GameplayObject
  47. {
  48. get { return followObject; }
  49. set { followObject = value; }
  50. }
  51. #endregion
  52. #region Status Data
  53. /// <summary>
  54. /// If true, the particle effect is currently active.
  55. /// </summary>
  56. private bool active = false;
  57. [XmlIgnore()]
  58. public bool Active
  59. {
  60. get { return active; }
  61. }
  62. #endregion
  63. #region Initialization Methods
  64. /// <summary>
  65. /// Create a new particle effect.
  66. /// </summary>
  67. public ParticleEffect() { }
  68. /// <summary>
  69. /// Create a new particle effect that is a clone of another one.
  70. /// </summary>
  71. /// <returns></returns>
  72. public ParticleEffect Clone()
  73. {
  74. ParticleEffect clone = new ParticleEffect();
  75. // copy the data
  76. clone.name = this.name;
  77. clone.position = this.position;
  78. // copy each system
  79. for (int i = 0; i < this.particleSystems.Count; ++i)
  80. {
  81. clone.ParticleSystems.Add(this.particleSystems[i].Clone());
  82. }
  83. return clone;
  84. }
  85. /// <summary>
  86. /// Initialize the particle effect.
  87. /// </summary>
  88. /// <param name="content">The contenet manager that owns the texture.</param>
  89. public virtual void Initialize(ContentManager content)
  90. {
  91. // initialize each system
  92. for (int i = 0; i < particleSystems.Count; ++i)
  93. {
  94. particleSystems[i].Initialize(content);
  95. }
  96. // allow us to start updating and drawing
  97. active = true;
  98. }
  99. /// <summary>
  100. /// Reset the particle effect.
  101. /// </summary>
  102. public virtual void Reset()
  103. {
  104. // reset each system
  105. for (int i = 0; i < particleSystems.Count; ++i)
  106. {
  107. particleSystems[i].Reset();
  108. }
  109. // allow us to start updating and drawing
  110. active = true;
  111. }
  112. #endregion
  113. #region Updating Methods
  114. /// <summary>
  115. /// Update the particle effect.
  116. /// </summary>
  117. /// <param name="elapsedTime">The amount of elapsed time, in seconds.</param>
  118. public virtual void Update(float elapsedTime)
  119. {
  120. // update the position based on the follow-object, if any
  121. if (followObject != null)
  122. {
  123. if (followObject.Active)
  124. {
  125. Position = followObject.Position;
  126. }
  127. else
  128. {
  129. followObject = null;
  130. Stop(false);
  131. }
  132. }
  133. // update each system
  134. active = false;
  135. for (int i = 0; i < particleSystems.Count; ++i)
  136. {
  137. if (particleSystems[i].Active)
  138. {
  139. particleSystems[i].Update(elapsedTime);
  140. active = true;
  141. }
  142. }
  143. }
  144. #endregion
  145. #region Drawing Methods
  146. /// <summary>
  147. /// Draw the particle effect.
  148. /// </summary>
  149. /// <param name="spriteBatch">The SpriteBatch object used to draw.</param>
  150. /// <param name="blendMode">Filters the systems drawn in this pass.</param>
  151. public virtual void Draw(SpriteBatch spriteBatch, SpriteBlendMode blendMode)
  152. {
  153. if (!active)
  154. return;
  155. // draw each system
  156. for (int i = 0; i < particleSystems.Count; ++i)
  157. {
  158. if (particleSystems[i].BlendMode == blendMode)
  159. {
  160. particleSystems[i].Draw(spriteBatch);
  161. }
  162. }
  163. }
  164. #endregion
  165. #region Control Methods
  166. /// <summary>
  167. /// Stop the particle effect.
  168. /// </summary>
  169. /// <param name="immediately">
  170. /// If true, particles are no longer drawn or updated.
  171. /// Otherwise, only generation is halted.
  172. /// </param>
  173. public void Stop(bool immediately)
  174. {
  175. // stop all of the systems
  176. for (int i = 0; i < particleSystems.Count; ++i)
  177. {
  178. particleSystems[i].Stop(immediately);
  179. }
  180. // halt updating/drawing of the particles if requested
  181. if (immediately)
  182. {
  183. active = false;
  184. }
  185. }
  186. #endregion
  187. #region Serialization Interface
  188. public string Name
  189. {
  190. get { return name; }
  191. set { name = value; }
  192. }
  193. public Vector2 Position
  194. {
  195. get { return position; }
  196. set
  197. {
  198. position = value;
  199. for (int i = 0; i < particleSystems.Count; ++i)
  200. {
  201. particleSystems[i].Position = position;
  202. }
  203. }
  204. }
  205. public Collection<ParticleSystem> ParticleSystems
  206. {
  207. get { return particleSystems as Collection<ParticleSystem>; }
  208. }
  209. #endregion
  210. #region Static Initialization Methods
  211. /// <summary>
  212. /// Create a new ParticleEffect object from the data in an XML file.
  213. /// </summary>
  214. /// <param name="filepath">The filename of the XML file.</param>
  215. /// <returns>A new ParticleEffect object.</returns>
  216. public static ParticleEffect Load(string filepath)
  217. {
  218. XmlSerializer serializer = new XmlSerializer(typeof(ParticleEffect));
  219. return (ParticleEffect)serializer.Deserialize(File.OpenRead(filepath));
  220. }
  221. #endregion
  222. }
  223. }