patterncsharpMinor
Smoke particle system
Viewed 0 times
particlesystemsmoke
Problem
Please note that I'm working on a game on Windows Phone 8 using Monogame. The game is fine (60 FPS) all the time, except when the particle system is activated. This is just a smoke particle system that begins to emit when the player jumps and stop to emit as the player is at "0" y velocity after the jump. When this particle system is activated it goes down to 20-30 FPS, which is very frustrating.
I watched my game with a profiler and it says that the bottleneck is here at the particle system, in particular with
What can I do to improve it?
The particle
```
public class Particle : IDisposable
{
public Texture2D texture_ { get; set; }
public Vector2 position_ { get; set; }
public Vector2 velocity_ { get; set; }
public float angle_ { get; set; }
public float angular_velocity_ { get; set; }
public Color color_ { get; set; }
public float scale_ { get; set; }
// The 'time to live' of the particle
public int TTL { get; set; }
private Rectangle source_rectangle_;
private Vector2 origin_;
public Particle(Texture2D texture, Vector2 position, Vector2 velocity,
float angle, float angularVelocity, Color color, float size, int ttl)
{
texture_ = texture;
position_ = position;
velocity_ = velocity;
angle_ = angle;
angular_velocity_ = angularVelocity;
color_ = color;
scale_ = size;
TTL = ttl;
source_rectangle_ = new Rectangle(0, 0, texture_.Width, texture_.Height);
origin_ = new Vector2(texture_.Width / 2, texture_.Height / 2);
}
public void Dispose()
{
}
public void Update(GameTime gameTime)
{
float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
--TTL;
position_ += velocity_ * elapsed;
angle_ += angular_velocity_ * elapsed;
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(
texture
I watched my game with a profiler and it says that the bottleneck is here at the particle system, in particular with
Update/Draw functions.What can I do to improve it?
The particle
```
public class Particle : IDisposable
{
public Texture2D texture_ { get; set; }
public Vector2 position_ { get; set; }
public Vector2 velocity_ { get; set; }
public float angle_ { get; set; }
public float angular_velocity_ { get; set; }
public Color color_ { get; set; }
public float scale_ { get; set; }
// The 'time to live' of the particle
public int TTL { get; set; }
private Rectangle source_rectangle_;
private Vector2 origin_;
public Particle(Texture2D texture, Vector2 position, Vector2 velocity,
float angle, float angularVelocity, Color color, float size, int ttl)
{
texture_ = texture;
position_ = position;
velocity_ = velocity;
angle_ = angle;
angular_velocity_ = angularVelocity;
color_ = color;
scale_ = size;
TTL = ttl;
source_rectangle_ = new Rectangle(0, 0, texture_.Width, texture_.Height);
origin_ = new Vector2(texture_.Width / 2, texture_.Height / 2);
}
public void Dispose()
{
}
public void Update(GameTime gameTime)
{
float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
--TTL;
position_ += velocity_ * elapsed;
angle_ += angular_velocity_ * elapsed;
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(
texture
Solution
I don't have a solution, but here are some tips:
Some of the tips are micro-optimizations and are totally useless in other scenarios, but they are very helpful in particle systems.
- Measuring the difference between structs and classes for particles can make a difference.
- Do not use properties for particles; use simple fields.
- Calculate values once (e.g. pass
totalsecondsto your particles, notgametime).
- Use object pooling for your particles; don't create them on the fly.
- Decide how many particles you want to support and use simple structures like arrays.
- Draw the particles manually without
spritebatch.
- Calculate everything you need at the beginning; don't create new objects.
Some of the tips are micro-optimizations and are totally useless in other scenarios, but they are very helpful in particle systems.
Context
StackExchange Code Review Q#51016, answer score: 9
Revisions (0)
No revisions yet.