ParticleEffect.cs 6.7 KB

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