|
SDLGameEngine
|
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