예제 #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;
        }
예제 #2
0
        /// <summary>
        /// When overridden in the derived class, handles processing the <paramref name="particle"/> when
        /// it is updated. Only valid if <see cref="ParticleModifier.ProcessOnUpdate"/> is set.
        /// </summary>
        /// <param name="emitter">The <see cref="ParticleEmitter"/> that the <paramref name="particle"/>
        /// came from.</param>
        /// <param name="particle">The <see cref="Particle"/> to process.</param>
        /// <param name="elapsedTime">The amount of time that has elapsed since the <paramref name="emitter"/>
        /// was last updated.</param>
        protected override void HandleProcessUpdated(ParticleEmitter emitter, Particle particle, int elapsedTime)
        {
            var agePercent = particle.GetAgePercent(CurrentTime);

            if (AllBitsSet())
            {
                particle.Color = ReleaseColor.Lerp(UltimateColor, agePercent);
            }
            else
            {
                byte r, g, b, a;

                if (ModifyRed)
                {
                    r = (byte)MathHelper.Lerp(ReleaseColor.R, UltimateColor.R, agePercent);
                }
                else
                {
                    r = particle.Color.R;
                }

                if (ModifyGreen)
                {
                    g = (byte)MathHelper.Lerp(ReleaseColor.G, UltimateColor.G, agePercent);
                }
                else
                {
                    g = particle.Color.G;
                }

                if (ModifyBlue)
                {
                    b = (byte)MathHelper.Lerp(ReleaseColor.B, UltimateColor.B, agePercent);
                }
                else
                {
                    b = particle.Color.B;
                }

                if (ModifyAlpha)
                {
                    a = (byte)MathHelper.Lerp(ReleaseColor.A, UltimateColor.A, agePercent);
                }
                else
                {
                    a = particle.Color.A;
                }

                particle.Color = new Color(r, g, b, a);
            }
        }