This is the code that displays particles :
// --------------------------------- //
// Project: TestParticleEmitter
// Start: Saturday, May 19, 2012
// IDE Version: 11.001
TYPE tParticle
m_fAge
m_fScale
m_fRotation
m_fVelocityX
m_fVelocityY
m_fRed
m_fBlue
m_fGreen
m_fAlpha
m_fX
m_fY
ENDTYPE
TYPE TParticleEmitter
m_freeParticles[] AS tParticle
m_liveParticles[] AS tParticle
m_strName$
m_baseParticle AS tParticle
m_fPointWeight = 1.0
m_fScaleFactor = - 0.2
m_fScaleMin = 0.5
m_fScaleMax = 1.0
m_fRotationFactor = 720.0
m_fVelocityMin = 9.0
m_fVelocityMax = 100.0
m_fRedFactor = 0.0
m_fBlueFactor = 0.0
m_fGreenFactor = 0.0
m_fAlphaFactor = -1.0
m_fMinDistance
m_fMaxDistance
m_fConeAngle = 360
m_fDirection
m_particleFile$
m_iParticlesPerBurst% = 20
m_Image% = -1
m_iWidth%;m_iHeight%
m_iXHandle%; m_iYHandle%
m_iAlphaBlend% = 1
m_lastBurstTime%
FUNCTION Initialise%:fileName$,ignoreImage%
LOCAL handle%, strLine$,key$,value$,val
self.Destroy()
DIM self.m_freeParticles[self.ReturnMaxParticles()]
IF fileName$<>""
handle%=GENFILE()
IF handle%<0 THEN RETURN FALSE
IF OPENFILE(handle%,fileName$,1)
READLINE handle%,strLine$
WHILE NOT(ENDOFFILE(handle%))
IF LEN(strLine$) > 0 AND LEFT$( strLine$, 1 ) <> "'"
key$ = LEFT$(strLine$,INSTR(strLine$,"="))
value$=RIGHT$(strLine$, LEN( strLine$ ) - INSTR( strLine$, "=" )-1)
val=value$
SELECT key$
CASE "point_weight"
self.m_fPointWeight = val
CASE "point_scalefactor"
self.m_fScaleFactor = val
CASE "point_scale"
self.m_fScaleMin = val
self.m_fScaleMax = val
CASE "point_scale_min"
self.m_fScaleMin = val
CASE "point_scale_max"
self.m_fScaleMax = val
CASE "point_rotationfactor"
self.m_fRotationFactor = val
CASE "point_coneangle"
self.m_fConeAngle = val
CASE "point_mindistance"
self.m_fMinDistance = val
CASE "point_maxdistance"
self.m_fMaxDistance = val
CASE "point_velocity_min"
self.m_fVelocityMin = val
CASE "point_velocity_max"
self.m_fVelocityMax = val
CASE "point_redfactor"
self.m_fRedFactor = val
CASE "point_red"
self.m_baseParticle.m_fRed = INTEGER(val)
CASE "point_greenfactor"
self.m_fGreenFactor = val
CASE "point_green"
self.m_baseParticle.m_fGreen = INTEGER(val)
CASE "point_bluefactor"
self.m_fBlueFactor = val
CASE "point_blue"
self.m_baseParticle.m_fBlue = INTEGER(val)
CASE "point_alphafactor"
self.m_fAlphaFactor = val
CASE "point_alpha"
self.m_baseParticle.m_fAlpha = val
CASE "emitter_particles_per_burst"
self.m_iParticlesPerBurst% = INTEGER(val)
CASE "image"
IF ignoreImage%=FALSE THEN self.LoadSpr(value$)
CASE "xhandle"
self.m_iXHandle% = INTEGER(val)
CASE "yhandle"
self.m_iYHandle% = INTEGER(val)
CASE "blendmode"
self.m_iAlphaBlend% = INTEGER(val)
ENDSELECT
ENDIF
READLINE handle%,strLine$
WEND
CLOSEFILE handle%
DEBUG "Loaded\n"
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
ENDIF
RETURN FALSE
ENDFUNCTION
FUNCTION Destroy%:
DIM self.m_liveParticles[0]
DIM self.m_freeParticles[0]
ENDFUNCTION
FUNCTION Finish%:
self.UnloadSprite()
self.Destroy()
ENDFUNCTION
FUNCTION UnloadSprite%:
IF self.m_Image%>=0 THEN LOADSPRITE "",self.m_Image%
self.m_Image%=-1
ENDFUNCTION
FUNCTION LoadSpr%:fileName$
self.m_Image%=GENSPRITE()
IF self.m_Image%>=0
self.m_particleFile$=fileName$
LOADSPRITE self.m_particleFile$,self.m_Image%
GETSPRITESIZE self.m_Image%,self.m_iWidth%,self.m_iHeight%
IF self.m_iWidth%=0 OR self.m_iHeight%=0 THEN self.m_Image%=-1
DEBUG "Sprite size : "+self.m_iWidth%+" "+self.m_iWidth%+"\n"
ENDIF
IF self.m_Image%>=0
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
ENDFUNCTION
FUNCTION Draw%:
LOCAL p AS tParticle
IF self.m_Image%=-1 THEN RETURN FALSE
FOREACH p IN self.m_liveParticles[]
ALPHAMODE ABS(p.m_fAlpha)*SGN(self.m_iAlphaBlend%-1.0)
self.z_rotozoomanim(self.m_Image%,p.m_fX,p.m_fY,self.m_iWidth%,self.m_iHeight%,p.m_fRotation,p.m_fScale, _
RGB(p.m_fRed*255.0,p.m_fGreen*255.0,p.m_fBlue*255.0))
NEXT
RETURN TRUE
ENDFUNCTION
FUNCTION Update%:fTime
LOCAL p AS tParticle
FOREACH p IN self.m_liveParticles[]
INC p.m_fAlpha,self.m_fAlphaFactor * fTime
INC p.m_fScale,self.m_fScaleFactor * fTime
IF p.m_fAlpha <= 0.0 OR p.m_fScale <= 0.0
DIMPUSH self.m_freeParticles[],p
DELETE p
ELSE
INC p.m_fAge,fTime
INC p.m_fRotation,self.m_fRotationFactor * fTime
DEC p.m_fVelocityX,self.m_fPointWeight * fTime
DEC p.m_fVelocityY,self.m_fPointWeight * fTime
INC p.m_fX,p.m_fVelocityX * fTime
INC p.m_fY,p.m_fVelocityY * fTime
INC p.m_fY,self.m_fPointWeight * (p.m_fAge * p.m_fAge)
INC p.m_fRed,self.m_fRedFactor * fTime
INC p.m_fBlue,self.m_fBlueFactor * fTime
INC p.m_fGreen,self.m_fGreenFactor * fTime
ENDIF
NEXT
//ASSERT ( m_freeParticles.Count() + m_liveParticles.Count() = MAX_PARTICLES_PER_EMITTER ) 'ensure particles don't exist IN both lists!!
ENDFUNCTION
FUNCTION SetDirection%:a
self.m_fDirection = a
DEBUG "Direction : "+self.m_fDirection+"\n"
ENDFUNCTION
FUNCTION DoBurst%:iX%,iY%,fpsSync%=TRUE
LOCAL count%
LOCAL p AS tParticle
IF fpsSync%
LOCAL timeNow%
timeNow=INTEGER(GETTIMERALL())
IF timeNow - self.m_lastBurstTime >= 20
self.m_lastBurstTime = timeNow
ELSE
RETURN FALSE
ENDIF
ENDIF
count%=self.m_iParticlesPerBurst%
WHILE BOUNDS(self.m_freeParticles[],0)<count%
DIMPUSH self.m_freeParticles[],self.m_liveParticles[0]
DIMDEL self.m_liveParticles[],0
WEND
FOREACH p IN self.m_freeParticles[]
LOCAL angle,velocity,distance
DEC count%
IF count%<0
RETURN TRUE
ENDIF
p=self.m_baseParticle
angle= (self.RndFloat()*self.m_fConeAngle)+(self.m_fDirection - ( self.m_fConeAngle / 2.0 ))
p.m_fScale = self.m_fScaleMin + (self.RndFloat()*(self.m_fScaleMax - self.m_fScaleMin ) )
velocity = self.m_fVelocityMin + (self.RndFloat()*(self.m_fVelocityMax - self.m_fVelocityMin ))
p.m_fVelocityX = COS( angle ) * velocity
p.m_fVelocityY = SIN( angle ) * velocity
distance = self.m_fMinDistance + (RndFloat()*(self.m_fMaxDistance - self.m_fMinDistance ))
p.m_fX = iX + (COS( angle ) * distance )
p.m_fY = iY + (SIN( angle ) * distance )
DIMPUSH self.m_liveParticles[],p
DELETE p
NEXT
RETURN TRUE
ENDFUNCTION
FUNCTION LiveCount%:
RETURN BOUNDS(self.m_liveParticles[],0)
ENDFUNCTION
FUNCTION RndFloat:
RETURN RND(100)/100.0
ENDFUNCTION
FUNCTION ReturnMaxParticles%:
RETURN 600
ENDFUNCTION
FUNCTION z_rotozoomanim: num%,_x,_y,w%,h%,_angle,_scale,_col%=0xFFFFFF
LOCAL sinp, cosp, spw, sph, dx, dy
LOCAL hx, hy, dxp, dxm, dyp, dym
sinp = SIN(_angle)
cosp = COS(_angle)
spw = w%-0.5
sph = h%-0.5
dx=spw/2
dy=sph/2
hx = (dx - (w%-self.m_iXHandle%))
hy = (dy - (h%-self.m_iYHandle%))
dxp = (dx+hx) * _scale
dxm = (dx-hx) * _scale
dyp = (dy+hy) * _scale
dym = (dy-hy) * _scale
STARTPOLY num%
POLYVECTOR _x - cosp * dxm - sinp * dym, _y - cosp * dym + sinp * dxm, 0.5, 0.5, _col
POLYVECTOR _x - cosp * dxm + sinp * dyp, _y + cosp * dyp + sinp * dxm, 0.5, sph, _col
POLYVECTOR _x + cosp * dxp + sinp * dyp, _y + cosp * dyp - sinp * dxp, spw, sph, _col
POLYVECTOR _x + cosp * dxp - sinp * dym, _y - cosp * dym - sinp * dxp, spw, 0.5, _col
ENDPOLY
ENDFUNCTION
ENDTYPE