Esempio n. 1
0
        /// <summary>
        /// Releases one or more particles.
        /// </summary>
        /// <param name="currentTime">The current time.</param>
        /// <param name="amount">The number of particles to release.</param>
        void ReleaseParticles(TickCount currentTime, int amount)
        {
            // Find how many we can actually release
            var lastIndex = Math.Min(Budget - 1, _lastAliveIndex + amount);

            // Ensure our particles array is large enough to fit the new particles.
            // When we resize the array, we use the "next power of two" sizing concept to reduce the
            // memory fragmentation (.NET internally does the same with most collections). To speed things up,
            // we just find the next power of two instead of looping until we have a large enough value.
            if (_particles.Length - 1 < lastIndex)
            {
                var newSize = BitOps.NextPowerOf2(lastIndex + 1);
                Debug.Assert(BitOps.IsPowerOf2(newSize),
                             "If this assert fails, something is probably wrong with BitOps.NextPowerOf2() or BitOps.IsPowerOf2().");
                Debug.Assert(newSize >= lastIndex + 1);
                Array.Resize(ref _particles, newSize);
            }

            // Start releasing the particles
            var hasReleaseModifiers = ParticleModifiers.HasReleaseModifiers;

            for (var i = _lastAliveIndex + 1; i <= lastIndex; i++)
            {
                var particle = _particles[i];
                if (particle == null)
                {
                    particle      = Particle.Create();
                    _particles[i] = particle;
                }

                // Set up the particle
                particle.Momentum  = Vector2.Zero;
                particle.LifeStart = currentTime;
                particle.LifeEnd   = (TickCount)(currentTime + ParticleLife.GetNext());
                particle.Rotation  = ReleaseRotation.GetNext();
                particle.Scale     = ReleaseScale.GetNext();
                ReleaseColor.GetNext(ref particle.Color);

                // Get the offset and force
                Vector2 offset;
                Vector2 force;
                GenerateParticleOffsetAndForce(particle, out offset, out force);

                // Set the position
                Vector2.Add(ref _origin, ref offset, out particle.Position);

                // Set the velocity
                Vector2.Multiply(ref force, ReleaseSpeed.GetNext(), out particle.Velocity);

                if (hasReleaseModifiers)
                {
                    ParticleModifiers.ProcessReleasedParticle(this, particle);
                }
            }

            // Increase the index of the last active particle
            _lastAliveIndex = lastIndex;
        }