// PickRandomDirection is used by InitializeParticles to decide which direction // particles will move. The default implementation is a random vector on a circle. protected virtual Vector2 PickRandomDirection() { float angle = Utils.RandomBetween(0, (float)Math.PI * 2); return(new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle))); }
// This function is called when we want to demo the explosion effect. It updates the // timeTillExplosion timer, and starts another explosion effect when the timer reaches zero. void CreateExplosions(float elapsedTime) { timeTillExplosion -= elapsedTime; while (timeTillExplosion < 0) { Vector2 where = canvas.Size.ToVector2(); // Create the explosion at some random point on the screen. if (ThumbnailGenerator.IsDrawingThumbnail) { where /= 2; } else { where.X *= Utils.RandomBetween(0.25f, 0.75f); where.Y *= Utils.RandomBetween(0.25f, 0.75f); } // The overall explosion effect is actually comprised of two particle systems: // the fiery bit, and the smoke behind it. Add particles to both of those systems. explosion.AddParticles(where); smoke.AddParticles(where); // Reset the timer. timeTillExplosion += TimeBetweenExplosions; } }
// InitializeParticle is overridden to add the appearance of wind. protected override void InitializeParticle(Particle particle, Vector2 where) { base.InitializeParticle(particle, where); // The base is mostly good, but we want to simulate a little bit of wind heading to the right. particle.Acceleration.X += Utils.RandomBetween(10, 50); }
// PickRandomDirection is overriden so we can make the particles always have an initial velocity pointing up. protected override Vector2 PickRandomDirection() { // Point the particles somewhere between 80 and 100 degrees. // Tweak this to make the smoke have more or less spread. float angle = Utils.RandomBetween(Utils.DegreesToRadians(80), Utils.DegreesToRadians(100)); // From the unit circle, cosine is the x coordinate and sine is the y coordinate. // We're negating y because on the screen increasing y moves down the display. return(new Vector2((float)Math.Cos(angle), -(float)Math.Sin(angle))); }
// Initialize is called by ParticleSystem to set up the particle, and prepares the particle for use. public void Initialize(Vector2 position, Vector2 velocity, Vector2 acceleration, float lifetime, float scale, float rotationSpeed) { this.Position = position; this.Velocity = velocity; this.Acceleration = acceleration; this.Lifetime = lifetime; this.Scale = scale; this.RotationSpeed = rotationSpeed; // Reset TimeSinceStart - we have to do this because particles will be reused. this.TimeSinceStart = 0.0f; // Set rotation to some random value between 0 and 360 degrees. this.Rotation = Utils.RandomBetween(0, (float)Math.PI * 2); }
// Randomizes some properties for a particle, then calls Initialize on it. // This can be overriden by subclasses if they want to modify the way particles // are created. For example, SmokePlumeParticleSystem overrides this function // make all particles accelerate to the right, simulating wind. protected virtual void InitializeParticle(Particle particle, Vector2 where) { // First, call PickRandomDirection to figure out which way the particle // will be moving. Velocity and acceleration values will come from this. Vector2 direction = PickRandomDirection(); // Pick some random values for our particle. float velocity = Utils.RandomBetween(minInitialSpeed, maxInitialSpeed); float acceleration = Utils.RandomBetween(minAcceleration, maxAcceleration); float lifetime = Utils.RandomBetween(minLifetime, maxLifetime); float scale = Utils.RandomBetween(minScale, maxScale); float rotationSpeed = Utils.RandomBetween(minRotationSpeed, maxRotationSpeed); // Then initialize the particle with these random values. particle.Initialize(where, velocity * direction, acceleration * direction, lifetime, scale, rotationSpeed); }