protected override void InitializeParticle(Particle p, Vector2 where)
// The base works fine except for acceleration. Explosions move outwards,
// then slow down and stop because of air resistance. Let's change
// acceleration so that when the particle is at max lifetime, the velocity
// will be zero.
// 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'll solve the equation for a0, using t = p.Lifetime and vt = 0.
p.Acceleration = -p.Velocity / p.Lifetime;
/// 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.
/// <param name="p">the particle to initialize</param>
/// <param name="where">the position on the screen that the particle should be
protected virtual void InitializeParticle(Particle p, Vector2 where)
// first, call PickRandomDirection to figure out which way the particle
// will be moving. velocity and acceleration's values will come from this.
direction = PickRandomDirection();
// pick some random values for our particle
float velocity =
float acceleration =
float lifetime =
float scale =
float rotationSpeed =
// then initialize it with those random values. initialize will save those,
// and make sure it is marked as active.
where, velocity * direction, acceleration * direction,
lifetime, scale, rotationSpeed);
/// override the base class's Initialize to do some additional work; we want to
/// call InitializeConstants to let subclasses set the constants that we'll use.
/// also, the particle array and freeParticles queue are set up here.
public void Initialize()
// calculate the total number of particles we will ever need, using the
// max number of effects and the max number of particles per effect.
// once these particles are allocated, they will be reused, so that
// we don't put any pressure on the garbage collector.
particles = new Particle[howManyEffects * maxNumParticles];
freeParticles = new Queue<Particle>(howManyEffects * maxNumParticles);
for (int i = 0; i < particles.Length; i++)
particles[i] = new Particle();