Exemple #1
0
        public ParticleGroup CreateGroup(string name = null)
        {
            var pGroup = new ParticleGroup(this);

            pGroup.Name = name;
            pGroup.Particles.Capacity = this.ParticleCount;
            return(pGroup);
        }
Exemple #2
0
        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);
            }
        }
Exemple #3
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);
                    }
                });
            }
        }