Particles.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // Particles.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.Generic;
  12. using System.Text;
  13. using Microsoft.Xna.Framework;
  14. using Microsoft.Xna.Framework.Graphics;
  15. #endregion
  16. namespace Spacewar
  17. {
  18. /// <summary>
  19. /// A class that represents a group of particles
  20. /// </summary>
  21. public class Particles : SceneItem
  22. {
  23. private static string particleTexture = @"textures\circle";
  24. private static Random random = new Random();
  25. private static SpriteBatch batch;
  26. public Particles(Game game)
  27. : base(game)
  28. {
  29. if (game != null)
  30. {
  31. IGraphicsDeviceService graphicsService = (IGraphicsDeviceService)game.Services.GetService(typeof(IGraphicsDeviceService));
  32. batch = new SpriteBatch(graphicsService.GraphicsDevice);
  33. }
  34. }
  35. /// <summary>
  36. /// Draws the particles in a batch
  37. /// </summary>
  38. public override void Render()
  39. {
  40. if (Count != 0)
  41. {
  42. IGraphicsDeviceService graphicsService = (IGraphicsDeviceService)GameInstance.Services.GetService(typeof(IGraphicsDeviceService));
  43. GraphicsDevice device = graphicsService.GraphicsDevice;
  44. batch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearClamp,
  45. DepthStencilState.None, RasterizerState.CullCounterClockwise);
  46. int particleCount = 0;
  47. foreach (SceneItem particle in this)
  48. {
  49. if (particle is Particle)
  50. {
  51. batch.Draw(SpacewarGame.ContentManager.Load<Texture2D>(SpacewarGame.Settings.MediaPath + particleTexture),
  52. new Vector2(particle.Position.X, particle.Position.Y),
  53. null, new Color(((Particle)particle).Color), 0,
  54. new Vector2(16, 16), .2f,
  55. SpriteEffects.None, particle.Position.Z);
  56. particleCount++;
  57. }
  58. }
  59. batch.End();
  60. //We DON'T need to call base class here. We are handling batching all the children ourselves
  61. //base.Render();
  62. }
  63. }
  64. /// <summary>
  65. /// Adds particles to represent vapour trail
  66. /// </summary>
  67. /// <param name="world">Start position of the particle</param>
  68. /// <param name="direction">Direction the ship is heading. Particles will be lined up along this vec</param>
  69. public void AddShipTrail(Matrix world, Vector2 direction)
  70. {
  71. //Move source point into screen space
  72. Vector4 source = Vector4.Transform(new Vector4(0, 0, 130000, 1), world * SpacewarGame.Camera.View * SpacewarGame.Camera.Projection);
  73. //and into pixels
  74. Vector2 source2D = new Vector2((int)((source.X / source.W + 1f) / 2f * 1280), (int)((-source.Y / source.W + 1f) / 2f * 720));
  75. direction = Vector2.Normalize(direction);
  76. for (int i = 0; i < 70; i++)
  77. {
  78. float trailDistance = random.Next(50);
  79. float trailOffset = random.Next(21) - 10;
  80. Add(new Particle(this.GameInstance,
  81. new Vector2(source2D.X + trailDistance * direction.X + trailOffset * direction.Y, source2D.Y + trailDistance * direction.Y + trailOffset * direction.X),
  82. new Vector2(trailDistance * trailOffset * direction.Y / 5, trailDistance * trailOffset * direction.X / 5),
  83. new Vector4(1f, 1f, .5f, .5f),
  84. new Vector4(.2f, .2f, 0f, .2f),
  85. new TimeSpan(0, 0, 2)));
  86. }
  87. }
  88. /// <summary>
  89. /// Adds particles to represent vapour trail
  90. /// </summary>
  91. /// <param name="world">Start position of the particle</param>
  92. /// <param name="direction">Direction the rocket is heading. Particles will be lined up along this vec</param>
  93. public void AddRocketTrail(Matrix world, Vector2 direction)
  94. {
  95. //Move source point into screen space
  96. Vector4 source = Vector4.Transform(new Vector4(0, 0, 291, 1), world * SpacewarGame.Camera.View * SpacewarGame.Camera.Projection);
  97. //and into pixels
  98. Vector2 source2D = new Vector2((int)((source.X / source.W + 1f) / 2f * 1280), (int)((-source.Y / source.W + 1f) / 2f * 720));
  99. direction = Vector2.Normalize(direction);
  100. for (int i = 0; i < 20; i++)
  101. {
  102. float trailDistance = random.Next(50);
  103. Add(new Particle(this.GameInstance,
  104. new Vector2(source2D.X, source2D.Y) + trailDistance * -direction,
  105. -direction,
  106. new Vector4(1f, 1f, .5f, .5f),
  107. new Vector4(.2f, .2f, 0f, .2f),
  108. new TimeSpan(0, 0, 1)));
  109. }
  110. }
  111. /// <summary>
  112. /// Adds particles that look like an explosion
  113. /// </summary>
  114. /// <param name="position"></param>
  115. public void AddExplosion(Vector3 position)
  116. {
  117. //Move source point into screen space
  118. Vector4 source = Vector4.Transform(position, SpacewarGame.Camera.View * SpacewarGame.Camera.Projection);
  119. //and into pixels
  120. Vector2 source2D = new Vector2((int)((source.X / source.W + 1f) / 2f * 1280), (int)((-source.Y / source.W + 1f) / 2f * 720));
  121. for (int i = 0; i < 300; i++)
  122. {
  123. Vector2 velocity = (float)random.Next(100) * Vector2.Normalize(new Vector2((float)(random.NextDouble() - .5), (float)(random.NextDouble() - .5)));
  124. Add(new Particle(this.GameInstance,
  125. new Vector2(source2D.X, source2D.Y),
  126. velocity,
  127. (i > 70) ? new Vector4(1.0f, 0f, 0f, 1) : new Vector4(.941f, .845f, 0f, 1),
  128. new Vector4(.2f, .2f, .2f, 0f),
  129. new TimeSpan(0, 0, 0, 0, random.Next(1000) + 500)));
  130. }
  131. }
  132. public override void OnCreateDevice()
  133. {
  134. IGraphicsDeviceService graphicsService = (IGraphicsDeviceService)GameInstance.Services.GetService(typeof(IGraphicsDeviceService));
  135. batch = new SpriteBatch(graphicsService.GraphicsDevice);
  136. }
  137. }
  138. }