diff --git a/include/ZE_ZBaseParticleSystem.h b/include/ZE_ZBaseParticleSystem.h
new file mode 100755
index 0000000..9ba5c2b
--- /dev/null
+++ b/include/ZE_ZBaseParticleSystem.h
@@ -0,0 +1,276 @@
+/*******************************************************************************
+ This file is Part of the ZEngine Library for 2D game development.
+ Copyright (C) 2002, 2003 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
+*******************************************************************************/
+
+/*!
+ \file ZE_ZBaseParticleSystem.h
+ \brief Definition and implementation file for the base of the ZEngine Particle System.
+
+ Definition and implementation file for ZEngine particle system class ZBaseParticleSystem.
+ Due to problems with template classes the template implementation needs to be in the same file as the declaration.
+
$id$
+ \author James Turk
+**/
+
+#ifndef __ze_zbaseparticlesystem_h__
+#define __ze_zbaseparticlesystem_h__
+
+#include "ZEngine.h"
+
+namespace ZE
+{
+
+/*!
+ \brief Basic particle class for ZEngine particle systems.
+
+ Basic particle class, all particles used should derive from this class so that needed members are available.
+ (No default constructor is needed because NewParticle should initialize members.)
+**/
+class ZBaseParticle
+{
+ public:
+ /*!
+ \brief Virtual destructor.
+
+ Empty virtual destructor to make inheritance safe.
+ **/
+ virtual ~ZBaseParticle()
+ {} // empty definition here, since ZBaseParticleSystem has no cpp file and this would be all that would be in it
+
+ //! X Position of particle.
+ float xPos;
+ //! Y Position of particle.
+ float yPos;
+ //! Energy of particle (particles die if energy is 0).
+ float energy;
+};
+
+/*!
+ \brief Base particle system, a virtual class defining an outline for a fully functional particle system.
+
+ Virtual class providing outline of basic particle system, designed so that a working particle system can be
+ derived with minimal waste. Uses templated system to allow particle systems to work with their own types of
+ particles, the particleType template parameter must be a type that has the members of ZBaseParticle.
+ (Note: If you need a very specific particle system it's probably best to write your own fit to your needs.)
+**/
+template
+class ZBaseParticleSystem
+{
+ protected:
+ //! Pointer to ZEngine singleton.
+ ZEngine *rEngine;
+ //! Pointer to array of particles.
+ particleType *rParticles;
+ //! Maximum number of particles, and size of rParticles array.
+ unsigned int rMaxParticles;
+ //! Current number of particles.
+ unsigned int rCurParticles;
+ //! Number of particles to release per second.
+ unsigned int rNumParticlesPerSec;
+ //! Millisecond format time of last update.
+ Uint32 rLastUpdate;
+
+ /*!
+ \brief Adds a new particle.
+
+ Finds room in array with dead particle, and adds new particle using NewParticle, called by Emit.
+ **/
+ void AddParticle();
+
+ /*!
+ \brief Pure virtual function to initialize and return a new particle.
+
+ Pure virtual function, overload should set up a new particle with desired traits, called by AddParticle.
+ **/
+ virtual particleType NewParticle()=0;
+
+ /*!
+ \brief Pure virtual function to update a particle.
+
+ Pure virtual function, overload should update the particle `rParticles[index]`, called by Update.
+ \param index Index of particle in rParticles array to update.
+ \param elapsedTime Decimal portion of a second since last call.
+ **/
+ virtual void UpdateParticle(int index, float elapsedTime)=0;
+
+ public:
+ /*!
+ \brief Basic constructor for ZBaseParticleSystem.
+
+ Basic constructor for ZBaseParticle system, initializes all values to 0.
+ **/
+ ZBaseParticleSystem();
+
+ /*!
+ \brief Virtual destructor for ZBaseParticleSystem.
+
+ Virtual destructor for ZBaseParticleSystem, destroys all particles, virtual to make class inheritance-safe.
+ **/
+ virtual ~ZBaseParticleSystem();
+
+ /*!
+ \brief Pure virtual function, renders the particles.
+
+ Pure virtual so that each particle system can render it's member particles in it's own way.
+ **/
+ virtual void Render()=0;
+
+ /*!
+ \brief Emit a given number of particles.
+
+ Emits a given number of particles, will not emit particles if system is full.
+ \param numParticles Number of particles to emit.
+ **/
+ void Emit(int numParticles);
+
+ /*!
+ \brief Updates status of particle system.
+
+ Updates entire particle system, calling update on every particle, emitting necessary new
+ particles, removing particles which have an energy <= 0 or are off the screen.
+ **/
+ void Update();
+
+ /*!
+ \brief Sets max particles allowed in system.
+
+ Set maximum number of particles allowed in system, particles are not emitted when system is full.
+ When this resizes the array contents are moved to the new array, if it shrinks the array particles may be lost.
+ \param max Maximum number of particles for system.
+ **/
+ void SetMaxParticles(int max);
+
+ /*!
+ \brief Sets release rate of particles.
+
+ Set number of particles to release per second.
+ \param rate Number of particles to release over the duration of one second.
+ **/
+ void SetRate(int rate);
+};
+
+//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();
+}
+
+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;
+
+ //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->Width()
+ || rParticles[i].yPos < 0 || rParticles[i].yPos > rEngine->Height() || rParticles[i].energy <= 0)
+ {
+ rParticles[i] = rParticles[--rCurParticles];
+ --i; //go back one to process that particle
+ }
+ }
+
+ rLastUpdate = rEngine->GetTime();
+
+ 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
+ }
+}
+
+template
+void ZBaseParticleSystem::SetMaxParticles(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(int rate)
+{
+ rNumParticlesPerSec = rate;
+}
+
+} //namespace ZE
+
+#endif //__ze_zbaseparticlesystem_h__
diff --git a/include/ZE_ZSimpleParticleSystem.h b/include/ZE_ZSimpleParticleSystem.h
new file mode 100755
index 0000000..8b1a2c0
--- /dev/null
+++ b/include/ZE_ZSimpleParticleSystem.h
@@ -0,0 +1,390 @@
+/*******************************************************************************
+ This file is Part of the ZEngine Library for 2D game development.
+ Copyright (C) 2002, 2003 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
+*******************************************************************************/
+
+/*!
+ \file ZE_ZSimpleParticleSystem.h
+ \brief Definition and implementation file for a simple particle system for ZEngine.
+
+ Definition and implementation file for ZEngine simple particle system, ZSimpleParticleSystem based on ZBaseParticleSystem.
+ Due to problems with template classes the template implementation needs to be in the same file as the declaration.
+
$id$
+ \author James Turk
+**/
+
+#ifndef __ze_zsimpleparticlesystem_h__
+#define __ze_zsimpleparticlesystem_h__
+
+#include "ZEngine.h"
+
+namespace ZE
+{
+
+/*!
+ \brief Simple particle class for ZSimpleParticleSystem.
+
+ General purpose particle, contains needed variables for a functional particle system.
+**/
+class ZSimpleParticle : public ZBaseParticle
+{
+ public:
+ //! Previous X position of particle.
+ float xPrev;
+ //! Previous Y position of particle.
+ float yPrev;
+ //! X Velocity of particle per second.
+ float xVel;
+ //! Y Velocity of particle per second.
+ float yVel;
+ //! Energy change per second.
+ float energyDelta;
+ //! Size of particle.
+ float size;
+ //! Size change per second.
+ float sizeDelta;
+ //! Red component of particle color.
+ Uint8 r;
+ //! Green component of particle color.
+ Uint8 g;
+ //! Blue component of particle color.
+ Uint8 b;
+ //! Alpha component of particle color.
+ Uint8 a;
+};
+
+/*!
+ \brief Possible draw styles for ZSimpleParticleSystem.
+
+ Possible draw styles for ZSimpleParticleSystem, each specifies different code with which the particles will be drawn.
+**/
+enum ParticleDrawStyle
+{
+ DS_POINT, /*!< Draw particles as simple points. */
+ DS_LINE, /*!< Draw particles as lines between the current position and the last. */
+ DS_IMAGE /*!< Draw particles as an image. */
+};
+
+/*!
+ \brief ZSimpleParticleSystem class, a simple particle system provided originally as an example.
+
+ ZSimpleParticleSystem class, example of implementation of a particle system on top of ZBaseParticleSystem base,
+ designed for flexibility and ease of use over speed. More specific, therefore even less optimized for specific
+ circumstances. Should be concidered usable but not optimal. (Although it is a great source of code for your
+ own implementations.)
+**/
+template
+class ZSimpleParticleSystem : public ZBaseParticleSystem
+{
+ protected:
+ //! Draw style, one of the three enumerated values specifying how particles will be drawn.
+ ParticleDrawStyle rStyle;
+ //! Image to draw (only used if rStyle is DS_IMAGE).
+ ZImage rImage;
+ //! Minimum X value for starting position.
+ float rMinX;
+ //! Maximum X value for starting position.
+ float rMaxX;
+ //! Minimum Y value for starting position.
+ float rMinY;
+ //! Maximum Y value for starting position.
+ float rMaxY;
+ //! Minimum X velocity, particle moves it's velocity every second.
+ float rMinXVel;
+ //! Maximum X velocity, particle moves it's velocity every second.
+ float rMaxXVel;
+ //! Minimum Y velocity, particle moves it's velocity every second.
+ float rMinYVel;
+ //! Maximum Y velocity, particle moves it's velocity every second.
+ float rMaxYVel;
+ //! Minimum starting energy. (Remember particles with energy values <= 0 are removed.)
+ float rMinEnergy;
+ //! Maximum starting energy.
+ float rMaxEnergy;
+ //! Minimum energy change per second.
+ float rMinEnergyDelta;
+ //! Maximum energy change per second.
+ float rMaxEnergyDelta;
+ //! Minimum starting size.
+ float rMinSize;
+ //! Maximum starting size.
+ float rMaxSize;
+ //! Minimum size change per second.
+ float rMinSizeDelta;
+ //! Maximum size change per second.
+ float rMaxSizeDelta;
+ //! Minimum red component of color, 0-255.
+ Uint8 rMinRed;
+ //! Maximum red component of color, 0-255.
+ Uint8 rMaxRed;
+ //! Minimum green component of color, 0-255.
+ Uint8 rMinGreen;
+ //! Maximum green component of color, 0-255.
+ Uint8 rMaxGreen;
+ //! Minimum blue component of color, 0-255.
+ Uint8 rMinBlue;
+ //! Maximum blue component of color, 0-255.
+ Uint8 rMaxBlue;
+ //! Minimum alpha of particle, 0-255.
+ Uint8 rMinAlpha;
+ //! Maximum alpha of particle, 0-255.
+ Uint8 rMaxAlpha;
+
+ /*!
+ \brief Function which creates a new particle.
+
+ Implementation of pure virtual NewParticle from ZBaseParticleSystem, creates a new particle with
+ it's members set to values between their min and max value as set by the system.
+ **/
+ virtual particleType NewParticle();
+
+ /*!
+ \brief Updates a given particle given it's index and the elapsedTime.
+
+ Implementation of pure virtual UpdateParticle from ZBaseParticleSystem, updates a given particle
+ relative to the elapsed time.
+ \param index Index of particle in rParticles array to update.
+ \param elapsedTime Decimal portion of a second since last call.
+ **/
+ virtual void UpdateParticle(int index, float elapsedTime);
+
+ public:
+ /*!
+ \brief Draws all particles.
+
+ Implementation of pure virtual Render from ZBaseParticleSystem, draws all particles in specified
+ ParticleDrawStyle.
+ **/
+ virtual void Render();
+
+ /*!
+ \brief Sets ParticleDrawStyle for this system.
+
+ Sets the method of drawing particles, point, line, or image particles.
+ \param style ParticleDrawStyle for this particle system to use.
+ **/
+ void SetDrawStyle(ParticleDrawStyle style);
+
+ /*!
+ \brief Sets image for particle system.
+
+ Sets image for particle system to use, assuming the drawing style is DS_IMAGE.
+ \brief filename Filename of image to load for the system.
+ **/
+ void SetImage(std::string filename);
+
+ /*!
+ \brief Sets the range of initial positions.
+
+ Sets the range of initial positions for a new particle.
+ \param minX Minimum X coordinate for new particles.
+ \param minY Minimum Y coordinate for new particles.
+ \param maxX Maximum X coordinate for new particles.
+ \param maxY Maximum Y coordinate for new particles.
+ **/
+ void SetPosRange(float minX, float minY, float maxX, float maxY);
+
+ /*!
+ \brief Sets range of velocities for particles.
+
+ Sets range from which a new particle obtains it's random velocity,
+ \param minXVel Minimum X velocity of a particle.
+ \param minYVel Minimum Y velocity of a particle.
+ \param maxXVel Maximum X velocity of a particle.
+ \param maxYVel Maximum Y velocity of a particle.
+ **/
+ void SetVelocityRange(float minXVel, float minYVel, float maxXVel, float maxYVel);
+
+ /*!
+ \brief Sets range of initial energy and energyDelta.
+
+ Sets the possible ranges for a particles starting energy and it's energyDelta. Particles with
+ energy less than or equal to 0 are deleted by ZBaseParticleSystem::Update.
+ \param minEnergy Minimum initial energy.
+ \param maxEnergy Maximum initial energy.
+ \param minEnergyDelta Minimum energy delta.
+ \param maxEnergyDelta Maximum energy delta.
+ **/
+ void SetEnergyRange(float minEnergy, float maxEnergy, float minEnergyDelta=0, float maxEnergyDelta=0);
+
+ /*!
+ \brief Sets range of initial size and sizeDelta.
+
+ Sets the possible ranges for a particles starting size and it's sizeDelta.
+ \param minSize Minimum initial size.
+ \param maxSize Maximum initial size.
+ \param minSizeDelta Minimum size delta.
+ \param maxSizeDelta Maximum size delta.
+ **/
+ void SetSizeRange(float minSize, float maxSize, float minSizeDelta=0, float maxSizeDelta=0);
+
+ /*!
+ \brief Set range of color for a new particle.
+
+ Sets range of possible colors, by component, for a new particle.
+ \param minRed Minimum value of red component (0-255).
+ \param maxRed Minimum value of red component (0-255).
+ \param minGreen Minimum value of green component (0-255).
+ \param maxGreen Minimum value of green component (0-255).
+ \param minBlue Minimum value of blue component (0-255).
+ \param maxBlue Minimum value of blue component (0-255).
+ \param minAlpha Minimum value of alpha value (0-255).
+ \param maxAlpha Minimum value of alpha value (0-255).
+ **/
+ void SetColorRange(Uint8 minRed, Uint8 maxRed, Uint8 minGreen, Uint8 maxGreen,
+ Uint8 minBlue, Uint8 maxBlue, Uint8 minAlpha, Uint8 maxAlpha);
+};
+
+//implementation//
+
+template
+particleType ZSimpleParticleSystem::NewParticle()
+{
+ particleType p;
+
+ p.xPrev = p.xPos = rEngine->Rand(rMinX,rMaxX);
+ p.yPrev = p.yPos = rEngine->Rand(rMinY,rMaxY);
+ p.xVel = rEngine->Rand(rMinXVel,rMaxXVel);
+ p.yVel = rEngine->Rand(rMinYVel,rMaxYVel);
+ p.energy = rEngine->Rand(rMinEnergy,rMaxEnergy);
+ p.energyDelta = rEngine->Rand(rMinEnergyDelta,rMaxEnergyDelta);
+ p.size = rEngine->Rand(rMinSize,rMaxSize);
+ p.sizeDelta = rEngine->Rand(rMinSizeDelta,rMaxSizeDelta);
+ p.r = rEngine->Rand(rMinRed,rMaxRed);
+ p.g = rEngine->Rand(rMinGreen,rMaxGreen);
+ p.b = rEngine->Rand(rMinBlue,rMaxBlue);
+ p.a = rEngine->Rand(rMinAlpha,rMaxAlpha);
+
+ return p;
+}
+
+template
+void ZSimpleParticleSystem::UpdateParticle(int index, float elapsedTime)
+{
+ rParticles[index].xPrev = rParticles[index].xPos;
+ rParticles[index].yPrev = rParticles[index].yPos;
+ rParticles[index].xPos += rParticles[index].xVel*elapsedTime;
+ rParticles[index].yPos += rParticles[index].yVel*elapsedTime;
+ rParticles[index].size += rParticles[index].sizeDelta*elapsedTime;
+ rParticles[index].energy += rParticles[index].energyDelta*elapsedTime;
+}
+
+template
+void ZSimpleParticleSystem::Render()
+{
+ switch(rStyle)
+ {
+ case DS_POINT:
+ glBindTexture(GL_TEXTURE_2D,0);
+ for(unsigned int i=0; i < rCurParticles; i++)
+ {
+ glPointSize(rParticles[i].size);
+ glBegin(GL_POINTS);
+ glColor4ub(rParticles[i].r,rParticles[i].g,rParticles[i].b,rParticles[i].a);
+ glVertex2f(rParticles[i].xPos,rParticles[i].yPos);
+ glEnd();
+ }
+ break;
+ case DS_LINE:
+ glBindTexture(GL_TEXTURE_2D,0);
+ for(unsigned int i=0; i < rCurParticles; i++)
+ {
+ glLineWidth(rParticles[i].size);
+ glBegin(GL_LINES);
+ glColor4ub(rParticles[i].r,rParticles[i].g,rParticles[i].b,rParticles[i].a);
+ glVertex2f(rParticles[i].xPos,rParticles[i].yPos);
+ glVertex2f(rParticles[i].xPrev,rParticles[i].yPrev);
+ glEnd();
+ }
+ break;
+ case DS_IMAGE:
+ float x,y,size;
+ rImage.Bind();
+ glBegin(GL_QUADS);
+ for(unsigned int i=0; i < rCurParticles; i++)
+ {
+ x = rParticles[i].xPos;
+ y = rParticles[i].yPos;
+ size = rParticles[i].size;
+
+ glColor4ub(rParticles[i].r,rParticles[i].g,rParticles[i].b,rParticles[i].a);
+ glTexCoord2f(0,1); glVertex2f(x,y);
+ glTexCoord2f(1,1); glVertex2f(x+size,y);
+ glTexCoord2f(0,1); glVertex2f(x+size,y-size);
+ glTexCoord2f(0,0); glVertex2f(x,y-size);
+ }
+ glEnd();
+ break;
+ }
+}
+
+template
+void ZSimpleParticleSystem::SetDrawStyle(ParticleDrawStyle style)
+{
+ rStyle = style;
+}
+
+template
+void ZSimpleParticleSystem::SetImage(std::string filename)
+{
+ rImage.Open(filename);
+}
+
+template
+void ZSimpleParticleSystem::SetPosRange(float minX, float minY, float maxX, float maxY)
+{
+ rMinX = minX;
+ rMaxX = maxX;
+ rMinY = minY;
+ rMaxY = maxY;
+}
+
+template
+void ZSimpleParticleSystem::SetVelocityRange(float minXVel, float minYVel, float maxXVel, float maxYVel)
+{
+ rMinXVel = minXVel;
+ rMaxXVel = maxXVel;
+ rMinYVel = minYVel;
+ rMaxYVel = maxYVel;
+}
+
+template
+void ZSimpleParticleSystem::SetEnergyRange(float minEnergy, float maxEnergy, float minEnergyDelta, float maxEnergyDelta)
+{
+ rMinEnergy = minEnergy;
+ rMaxEnergy = maxEnergy;
+ rMinEnergyDelta = minEnergyDelta;
+ rMaxEnergyDelta = maxEnergyDelta;
+}
+
+template
+void ZSimpleParticleSystem::SetSizeRange(float minSize, float maxSize, float minSizeDelta, float maxSizeDelta)
+{
+ rMinSize = minSize;
+ rMaxSize = maxSize;
+ rMinSizeDelta = minSizeDelta;
+ rMaxSizeDelta = maxSizeDelta;
+}
+
+template
+void ZSimpleParticleSystem::SetColorRange(Uint8 minRed, Uint8 maxRed, Uint8 minGreen, Uint8 maxGreen,
+ Uint8 minBlue, Uint8 maxBlue, Uint8 minAlpha, Uint8 maxAlpha)
+{
+ rMinRed = minRed;
+ rMaxRed = maxRed;
+ rMinGreen = minGreen;
+ rMaxGreen = maxGreen;
+ rMinBlue = minBlue;
+ rMaxBlue = maxBlue;
+ rMinAlpha = minAlpha;
+ rMaxAlpha = maxAlpha;
+}
+
+} //namespace ZE
+
+#endif //__ze_zsimpleparticlesystem_h__
diff --git a/include/ZEngine.h b/include/ZEngine.h
index 426e5c9..fb50486 100644
--- a/include/ZEngine.h
+++ b/include/ZEngine.h
@@ -4,7 +4,7 @@
Header file for ZEngine Game Engine from Concept of Zero, this is the file that programs that wish to
utilize ZEngine should include.
-
$Id: ZEngine.h,v 1.26 2003/05/13 01:30:51 cozman Exp $
+
$Id: ZEngine.h,v 1.27 2003/07/10 19:19:19 cozman Exp $
\author James Turk
**/
@@ -27,7 +27,7 @@
to have no leaks.
-The ZEngine website : http://zengine.sourceforge.net/.
-The ZEngine tutorials : http://conceptofzero.net/tutorials/zengine/.
- -The ZEngine forums : http://www.conceptofzero.net/forums/index.php?act=SF&f=15
+ -The ZEngine forums : http://www.conceptofzero.net/index.php?name=PNphpBB2&file=viewforum&f=4
\section Licensing Licensing
@@ -57,6 +57,9 @@
#include "ZE_ZTimer.h"
#include "ZE_ZConfigFile.h"
#include "ZE_ZRect.h"
+#include "ZE_ZRandGen.h"
+#include "ZE_ZBaseParticleSystem.h"
+#include "ZE_ZSimpleParticleSystem.h"
#ifdef USE_SDL_TTF
#include "ZE_ZFont.h"
#endif