Particles Particles Many game applications have the need to display many similar "particles" at the same time. Some examples are smoke, dust, rain, snow, explosions, etc. We are going to use classes to build a "particle engine". A particle engine is something that creates and manages particles. We will need two classes: a Particle class and a ParticleEngine class. A Particle class What are the characteristics of a particle? It has a texture, a position, a velocity, an angle, an angular velocity, a color, and a size. Also, particles eventually disappear, so we need to keep track of how long they have to live. Create a new class called Particle. Add the appropriate using statements at the beginning. using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework; Properties Then add the following private variables. private private private private private private private private Texture2D texture; Vector2 position; Vector2 velocity; float angle; float angularVelocity; Color color; float size; int timeToLive; The timeToLive variable is the only one that needs to be accessed from the outside, so it's the only one that needs a pair of get/set property procedures. public int TimeToLive { get {return timeToLive;} set {timeToLive = value;} } A Constructor Add the following constructor: public Particle(Texture2D texture, Vector2 position, Vector2 velocity, float angle, float angularVelocity, 2/7/2016 Document1 Page 1 of 5 Color color, float size, int timeToLive) { this.texture = texture; this.position = position; this.velocity = velocity; this.angle = angle; this.angularVelocity = angularVelocity; this.color = color; this.size = size; this.timeToLive = timeToLive; } Update A particle needs to be able to update itself. public void Update() { timeToLive--; position += velocity; angle += angularVelocity; } Draw A particle needs to be able to draw itself. public void Draw(SpriteBatch spriteBatch) { Rectangle sourceRectangle = new Rectangle(0, 0, texture.Width, texture.Height); Vector2 origin = new Vector2(texture.Width / 2, texture.Height / 2); spriteBatch.Draw(texture, position, sourceRectangle, color, angle, origin, size, SpriteEffects.None, 0f); } That's it! That's our particle! The ParticleEngine class What does a particle engine need to be able to do? 1. 2. 3. 4. 5. It It It It It needs needs needs needs needs to to to to to be be be be be able able able able able to to to to to keep track of where the particles are coming from. keep track of all of its particles. create new particles. update itself. draw itself. Create a new class called ParticleEngine. Add the appropriate using statements at the beginning. using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework; 2/7/2016 Document1 Page 2 of 5 Private variables private Random random; public Vector2 EmitterLocation { get; set; } private List<Particle> particles; private List<Texture2D> textures; Constructor public ParticleEngine(List<Texture2D> textures, Vector2 location) { EmitterLocation = location; this.textures = textures; this.particles = new List<Particle>(); random = new Random(); } Create Particles A particle engine needs to be able to create particles. private Particle GenerateNewParticle() { // Pick a random texture Texture2D texture = textures[random.Next(textures.Count)]; Vector2 position = EmitterLocation; // Pick a random velocity Vector2 velocity = new Vector2( 1f * (float)(random.NextDouble() * 2 - 1), 1f * (float)(random.NextDouble() * 2 - 1)); // Start rightside up float angle = 0; // Set random rotation speed float angularVelocity = 0.1f * (float)(random.NextDouble() * 2 1); // Set a random color Color color = new Color( (float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()); // Set a random size float size = (float)random.NextDouble(); // Set a random time to live from 20 to 60 ticks int timeToLive = 20 + random.Next(40); return new Particle(texture, position, velocity, angle, 2/7/2016 Document1 Page 3 of 5 angularVelocity, color, size, timeToLive); } Update A particle engine needs to be able to update itself. It will add new particles on every tick, and it will update each particle that is already on its list. public void Update() { int total = 10; // Add 10 new particles per tick for (int i = 0; i < total; i++) { particles.Add(GenerateNewParticle()); } // Go through the entire list of particles and update // each particle's position, rotation, and time to live. for (int particle = particles.Count -1; particle >= 0; particle--) { particles[particle].Update(); if (particles[particle].TimeToLive <= 0) { particles.RemoveAt(particle); } } } Draw A particle engine needs to be able to draw itself. public void Draw(SpriteBatch spriteBatch) { for (int index = 0; index < particles.Count; index++) { particles[index].Draw(spriteBatch); } } Using the particle engine Create the particle engine Once you create the engine, it's easy to use. Add the following to your main program: ParticleEngine particleEngine; 2/7/2016 Document1 Page 4 of 5 Load the particles List<Texture2D> textures = new List<Texture2D>(); //textures.Add(Content.Load<Texture2D>("smoke")); textures.Add(Content.Load<Texture2D>("circle")); textures.Add(Content.Load<Texture2D>("star")); textures.Add(Content.Load<Texture2D>("diamond")); particleEngine = new ParticleEngine(textures, new Vector2(400, 240)); Update the engine's location and update the engine itself particleEngine.EmitterLocation = new Vector2(Mouse.GetState().X, Mouse.GetState().Y); particleEngine.Update(); Draw the engine particleEngine.Draw(spriteBatch); 2/7/2016 Document1 Page 5 of 5