Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

/include/ZE_ZBaseParticleSystem.h

Go to the documentation of this file.
00001 /*******************************************************************************
00002         This file is Part of the ZEngine Library for 2D game development.
00003                    Copyright (C) 2002, 2003 James Turk
00004 
00005                      Licensed under a BSD-style license.
00006 
00007     The maintainer of this library is James Turk (james@conceptofzero.net) 
00008      and the home of this Library is http://www.zengine.sourceforge.net
00009 *******************************************************************************/
00010 
00021 #ifndef __ze_zbaseparticlesystem_h__
00022 #define __ze_zbaseparticlesystem_h__
00023 
00024 #include "ZEngine.h"
00025 
00026 namespace ZE
00027 {
00028 
00035 class ZBaseParticle
00036 {
00037     public:
00043         virtual ~ZBaseParticle() 
00044         {}  // empty definition here, since ZBaseParticleSystem has no cpp file and this would be all that would be in it
00045 
00047         float xPos;
00049         float yPos;
00051         float energy;
00052 };
00053 
00062 template <class particleType>
00063 class ZBaseParticleSystem
00064 {
00065     protected:
00067         ZEngine *rEngine;
00069         particleType *rParticles;
00071         unsigned int rMaxParticles;
00073         unsigned int rCurParticles;
00075         unsigned int rNumParticlesPerSec;
00077         Uint32 rLastUpdate;
00079         bool rPaused;
00080 
00086         void AddParticle();
00087 
00093         virtual particleType NewParticle()=0;
00094 
00102         virtual void UpdateParticle(int index, float elapsedTime)=0;
00103 
00104     public:
00110         ZBaseParticleSystem();
00111 
00117         virtual ~ZBaseParticleSystem();
00118 
00124         virtual void Render()=0;
00125 
00132         void Emit(int numParticles);
00133 
00141         virtual void Update();
00142 
00148         void Clear();
00149 
00155         void Pause();
00156 
00162         void Unpause();
00163 
00169         void Stop();
00170 
00177         bool Paused();
00178                 
00186         void SetMaxParticles(unsigned int max);
00187 
00194         void SetRate(unsigned int rate);
00195 };
00196 
00197 //implementation//
00198 
00199 template <class particleType>
00200 void ZBaseParticleSystem<particleType>::AddParticle()
00201 {
00202     //empty space is always at end, function is private so no checking is needed (Emit does that)
00203     rParticles[rCurParticles] = NewParticle();  
00204     ++rCurParticles;
00205 }
00206 
00207 template <class particleType>
00208 ZBaseParticleSystem<particleType>::ZBaseParticleSystem()
00209 {
00210     rEngine = ZEngine::GetInstance();
00211     rParticles = NULL;
00212     rMaxParticles = rCurParticles = rNumParticlesPerSec = 0;
00213     rLastUpdate = rEngine->GetTime();
00214     rPaused = false;
00215 }
00216 
00217 template <class particleType>
00218 ZBaseParticleSystem<particleType>::~ZBaseParticleSystem()
00219 {
00220     if(rParticles)
00221         delete []rParticles;
00222 }
00223 
00224 template <class particleType>
00225 void ZBaseParticleSystem<particleType>::Emit(int numParticles)
00226 {
00227     while(numParticles > 0 && rCurParticles < rMaxParticles)
00228     {
00229         AddParticle();
00230         --numParticles;
00231     }
00232 }
00233 
00234 template <class particleType>
00235 void ZBaseParticleSystem<particleType>::Update()
00236 {
00237     float elapsed = (rEngine->GetTime()-rLastUpdate)/1000.0f;
00238     double emitAmount;
00239     static double overflow=0;
00240 
00241     if(!rPaused)
00242     {
00243         //update every particle and remove dead particles
00244         for(unsigned int i=0; i < rCurParticles; ++i)
00245         {
00246             UpdateParticle(i,elapsed);
00247             if(rParticles[i].xPos < 0 || rParticles[i].xPos > rEngine->DisplayWidth() 
00248                 || rParticles[i].yPos < 0 || rParticles[i].yPos > rEngine->DisplayHeight() || rParticles[i].energy <= 0)
00249             {
00250                 rParticles[i] = rParticles[--rCurParticles];
00251                 --i;    //go back one to process that particle
00252             }
00253         }
00254 
00255         emitAmount = elapsed*rNumParticlesPerSec;
00256         overflow += emitAmount - static_cast<int>(emitAmount); //only floating point portion of emitAmount
00257         Emit(static_cast<int>(emitAmount));
00258         if(overflow >= .95) //a little lower than one, for tolerance
00259         {
00260             Emit(1);
00261             overflow = 0;   //dump & clear overflow
00262         }
00263     }
00264 
00265     rLastUpdate = rEngine->GetTime();
00266 }
00267 
00268 
00269 template <class particleType>
00270 void ZBaseParticleSystem<particleType>::Clear()
00271 {
00272     rCurParticles = 0;
00273 }
00274 
00275 template <class particleType>
00276 void ZBaseParticleSystem<particleType>::Pause()
00277 {
00278     rPaused = true;
00279 }
00280 
00281 template <class particleType>
00282 void ZBaseParticleSystem<particleType>::Unpause()
00283 {
00284     rPaused = false;
00285 }
00286 
00287 template <class particleType>
00288 void ZBaseParticleSystem<particleType>::Stop()
00289 {
00290     Clear();
00291     Pause();
00292 }
00293 
00294 template <class particleType>
00295 bool ZBaseParticleSystem<particleType>::Paused()
00296 {
00297     return rPaused;
00298 }
00299 
00300 template <class particleType>
00301 void ZBaseParticleSystem<particleType>::SetMaxParticles(unsigned int max)
00302 {
00303     particleType *temp;
00304     unsigned int i;
00305 
00306     if(max)
00307     {
00308         if(max != rMaxParticles)    //only do this if size changed
00309         {
00310             if(rCurParticles)
00311             {
00312                 rCurParticles %= max;
00313                 //copy current particles to temp
00314                 temp = new particleType[rCurParticles];
00315                 for(i=0; i < rCurParticles; ++i)
00316                     temp[i] = rParticles[i];
00317             }
00318 
00319             //change size of rParticles
00320             if(rParticles)
00321                 delete []rParticles;
00322             rParticles = new particleType[max];
00323             rMaxParticles = max;
00324 
00325             if(rCurParticles)
00326             {
00327                 //copy particles from temp back to rParticles
00328                 for(i=0; i < rCurParticles; ++i)
00329                     rParticles[i] = temp[i];
00330 
00331                 delete []temp;
00332             }
00333         }
00334     }
00335     else
00336     {
00337         rMaxParticles = rCurParticles = 0;
00338         if(rParticles)
00339             delete []rParticles;
00340     }
00341 }
00342 
00343 template <class particleType>
00344 void ZBaseParticleSystem<particleType>::SetRate(unsigned int rate)
00345 {
00346     rNumParticlesPerSec = rate;
00347 }
00348 
00349 }   //namespace ZE
00350 
00351 #endif //__ze_zbaseparticlesystem_h__

Generated on Sun Oct 5 19:34:45 2003 for ZEngine by doxygen1.3