/// <summary> /// PickRandomDirection is used by AddParticle to decide which direction /// particles will move. /// </summary> private Vector2 PickRandomDirection() { float angle = ParticleHelpers.RandomBetween(settings.MinDirectionAngle, settings.MaxDirectionAngle); // our settings angles are in degrees, so we must convert to radians angle = MathHelper.ToRadians(angle); 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) { // set the values to the requested values 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 = ParticleHelpers.RandomBetween(0, MathHelper.TwoPi); }
// 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. private void UpdateExplosions(float dt) { timeTillExplosion -= dt; if (timeTillExplosion < 0) { Vector2 where = Vector2.Zero; // create the explosion at some random point on the screen. where.X = ParticleHelpers.RandomBetween(0, graphics.GraphicsDevice.Viewport.Width); where.Y = ParticleHelpers.RandomBetween(0, graphics.GraphicsDevice.Viewport.Height); // 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, Vector2.Zero); smoke.AddParticles(where, Vector2.Zero); // reset the timer. timeTillExplosion = TimeBetweenExplosions; } }
/// <summary> /// InitializeParticle randomizes some properties for a particle, then /// calls initialize on it. It 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. /// </summary> /// <param name="p">the particle to initialize</param> /// <param name="where">the position on the screen that the particle should be /// </param> /// <param name="velocity">The base velocity that the particle should have</param> private void InitializeParticle(Particle p, Vector2 where, Vector2 velocity) { // Adjust the input velocity based on how much // this particle system wants to be affected by it. velocity *= settings.EmitterVelocitySensitivity; // Adjust the velocity based on our random values Vector2 direction = PickRandomDirection(); float speed = ParticleHelpers.RandomBetween(settings.MinInitialSpeed, settings.MaxInitialSpeed); velocity += direction * speed; // pick some random values for our particle float lifetime = ParticleHelpers.RandomBetween(settings.MinLifetime, settings.MaxLifetime); float scale = ParticleHelpers.RandomBetween(settings.MinSize, settings.MaxSize); float rotationSpeed = ParticleHelpers.RandomBetween(settings.MinRotationSpeed, settings.MaxRotationSpeed); // our settings angles are in degrees, so we must convert to radians rotationSpeed = MathHelper.ToRadians(rotationSpeed); // figure out our acceleration base on our AccelerationMode Vector2 acceleration = Vector2.Zero; switch (settings.AccelerationMode) { case AccelerationMode.Scalar: // randomly pick our acceleration using our direction and // the MinAcceleration/MaxAcceleration values float accelerationScale = ParticleHelpers.RandomBetween( settings.MinAccelerationScale, settings.MaxAccelerationScale); acceleration = direction * accelerationScale; break; case AccelerationMode.EndVelocity: // Compute our acceleration based on our ending velocity from the settings. // We'll use the equation vt = v0 + (a0 * t). (If you're not familar with // this, it's one of the basic kinematics equations for constant // acceleration, and basically says: // velocity at time t = initial velocity + acceleration * t) // We're solving for a0 by substituting t for our lifetime, v0 for our // velocity, and vt as velocity * settings.EndVelocity. acceleration = (velocity * (settings.EndVelocity - 1)) / lifetime; break; case AccelerationMode.Vector: acceleration = new Vector2( ParticleHelpers.RandomBetween(settings.MinAccelerationVector.X, settings.MaxAccelerationVector.X), ParticleHelpers.RandomBetween(settings.MinAccelerationVector.Y, settings.MaxAccelerationVector.Y)); break; default: break; } // then initialize it with those random values. initialize will save those, // and make sure it is marked as active. p.Initialize( where, velocity, acceleration, lifetime, scale, rotationSpeed); }