SDLGameEngine

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

# src/sgeparticles.c

    00001 /*
    00002  * Copyright (c) 2007 Heiko Irrgang
    00003  *
    00004  * The license and distribution terms for this file may be
    00005  * found in the file COPYING in this distribution or at
    00006  * http://93-interactive.com/cms/products/software/sdl-game-engine/license/
    00007  */
    00008
    00009 #include <sge.h>
    00010
    00011 SGEPARTICLES *sgeParticlesNew(
    00012                 void *(*createFunction)(void *),
    00013                 Uint32 (*drawFunction)(Uint32, void *),
    00014                 void (*freeFunction)(Uint32, void *)
    00015 ) {
    00016         SGEPARTICLES *ret;
    00017         sgeNew(ret, SGEPARTICLES);
    00018         ret->runtime=0;
    00019         ret->particles=sgeAutoArrayNew(freeFunction);
    00020         ret->timeToLive=100;
    00021         ret->timeToLiveDistribution=50;
    00022         ret->infinite=0;
    00023         ret->angle=0;
    00024         ret->angleDistribution=20;
    00025         ret->gravity=.2;
    00026         ret->emission=20;
    00027         ret->emissionDistribution=10;
    00028         ret->internalEmission=0;
    00029         ret->speed=1;
    00030         ret->speedDistribution=.2;
    00031         ret->create=createFunction;
    00032         ret->draw=drawFunction;
    00033         ret->drawSurface=screen;
    00034         ret->x=0;
    00035         ret->y=0;
    00036         ret->custom=NULL;
    00037         ret->customDestroy=NULL;
    00038         return ret;
    00039 }
    00040
    00041 void sgeParticlesDestroy(SGEPARTICLES *p) {
    00042         sgeArrayDestroy(p->particles);
    00043         if (p->customDestroy!=NULL) {
    00044                 (p->customDestroy(p->custom));
    00045         }
    00046         sgeFree(p);
    00047 }
    00048
    00049 void sgeParticlesDraw(SGEPARTICLES *p) {
    00050         Uint32 i;
    00051         float emission;
    00052         p->runtime++;
    00053         emission=sgeParticlesGetNewEmission(p);
    00054         for (i=0;i<(int)emission;i++) {
    00055                 sgeArrayAdd(p->particles, (void *)(p->create)((void *)p));
    00056         }
    00057         for (i=0;i<p->particles->numberOfElements;i++) {
    00058                 i=(p->draw)(i, (void *)p);
    00059         }
    00060 }
    00061
    00062 float sgeParticlesGetNewEmission(SGEPARTICLES *p) {
    00063         if (p->emission<1) {
    00064                 p->internalEmission+=p->emission;
    00065                 if (p->internalEmission>1) {
    00066                         p->internalEmission-=1;
    00067                         return 1;
    00068                 }
    00069                 return 0;
    00070         }
    00071         if (p->emissionDistribution!=0) {
    00072                 return p->emission+sgeRandomFloat(-(p->emissionDistribution/2),(p->emissionDistribution));
    00073         }
    00074         return p->emission;
    00075 }
    00076
    00077 Uint32 sgeParticlesGetNewTimeToLive(SGEPARTICLES *p) {
    00078         if (p->timeToLiveDistribution!=0) {
    00079                 Sint32 tmp;
    00080                 tmp=p->timeToLive+sgeRandom(-(p->timeToLiveDistribution>>1),(p->timeToLiveDistribution));
    00081                 if (tmp>=0) return tmp;
    00082                 return 0;
    00083         }
    00084         return p->timeToLive;
    00085 }
    00086
    00087 float sgeParticlesGetNewSpeed(SGEPARTICLES *p) {
    00088         if (p->speedDistribution!=0) {
    00089                 return p->speed+sgeRandomFloat(-p->speedDistribution/2,p->speedDistribution);
    00090         }
    00091         return p->speed;
    00092 }
    00093
    00094 float sgeParticlesGetNewAngle(SGEPARTICLES *p) {
    00095         if (p->angleDistribution!=0) {
    00096                 return p->angle+sgeRandomFloat(-p->angleDistribution/2,p->angleDistribution);
    00097         }
    00098         return p->angle;
    00099 }
    00100
    00101 inline float sgeParticlesGetNewX(float x, float angle, float speed) {
    00102         return x+cos(M_PI/180*angle)*speed;
    00103 }
    00104
    00105 inline float sgeParticlesGetNewY(float y, float angle, float speed, float gravity) {
    00106         return y+sin(M_PI/180*angle)*speed+gravity;
    00107 }
    00108
    00109 void *sgePixelParticleNew(void *p) {
    00110         SGEPIXELPARTICLE *ret;
    00111         SGEPARTICLES *pp=(SGEPARTICLES *)p;
    00112         SGEPIXELPARTICLEDATA *data=pp->custom;
    00113         Uint8 r,g,b;
    00114         sgeNew(ret, SGEPIXELPARTICLE);
    00115         ret->x=(float)pp->x;
    00116         ret->y=(float)pp->y;
    00117         ret->speed=sgeParticlesGetNewSpeed(pp);
    00118         ret->angle=sgeParticlesGetNewAngle(pp);
    00119         ret->timeToLive=sgeParticlesGetNewTimeToLive(pp);
    00120         r=MIN(data->r1,data->r2)+sgeRandom(0,MAX(data->r2,data->r1)-MIN(data->r2,data->r1));
    00121         g=MIN(data->g1,data->g2)+sgeRandom(0,MAX(data->g2,data->g1)-MIN(data->g2,data->g1));
    00122         b=MIN(data->b1,data->b2)+sgeRandom(0,MAX(data->b2,data->b1)-MIN(data->b2,data->b1));
    00123         ret->color=sgeMakeColor(screen,r,g,b,0xff);
    00124         ret->gravity=0;
    00125         return ret;
    00126 }
    00127
    00128 void sgePixelParticleDestroy(Uint32 arrayidx, void *particle) {
    00129         SGEPIXELPARTICLE *p=(SGEPIXELPARTICLE *)particle;
    00130         sgeFree(p);
    00131 }
    00132
    00133 Uint32 sgePixelParticleDraw(Uint32 arrayidx, void *p) {
    00134         SGEPARTICLES *pp=(SGEPARTICLES *)p;
    00135         SGEPIXELPARTICLE *particle=sgeArrayGet(pp->particles, arrayidx);
    00136
    00137         if (pp->infinite==0) {
    00138                 if (particle->timeToLive<1) {
    00139                         sgeArrayRemove(pp->particles, arrayidx);
    00140                         return arrayidx-1;
    00141                 } else {
    00142                         particle->timeToLive--;
    00143                 }
    00144         }
    00145         particle->gravity+=pp->gravity;
    00146         particle->x=sgeParticlesGetNewX(particle->x, particle->angle, particle->speed);
    00147         particle->y=sgeParticlesGetNewY(particle->y, particle->angle, particle->speed, particle->gravity);
    00148
    00149         sgeDrawPixel(pp->drawSurface, (int)particle->x, (int)particle->y, particle->color);
    00150         return arrayidx;
    00151 }
    00152
    00153 void sgeParticlesPixelCustomDestroy(void *data) {
    00154         SGEPIXELPARTICLEDATA *d=(SGEPIXELPARTICLEDATA *)data;
    00155         sgeFree(d);
    00156 }
    00157
    00158 SGEPARTICLES *sgeParticlesPixelNew(Uint8 r1, Uint8 g1, Uint8 b1, Uint8 r2, Uint8 g2, Uint8 b2) {
    00159         SGEPIXELPARTICLEDATA *data;
    00160         SGEPARTICLES *ret=sgeParticlesNew(
    00161                         sgePixelParticleNew,
    00162                         sgePixelParticleDraw,
    00163                         sgePixelParticleDestroy
    00164         );
    00165         sgeNew(data, SGEPIXELPARTICLEDATA);
    00166         data->r1=r1;
    00167         data->g1=g1;
    00168         data->b1=b1;
    00169         data->r2=r2;
    00170         data->g2=g2;
    00171         data->b2=b2;
    00172         ret->custom=(void *)data;
    00173         ret->customDestroy=sgeParticlesPixelCustomDestroy;
    00174         return ret;
    00175 }
    00176
    00177 SGEPARTICLES *sgeParticlesSpriteNew(SGESPRITE *sprite) {
    00178         SGESPRITEPARTICLEDATA *data;
    00179         SGEPARTICLES *ret=sgeParticlesNew(
    00180                         sgeSpriteParticleNew,
    00181                         sgeSpriteParticleDraw,
    00182                         sgeSpriteParticleDestroy
    00183         );
    00184         sgeNew(data, SGESPRITEPARTICLEDATA);
    00185         data->sprite=sprite;
    00186         ret->custom=(void *)data;
    00187         ret->customDestroy=sgeParticlesSpriteCustomDestroy;
    00188         return ret;
    00189 }
    00190
    00191 void *sgeSpriteParticleNew(void *p) {
    00192         SGESPRITEPARTICLE *ret;
    00193         SGEPARTICLES *pp=(SGEPARTICLES *)p;
    00194         sgeNew(ret, SGESPRITEPARTICLE);
    00195         ret->x=(float)pp->x;
    00196         ret->y=(float)pp->y;
    00197         ret->speed=sgeParticlesGetNewSpeed(pp);
    00198         ret->angle=sgeParticlesGetNewAngle(pp);
    00199         ret->timeToLive=sgeParticlesGetNewTimeToLive(pp);
    00200         ret->gravity=0;
    00201         return ret;
    00202 }
    00203
    00204 void sgeSpriteParticleDestroy(Uint32 arrayidx, void *particle) {
    00205         SGESPRITEPARTICLE *p=(SGESPRITEPARTICLE *)particle;
    00206         sgeFree(p);
    00207 }
    00208
    00209 Uint32 sgeSpriteParticleDraw(Uint32 arrayidx, void *p) {
    00210         SGEPARTICLES *pp=(SGEPARTICLES *)p;
    00211         SGESPRITEPARTICLE *particle=sgeArrayGet(pp->particles, arrayidx);
    00212         SGESPRITEPARTICLEDATA *data=pp->custom;
    00213
    00214         if (pp->infinite==0) {
    00215                 if (particle->timeToLive<1) {
    00216                         sgeArrayRemove(pp->particles, arrayidx);
    00217                         return arrayidx-1;
    00218                 } else {
    00219                         particle->timeToLive--;
    00220                 }
    00221         }
    00222         particle->gravity+=pp->gravity;
    00223         particle->x=sgeParticlesGetNewX(particle->x, particle->angle, particle->speed);
    00224         particle->y=sgeParticlesGetNewY(particle->y, particle->angle, particle->speed, particle->gravity);
    00225
    00226         sgeSpriteDrawXY(data->sprite, (int)particle->x, (int)particle->y, pp->drawSurface);
    00227         return arrayidx;
    00228 }
    00229
    00230 void sgeParticlesSpriteCustomDestroy(void *data) {
    00231         SGESPRITEPARTICLEDATA *d=(SGESPRITEPARTICLEDATA *)data;
    00232         sgeSpriteDestroy(d->sprite);
    00233         sgeFree(d);
    00234 }
    00235

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines