Code archives/Graphics/Particles!
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
A simple 2d particle system complete with a useful (though a little cludged together) editor written in MaxGUI. There's a collection of particle parameters such as alpha,red,green,blue,rotation,scale & weight, and 'factor' values that adjusts each parameter over time. eg. alpha = 1 and alphafactor -1 will fade alpha from 1 to 0 over one second. alpha = 1 and alphafactor = -0.5 will fade it over two seconds. Particles are tied to an emitter, which releases particles in 'Bursts' [doBurst(x,y)]. Emitter parameters include random velocity range and number of particles per burst. To maintain consistant results over different frame rates the bursts are limited to 20 per second. So the editor results (timed to run at 20fps) will be the same as your game results no matter how often you call DoBurst. If you want to override the 20fps limit (useful if you're interpolating the emitter position during one frame), it's as simple as DoBurst(x,y,False). Screenshot: www.matibee.co.uk/temp/particles.jpg (I'm not sure how to use the code arc's, so this is an experiment!)... The editor code.. The sample code.. The 'fire.txt' emitter used in the sample point_weight=1.00000000 point_scale=1.00000000 point_scalefactor=2.00000000 point_rotationfactor=720.000000 point_velocity_min=-100.000000 point_velocity_max=100.000000 point_red=1.00000000 point_redfactor=1.00000000 point_green=1.00000000 point_greenfactor=-1.00000000 point_blue=0.000000000 point_bluefactor=0.000000000 point_alpha=0.500000000 point_alphafactor=-0.500000000 emitter_particles_per_burst=20 xhandle=8 yhandle=8 image=Particle1.tga some other emitters point_weight=10.0000000 point_scale=0.200000003 point_scalefactor=1.60000002 point_rotationfactor=600.000000 point_velocity_min=-350.000000 point_velocity_max=350.000000 point_red=1.00000000 point_redfactor=0.000000000 point_green=0.000000000 point_greenfactor=1.00000000 point_blue=0.000000000 point_bluefactor=1.00000000 point_alpha=1.00000000 point_alphafactor=-1.00000000 emitter_particles_per_burst=40 xhandle=8 yhandle=8 image=Particle1.tga point_weight=40.0000000 point_scale=1.00000000 point_scalefactor=-0.200000003 point_rotationfactor=0.000000000 point_velocity_min=1.00000000 point_velocity_max=80.0000000 point_red=1.00000000 point_redfactor=0.000000000 point_green=0.000000000 point_greenfactor=1.00000000 point_blue=1.00000000 point_bluefactor=0.000000000 point_alpha=1.00000000 point_alphafactor=-1.00000000 emitter_particles_per_burst=2 xhandle=8 yhandle=8 image=Particle1.tga point_weight=10.0000000 point_scale=1.00000000 point_scalefactor=-0.200000003 point_rotationfactor=720.000000 point_velocity_min=-1.000000000 point_velocity_max=30.0000000 point_red=1.00000000 point_redfactor=0.000000000 point_green=0.500000000 point_greenfactor=-0.500000000 point_blue=0.000000000 point_bluefactor=0.800000012 point_alpha=1.00000000 point_alphafactor=-0.600000024 emitter_particles_per_burst=2 xhandle=-2 yhandle=-2 image=Particle1.tga My .tga file can be found here www.matibee.co.uk/temp/Particle1.tga It's not the most thorough particle system in the world, but along with the editor, it might serve as a useful learning aid or start point to improve upon. Cheers Matt | |||||
Const MAX_PARTICLES_PER_EMITTER% = 600 Type Particle Field m_fAge:Float Field m_fScale:Float Field m_fRotation:Float Field m_fVelocityX:Float Field m_fVelocityY:Float Field m_fRed:Float Field m_fBlue:Float Field m_fGreen:Float Field m_fAlpha:Float Field m_fX:Float Field m_fY:Float End Type Type ParticleEmitter Field m_freeParticles:TList Field m_liveParticles:TList Field m_baseParticle:Particle Field m_fPointWeight:Float = 1.0 Field m_fScaleFactor:Float = -0.2 Field m_fRotationFactor:Float = 720.0 Field m_fVelocityMin:Float = 9.0 Field m_fVelocityMax:Float = 100.0 Field m_fRedFactor:Float = 0.0 Field m_fBlueFactor:Float = 0.0 Field m_fGreenFactor:Float = 0.0 Field m_fAlphaFactor:Float = -1.0 Field m_iParticlesPerBurst:Int = 20 Field m_Image:TImage Field m_iXHandle:Int, m_iYHandle:Int Field m_lastBurstTime:Int Function Create:ParticleEmitter( strUrl:String = "", IgnoreImage:Int = False ) Local emitter:ParticleEmitter = New ParticleEmitter emitter.m_freeParticles = New TList emitter.m_liveParticles = New TList emitter.m_baseParticle = New Particle For Local t:Int = 0 To MAX_PARTICLES_PER_EMITTER - 1 emitter.m_freeParticles.AddLast( New Particle ) Next If ( Len (strUrl) ) Local inFile:TStream = ReadFile( strUrl ) While ( inFile And Not Eof( inFile ) ) 'Debugstop Local strLine:String = ReadLine( inFile ) If ( Len(strLine) > 0 And Left( strline, 1 ) <> "'" ) Local key:String = Left( strLine, Instr( strLine, "=" ) - 1 ) Local value:String = Right( strLine, Len( strLine ) - Instr( strLine, "=" ) ) If ( key = "point_weight" ) emitter.m_fPointWeight = value.ToFloat() Else If ( key = "point_scalefactor" ) emitter.m_fScaleFactor = value.ToFloat() Else If ( key = "point_scale" ) emitter.m_baseParticle.m_fScale = value.ToFloat() Else If ( key = "point_rotationfactor" ) emitter.m_fRotationFactor = value.ToFloat() Else If ( key = "point_velocity_min" ) emitter.m_fVelocityMin = value.ToFloat() Else If ( key = "point_velocity_max" ) emitter.m_fVelocityMax = value.ToFloat() Else If ( key = "point_redfactor" ) emitter.m_fRedFactor = value.ToFloat() Else If ( key = "point_red" ) emitter.m_baseParticle.m_fRed = value.ToFloat() Else If ( key = "point_greenfactor" ) emitter.m_fGreenFactor = value.ToFloat() Else If ( key = "point_green" ) emitter.m_baseParticle.m_fGreen = value.ToFloat() Else If ( key = "point_bluefactor" ) emitter.m_fBlueFactor = value.ToFloat() Else If ( key = "point_blue" ) emitter.m_baseParticle.m_fBlue = value.ToFloat() Else If ( key = "point_alphafactor" ) emitter.m_fAlphaFactor = value.ToFloat() Else If ( key = "point_alpha" ) emitter.m_baseParticle.m_fAlpha = value.ToFloat() Else If ( key = "emitter_particles_per_burst" ) emitter.m_iParticlesPerBurst = value.ToInt() Else If ( key = "image" And Not IgnoreImage ) emitter.m_Image = LoadImage( value, FILTEREDIMAGE ) Else If ( key = "xhandle" ) emitter.m_iXHandle = value.ToInt() Else If ( key = "yhandle" ) emitter.m_iYHandle = value.ToInt() End If End If End While CloseFile ( inFile ) If emitter.m_Image SetImageHandle( emitter.m_Image, emitter.m_iXHandle, emitter.m_iYHandle ) End If Return emitter End Function Method Draw() If ( Not m_Image ) Return For Local p:Particle = EachIn m_liveParticles SetScale p.m_fScale, p.m_fScale SetRotation p.m_fRotation SetAlpha p.m_fAlpha SetColor( p.m_fRed * 255.0, p.m_fGreen * 255.0, p.m_fBlue * 255.0 ) DrawImage( m_Image, p.m_fX, p.m_fY ) Next End Method Method Update( fTime:Float ) For Local p:Particle = EachIn m_liveParticles p.m_fAlpha :+ m_fAlphaFactor * fTime p.m_fScale :+ m_fScaleFactor * fTime If ( p.m_fAlpha <= 0 Or p.m_fScale <= 0 ) m_freeParticles.AddLast( p ) m_liveParticles.Remove( p ) Else p.m_fAge :+ fTime p.m_fRotation :+ m_fRotationFactor * fTime p.m_fX :+ p.m_fVelocityX * fTime p.m_fY :+ p.m_fVelocityY * fTime p.m_fVelocityX :- m_fPointWeight * fTime p.m_fVelocityY :- m_fPointWeight * fTime p.m_fY :+ m_fPointWeight * (p.m_fAge * p.m_fAge) p.m_fRed :+ m_fRedFactor * fTime p.m_fBlue :+ m_fBlueFactor * fTime p.m_fGreen :+ m_fGreenFactor * fTime End If Next Assert ( m_freeParticles.Count() + m_liveParticles.Count() = MAX_PARTICLES_PER_EMITTER ) 'ensure particles don't exist in both lists!! End Method Method DoBurst( iX:Int, iY:Int, fpsSync:Int = True ) If ( fpsSync ) Local timeNow:Int = MilliSecs() If ( timeNow - m_lastBurstTime ) >= 20 m_lastBurstTime = timeNow Else Return End If EndIf Local count:Int = m_iParticlesPerBurst For Local p:Particle = EachIn m_freeParticles MemCopy( p, m_baseParticle, SizeOf( Particle ) ) p.m_fVelocityX = m_fVelocityMin + ( RndFloat() * ( m_fVelocityMax - m_fVelocityMin ) ) p.m_fVelocityY = m_fVelocityMin + ( RndFloat() * ( m_fVelocityMax - m_fVelocityMin ) ) p.m_fX = iX p.m_fY = iY m_liveParticles.AddLast( p ) m_freeParticles.Remove( p ) count :- 1 If ( count <= 0 ) Return End If Next End Method End Type |
Comments
| ||
This is great. I'm having some good fun playing with it. Thank you. |
| ||
Really nice!. I have been playing with it and I really like it, I'm going to use it in my future games, I hopefully. I do not have MaxGui though, could you make the editor available in other ways?. |
| ||
Sure. The full download is available here... http://www.matibee.co.uk/wpsite/?p=15 |
| ||
Very nice code. Could you explain more matibee what's the ftime parameter into the update function ? Thanks ! |
| ||
The fTime parameter is a floating point delta time of your frame rate. ie 60 fps = 1/60 or 0.016666. |
| ||
Many thanks ! |
| ||
Is there a way to set a time parameter so particules are created for example during 5 seconds (particule age ?). (i use this code to create an explosion). Thanks ! |
| ||
Is there a way to set a time parameter so particules are created for example during 5 seconds (particule age ?) Not in this system. Why not store the time you last called "DoBurst", then call it again 5 seconds later. This code is more concerned with the behaviour of the particles and updating them rather than controlling the emitters. |
Code Archives Forum