/******************************************************************************* This file is Part of the ZEngine Library for 2D game development. Copyright (C) 2002-2004 James Turk Licensed under a BSD-style license. The maintainer of this library is James Turk (james@conceptofzero.net) and the home of this Library is http://www.zengine.sourceforge.net *******************************************************************************/ #ifndef __ze_zbaseparticlesystem_h__ #define __ze_zbaseparticlesystem_h__ #include "ZEngine.h" namespace ZE { class ZBaseParticle { public: virtual ~ZBaseParticle() {} // empty definition here, since ZBaseParticleSystem has no cpp file and this would be all that would be in it float xPos; float yPos; float energy; }; template class ZBaseParticleSystem { protected: ZEngine *rEngine; particleType *rParticles; unsigned int rMaxParticles; unsigned int rCurParticles; unsigned int rNumParticlesPerSec; Uint32 rLastUpdate; bool rPaused; void AddParticle(); virtual particleType NewParticle()=0; virtual void UpdateParticle(int index, float elapsedTime)=0; public: ZBaseParticleSystem(); virtual ~ZBaseParticleSystem(); virtual void Render()=0; void Emit(int numParticles); virtual void Update(); void Clear(); void Pause(); void Unpause(); void Stop(); void SetMaxParticles(unsigned int max); void SetRate(unsigned int rate); bool IsPaused(); }; //implementation// template void ZBaseParticleSystem::AddParticle() { //empty space is always at end, function is private so no checking is needed (Emit does that) rParticles[rCurParticles] = NewParticle(); ++rCurParticles; } template ZBaseParticleSystem::ZBaseParticleSystem() { rEngine = ZEngine::GetInstance(); rParticles = NULL; rMaxParticles = rCurParticles = rNumParticlesPerSec = 0; rLastUpdate = rEngine->GetTime(); rPaused = false; } template ZBaseParticleSystem::~ZBaseParticleSystem() { if(rParticles) delete []rParticles; } template void ZBaseParticleSystem::Emit(int numParticles) { while(numParticles > 0 && rCurParticles < rMaxParticles) { AddParticle(); --numParticles; } } template void ZBaseParticleSystem::Update() { float elapsed = (rEngine->GetTime()-rLastUpdate)/1000.0f; double emitAmount; static double overflow=0; if(!rPaused) { //update every particle and remove dead particles for(unsigned int i=0; i < rCurParticles; ++i) { UpdateParticle(i,elapsed); if(rParticles[i].xPos < 0 || rParticles[i].xPos > rEngine->DisplayWidth() || rParticles[i].yPos < 0 || rParticles[i].yPos > rEngine->DisplayHeight() || rParticles[i].energy <= 0) { rParticles[i] = rParticles[--rCurParticles]; --i; //go back one to process that particle } } emitAmount = elapsed*rNumParticlesPerSec; overflow += emitAmount - static_cast(emitAmount); //only floating point portion of emitAmount Emit(static_cast(emitAmount)); if(overflow >= .95) //a little lower than one, for tolerance { Emit(1); overflow = 0; //dump & clear overflow } } rLastUpdate = rEngine->GetTime(); } template void ZBaseParticleSystem::Clear() { rCurParticles = 0; } template void ZBaseParticleSystem::Pause() { rPaused = true; } template void ZBaseParticleSystem::Unpause() { rPaused = false; } template void ZBaseParticleSystem::Stop() { Clear(); Pause(); } template bool ZBaseParticleSystem::IsPaused() { return rPaused; } template void ZBaseParticleSystem::SetMaxParticles(unsigned int max) { particleType *temp; unsigned int i; if(max) { if(max != rMaxParticles) //only do this if size changed { if(rCurParticles) { rCurParticles %= max; //copy current particles to temp temp = new particleType[rCurParticles]; for(i=0; i < rCurParticles; ++i) temp[i] = rParticles[i]; } //change size of rParticles if(rParticles) delete []rParticles; rParticles = new particleType[max]; rMaxParticles = max; if(rCurParticles) { //copy particles from temp back to rParticles for(i=0; i < rCurParticles; ++i) rParticles[i] = temp[i]; delete []temp; } } } else { rMaxParticles = rCurParticles = 0; if(rParticles) delete []rParticles; } } template void ZBaseParticleSystem::SetRate(unsigned int rate) { rNumParticlesPerSec = rate; } } //namespace ZE #endif //__ze_zbaseparticlesystem_h__