/// <summary> /// Applies this modifiers effect to the given particle node. /// </summary> /// <param name="node">Node to apply effect to.</param> /// <param name="deltaTime">Time elapsed since last frame.</param> public abstract void Apply(ParticleNode node, float deltaTime);
/// <summary> /// Gets or sets if this modifier is active on the give node. /// </summary> /// <param name="node">Node to check activity against.</param> protected bool Active(ParticleNode node) { float percent = (100.0f / (float)node.LifeTime) * (float)node.ExpiredLife; return (percent >= _effectDuration.Start && percent <= _effectDuration.Finish); }
/// <summary> /// Applies this modifiers effect to the given particle node. /// </summary> /// <param name="node">Node to apply effect to.</param> /// <param name="deltaTime">Time elapsed since last frame.</param> public override void Apply(ParticleNode node, float deltaTime) { // Check that we are active on this particle. if (Active(node) == false) return; // Couple of useful variables. float onePercent = (100.0f / (float)node.LifeTime); float duration = (_effectDuration.Finish - _effectDuration.Start); float expired = (onePercent * (float)node.ExpiredLife) - _effectDuration.Start; // Color the particle int rRand = _colorTintRedRandom.Minimum + (int)((_colorTintRedRandom.Maximum - _colorTintRedRandom.Minimum) * node.RandomNumbers[2]); int gRand = _colorTintGreenRandom.Minimum + (int)((_colorTintGreenRandom.Maximum - _colorTintGreenRandom.Minimum) * node.RandomNumbers[3]); int bRand = _colorTintBlueRandom.Minimum + (int)((_colorTintBlueRandom.Maximum - _colorTintBlueRandom.Minimum) * node.RandomNumbers[4]); int aRand = _colorTintAlphaRandom.Minimum + (int)((_colorTintAlphaRandom.Maximum - _colorTintAlphaRandom.Minimum) * node.RandomNumbers[5]); int r = (int)(_colorTint.Start.R + (((_colorTint.Finish.R - _colorTint.Start.R) / duration) * expired)); int g = (int)(_colorTint.Start.G + (((_colorTint.Finish.G - _colorTint.Start.G) / duration) * expired)); int b = (int)(_colorTint.Start.B + (((_colorTint.Finish.B - _colorTint.Start.B) / duration) * expired)); int a = (int)(_colorTint.StartAlpha + (((_colorTint.FinishAlpha - _colorTint.StartAlpha) / duration) * expired)); node.Color = ColorMethods.CombineColor(ColorFormats.A8R8G8B8, MathMethods.Restrict(r + rRand, 0, 255), MathMethods.Restrict(g + gRand, 0, 255), MathMethods.Restrict(b + bRand, 0, 255), MathMethods.Restrict(a + aRand, 0, 255)); }
/// <summary> /// Applies this modifiers effect to the given particle node. /// </summary> /// <param name="node">Node to apply effect to.</param> /// <param name="deltaTime">Time elapsed since last frame.</param> public override void Apply(ParticleNode node, float deltaTime) { // Check that we are active on this particle. if (Active(node) == false) return; // Couple of useful variables. float onePercent = (100.0f / (float)node.LifeTime); float duration = (_effectDuration.Finish - _effectDuration.Start); float expired = (onePercent * (float)node.ExpiredLife) - _effectDuration.Start; if (_animationMode == AnimationModifierMode.Loop) node.Frame = _frames.Start + ((((int)expired) / _frameDelay) % (_frames.Finish - _frames.Start)); else if (_animationMode == AnimationModifierMode.OneShot) node.Frame = _frames.Start + (int)(((_frames.Finish - _frames.Start) / duration) * expired); }
/// <summary> /// Applies this modifiers effect to the given particle node. /// </summary> /// <param name="node">Node to apply effect to.</param> /// <param name="deltaTime">Time elapsed since last frame.</param> public override void Apply(ParticleNode node, float deltaTime) { // Check that we are active on this particle. if (Active(node) == false) return; // Couple of useful variables. float onePercent = (100.0f / (float)node.LifeTime); float duration = (_effectDuration.Finish - _effectDuration.Start); float expired = (onePercent * (float)node.ExpiredLife) - _effectDuration.Start; float xRand = _xAccelerationRandom.Minimum + ((_xAccelerationRandom.Maximum - _xAccelerationRandom.Minimum) * node.RandomNumbers[0]); float yRand = _yAccelerationRandom.Minimum + ((_yAccelerationRandom.Maximum - _yAccelerationRandom.Minimum) * node.RandomNumbers[1]); // Move the particle. float accX = (float)(_xAcceleration.Start + (((_xAcceleration.Finish - _xAcceleration.Start) / duration) * expired)); float accY = (float)(_yAcceleration.Start + (((_yAcceleration.Finish - _yAcceleration.Start) / duration) * expired)); node.Move((accX + xRand) * deltaTime, (accY + yRand) * deltaTime, 0); }
/// <summary> /// Causes this particle type to update itself. /// </summary> /// <param name="deltaTime">Time elapsed since last frame.</param> public void Think(float deltaTime) { // Find any new dead particles. ArrayList removeList = new ArrayList(); foreach (ParticleNode particle in _particles) { if (particle.IsDead == true) { particle.IsVisible = false; _deadParticles.Add(particle); _emitter.Particles.Remove(particle); removeList.Add(particle); } } foreach (ParticleNode particle in removeList) _particles.Remove(particle); // Remove dead particles from particle list. if (_deadCleanUpTimer.DurationMillisecond > 500) { _deadCleanUpTimer.Restart(); _deadParticles.Clear(); } // Create any new particles that need to be created. if (_emitTimer.DurationMillisecond > _cycleEmitRate && (_cycleCount < _maximumCycles || _maximumCycles == 0)) { _cycleEmitRate = MathMethods.Random(_emitRate.Minimum, _emitRate.Maximum); _emitTimer.Restart(); int emitCount = MathMethods.Random(_emitCount.Minimum, _emitCount.Maximum); for (int particleNumber = 0; particleNumber < emitCount; particleNumber++) { ParticleNode particle = null; // Recycle dead particle if we can. if (_deadParticles.Count > 0) { particle = (ParticleNode)_deadParticles[0]; _deadParticles.Remove(particle); particle.Reset(); } // Create a new particle as we can't recycle. if (particle == null) particle = new ParticleNode(); // Position it according to emit shape. float x = _emitter.Transformation.X; float y = _emitter.Transformation.Y; if (_emitShape == EmitShape.Circle) { float angle = MathMethods.Random(0, 360); x += ((float)Math.Sin(angle) * MathMethods.Random(0, _emitter.BoundingRectangle.Width / 2)) + (_emitter.BoundingRectangle.Width / 2); y += ((float)Math.Cos(angle) * MathMethods.Random(0, _emitter.BoundingRectangle.Height / 2)) + (_emitter.BoundingRectangle.Height / 2); } else if (_emitShape == EmitShape.Rectangle) { x += MathMethods.Random(0, _emitter.BoundingRectangle.Width); y += MathMethods.Random(0, _emitter.BoundingRectangle.Height); } // Setup some basic settings. particle.IsVisible = _emitter.IsVisible; particle.LifeTime = MathMethods.Random(_particleLifeTimeRandom.Minimum, _particleLifeTimeRandom.Maximum); particle.Position(x, y, _emitter.Transformation.Z); // Add particle to lists. _particles.Add(particle); _emitter.Particles.Add(particle); } _cycleCount++; } // Apply modifiers to all alive particles. foreach (ParticleModifier modifier in _modifiers) foreach (ParticleNode particle in _particles) modifier.Apply(particle, deltaTime); }
/// <summary> /// Applies this modifiers effect to the given particle node. /// </summary> /// <param name="node">Node to apply effect to.</param> /// <param name="deltaTime">Time elapsed since last frame.</param> public override void Apply(ParticleNode node, float deltaTime) { // Check that we are active on this particle. if (Active(node) == false) return; // Properties, properties :D. node.Image = _image; node.RenderMode = _renderMode; node.BlendMode = _blendMode; node.Text = _text; node.Font = _font; node.IsSolid = _isVisible; node.IsVisible = _isEnabled; node.Shader = _shader; }