ParticleEffect.cs 6.8 KB

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