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; }