예제 #1
0
        public static void UpdateParticle(ParticleManager <ParticleState> .Particle particle)
        {
            var velocity = particle.State.Velocity;

            particle.Position   += velocity;
            particle.Orientation = velocity.ToAngle();
            float speed = velocity.Length();
            float alpha = Math.Min(1, Math.Min(particle.PercentLife * 2, speed * 1f));

            alpha           *= alpha;
            particle.Color.A = (byte)(255 * alpha);
            particle.Scale.X = particle.State.LengthMultiplier * Math.Min(Math.Min(1f, 0.2f * speed + 0.1f), alpha);
            //particle.Scale.Y = particle.State.LengthMultiplier * Math.Min(Math.Min(1f, 0.2f * speed + 0.1f), alpha);
            //when velocity ~ 0, set it to 0;
            var pos    = particle.Position;
            int width  = (int)GameRoot.ScreenSize.X;
            int height = (int)GameRoot.ScreenSize.Y;

            // collide with the edges of the screen
            if (pos.X < 0)
            {
                velocity.X = Math.Abs(velocity.X);
            }
            else if (pos.X > width)
            {
                velocity.X = -Math.Abs(velocity.X);
            }
            if (pos.Y < 0)
            {
                velocity.Y = Math.Abs(velocity.Y);
            }
            else if (pos.Y > height)
            {
                velocity.Y = -Math.Abs(velocity.Y);
            }
            if (Math.Abs(velocity.X) + Math.Abs(velocity.Y) < 0.00000001f)
            {
                velocity = Vector2.Zero;
            }
            else if (particle.State.Type == ParticleType.Enemy)
            {
                velocity *= 0.94f;
            }
            else
            {
                velocity *= 0.96f + Math.Abs(velocity.X) % 0.04f;
            }
            if (particle.State.Type != ParticleType.IgnoreGravity)
            {
                foreach (var blackHole in EntityManager.BlackHoles)
                {
                    var   dPos     = blackHole.Position - pos;
                    float distance = dPos.Length();
                    var   n        = dPos / distance;
                    velocity += 10000 * n / (distance * distance + 10000);

                    // add tangential acceleration for nearby particles
                    if (distance < 400)
                    {
                        velocity += 45 * new Vector2(n.Y, -n.X) / (distance + 100);
                    }
                }
            }
            particle.State.Velocity = velocity;
        }
        public static void UpdateParticle(ParticleManager <ParticleState> .Particle particle)
        {
            var   vel   = particle.State.Velocity;
            float speed = vel.Length();

            // using Vector2.Add() should be slightly faster than doing "x.Position += vel;" because the Vector2s
            // are passed by reference and don't need to be copied. Since we may have to update a very large
            // number of particles, this method is a good candidate for optimizations.
            Vector2.Add(ref particle.Position, ref vel, out particle.Position);

            // fade the particle if its PercentLife or speed is low.
            float alpha = Math.Min(1, Math.Min(particle.PercentLife * 2, speed * 1f));

            alpha *= alpha;

            particle.Tint.A = (byte)(255 * alpha);

            // the length of bullet particles will be less dependent on their speed than other particles
            if (particle.State.Type == ParticleType.Bullet)
            {
                particle.Scale.X = particle.State.LengthMultiplier * Math.Min(Math.Min(1f, 0.1f * speed + 0.1f), alpha);
            }
            else
            {
                particle.Scale.X = particle.State.LengthMultiplier * Math.Min(Math.Min(1f, 0.2f * speed + 0.1f), alpha);
            }

            particle.Orientation = vel.ToAngle();

            var pos    = particle.Position;
            int width  = (int)NeonShooterGame.ScreenSize.X;
            int height = (int)NeonShooterGame.ScreenSize.Y;

            // collide with the edges of the screen
            if (pos.X < 0)
            {
                vel.X = Math.Abs(vel.X);
            }
            else if (pos.X > width)
            {
                vel.X = -Math.Abs(vel.X);
            }
            if (pos.Y < 0)
            {
                vel.Y = Math.Abs(vel.Y);
            }
            else if (pos.Y > height)
            {
                vel.Y = -Math.Abs(vel.Y);
            }

            if (particle.State.Type != ParticleType.IgnoreGravity)
            {
                foreach (var blackHole in EntityManager.BlackHoles)
                {
                    var   dPos     = blackHole.Position - pos;
                    float distance = dPos.Length();
                    var   n        = dPos / distance;
                    vel += 10000 * n / (distance * distance + 10000);

                    // add tangential acceleration for nearby particles
                    if (distance < 400)
                    {
                        vel += 45 * new Vector2(n.Y, -n.X) / (distance + 100);
                    }
                }
            }

            if (Math.Abs(vel.X) + Math.Abs(vel.Y) < 0.00000000001f)             // denormalized floats cause significant performance issues
            {
                vel = Vector2.Zero;
            }
            else if (particle.State.Type == ParticleType.Enemy)
            {
                vel *= 0.94f;
            }
            else
            {
                vel *= 0.96f + Math.Abs(pos.X) % 0.04f;                 // rand.Next() isn't thread-safe, so use the position for pseudo-randomness
            }
            particle.State.Velocity = vel;
        }