Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Recently I started designing a particle system for a game I develop. But I have some issues with it. I mean, it works but I have a feeling that my design isn't good enough.

So, basically I have a Particle class which contains the particle's vars and couple of functions:

class OBJECTATTRIBUTE_API Particle
{
protected:
     Vector3d position;
     Vector3d direction;
     Vector3d gravity;

     float life;
     float fade;

     float red;
     float green;
     float blue;

     bool isActive;
     bool isInit;

public:
     void Deinitialize();

     void SetPosition(Vector3d position);

     bool IsActive();
};

And I derive from that class the types of particles. Like this:

class OBJECTATTRIBUTE_API ParticleExplosion : public Particle
{
public:
    void Initialize();

    void Update();
    void Render();

    void Rejuvenate();
};

And at the end is the emitter. This is actually where I think my design fails. I make an emitter for every particle system and, at some point, I may have too much different emitters.

Here is an example of the particle emitter realisation:

// The base class
class OBJECTATTRIBUTE_API ParticleEmitter
{
protected:
    Vector3d emitterPosition;

    unsigned int particleTextureID;
    unsigned int particleCount;
    bool isEmitterStopped;

public:
    ParticleEmitter();
    ParticleEmitter(Vector3d emitterPosition);
};

// The derived emitter.
class OBJECTATTRIBUTE_API ParticleEmitter_Explosion : public ParticleEmitter
{
private:
   ParticleExplosion *particles;

public:
   void AddParticles(unsigned int particleCount);

   void Initialize();

   void Start();
   void Stop();

   void Reposition(Vector3d newPosition);
   void SetParticleTextureID(unsigned int particleTextureID);
};

And the question - Is my particle system design good? If not, what can I do to improve it?

EDIT : I was told that the question was too subjective, so I will try to add couple of specifications.

Firstly, I started making the particle system for explosion simulation and also some attack animations in my game. It works very well with that, so I think this goal is achieved.

Secondly, the performance hit is acceptable and I am OK with that.

And finally, the question was about is this design good for flexible adding of new particle effects implementation?

share|improve this question
    
What makes you think your system is not good? It does work and follows common OOP guidelines. You're concerned about having multiple emitters, but... how would you do it otherwise? One emitter with multiple emission points? Why would you want that? –  kaoD Feb 17 '12 at 13:54
    
Well, I thought of making one emitter class and define the particles in it like that: Particle *particles. After that the particle type is set by the user and we have one emitter class for multiple purposes. I left that idea because it was not so flexible(maybe we want a different emitter to do different things and so on). –  Tsvetan Feb 17 '12 at 14:00
    
It all depends on what your end-goal is. Is it efficient enough that you can get as many particles on the screen as you need without a performance hit? Does it look good? If it meets those two criteria I would say that you're fine. –  Nic Foster Feb 17 '12 at 15:08
    
Well, I get a performance hit at about 100k particles(+- 10k), but I don't need so many of them, so I am OK with that. And yes, it looks good. So, I guess the design is OK. –  Tsvetan Feb 17 '12 at 15:12
1  
Definitely add a virtual destructor to the base classes –  Maik Semder Feb 18 '12 at 16:23
show 4 more comments

1 Answer

up vote 1 down vote accepted

I would decouple the particle type from a specific emitter. Have a base emitter and have it work with different particles.

For instance you can derive a SprayEmitter class deriving ParticleEmitter and you pass it the particles you want it to work with. The emitter can then call Set position on the particles to move them where you want them e.t.c.

Essentially the Emitter takes care of how particles are emitted regardless of their concrete type and the particles are only concerned about updating themselves.

I guess the above would be best achieved using a function pointer in the emitter with the signature to return an abstract particle. You can have a class sitting above the emitter that will pass it a function that creates a particular concrete particle so when you call AddParticles you can call this createParticle function and add the return to your array of particles in the emitter.

share|improve this answer
    
Would't that slow the process or be too complex? I mean, isn't it simpler to know the concrete type at the beginning and not bother finding it out later? –  Tsvetan Feb 17 '12 at 14:27
    
The reason why you would do something like above is to make your code more flexible. The overheads of using a function pointer is probably insignificant in the grand scheme of things. You should only look to optimize if you run into performance problems later on. In terms of being too complex, I would argue it is simpler than creating a set of different emitters for each particle. If you have 2 emitters, say one which shoots forward and one that shoots backwards and 2 particles (red and blue) you would have 6 vs 4 concretes. Scaling it up though you would have 12 vs 8 for 6 particles. –  Jkh2 Feb 17 '12 at 14:49
    
Furthermore it would allow you to easily switch things around. Having only the concrete implementation would mean you would have to create a new emitter class if you wanted a new particle type to share the same emitter functionality of an existing emitter. Using the function pointer you can simply instantiate am existing emitter type with a pointer to the function to create your new particle –  Jkh2 Feb 17 '12 at 14:51
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.