public ParticleGroup CreateGroup(string name = null) { var pGroup = new ParticleGroup(this); pGroup.Name = name; pGroup.Particles.Capacity = this.ParticleCount; return(pGroup); }
public void DrawGroup(SpriteBatch sprite, ParticleGroup pGroup, Vector2 position) { if (this.Texture?.Texture == null) { return; } var textureSize = this.Texture.AtlasRect?.Size.ToVector2() ?? new Vector2(this.Texture.Texture.Width, this.Texture.Texture.Height); var rad = textureSize.Length() / (float)Math.Sqrt(2); var origin = this.Texture.Origin.ToVector2(); position += pGroup.Position; foreach (var p in pGroup.Particles) { var color = Lerp(p.StartColor, p.EndColor, p.NormalizedTime); var size = MathHelper.Lerp(p.StartSize, p.EndSize, p.NormalizedTime); var scale = size / rad; var rot = MathHelper.ToRadians(MathHelper.Lerp(p.StartSpin, p.EndSpin, p.NormalizedTime)); //重新计算alpha if (this.alphaPoints.Length > 0) { color.A = (byte)CalcAlphaFromPoints(p); } if (this.OpacityModifyRGB) { if (color.R == 0 && color.G == 0 && color.B == 0) { color.R = color.G = color.B = color.A; } else { //float alpha = color.A / 255.0f; ; //color.R = (byte)(color.R * alpha); //color.G = (byte)(color.G * alpha); //color.B = (byte)(color.B * alpha); } } var pos = p.Pos + position; sprite.Draw(this.Texture.Texture, pos, this.Texture.AtlasRect, color, rot, origin, scale, SpriteEffects.None, 0); } }
public void UpdateGroup(ParticleGroup pGroup, TimeSpan elapsed) { var time = (float)elapsed.TotalSeconds; if (pGroup.IsActive) { if (pGroup.Particles.Count < this.ParticleCount) //生成粒子 { float emitCount = this.Emitter.EmissionRate * time; var count = (int)emitCount + (this.Rand.NextPercent(emitCount % 1) ? 1 : 0); count = Math.Min(count, this.ParticleCount - pGroup.Particles.Count); for (int i = 0; i < count; i++) { var p = this.Emitter.Emit(); if (p.Life <= 0) //fix bug { continue; } pGroup.Particles.Add(p); } } //计算时间 if (this.Duration > 0) { pGroup.Time += time; if (pGroup.Time > this.Duration) { pGroup.IsActive = false; } } } //更新所有粒子 if (pGroup.Particles.Count > 0) { pGroup.Particles.ForEach(p => { p.Time += time; p.NormalizedTime = p.Life <= 0 ? 0 : (p.Time / p.Life); if (p.NormalizedTime >= 1) { return; } //更新粒子 var accDir = p.Pos; if (accDir != Vector2.Zero) //计算方向 { accDir.Normalize(); } var radial = accDir * p.RadialAcc; //法线加速度矢量 //var tangent = new Vector2(-accDir.Y, accDir.X) * p.TangentialAcc; //切线加速度矢量 var tangent = Vector2.Zero; //tangent not works in the game? var acc = this.Gravity + radial + tangent; //总加速度矢量 p.Dir += acc * time; //计算加速度 p.Pos += p.Dir * time; //计算位置 //计算旋转 p.Angle += p.RotatePerSecond * time; var rad = MathHelper.Lerp(p.StartRadius, p.EndRadius, p.NormalizedTime); if (rad > 0) { var radian = MathHelper.ToRadians(p.Angle); accDir = new Vector2((float)Math.Cos(radian), (float)Math.Sin(radian)); p.Pos += accDir * rad * time; } }); //回收粒子 pGroup.Particles.RemoveAll(p => { if (p.NormalizedTime >= 1) { this.CollectParticle(p); return(true); } else { return(false); } }); } }