Particle System
BlitzMax Forums/BlitzMax Programming/Particle System
| ||
| Hi everyone! (Full code at the bottom of the post) I started work on an RTS a little while ago and decided that it was time to make a particle system for it. Now, I've never actually made a particle system so this was a first but I kind of like the design. So, I've decided to release it. I only started it an hour or so ago so don't expect much; but that's kind of the philosophy. It's meant to be as modular as possible to allow for any modifications that you want. The way it works is through "modifiers". Particles themselves have nothing associated with them. Instead they are acted upon by modifiers that are all user defined. They can hold any kind of data that you'd like them to hold through the use of a "Data" type. Furthermore user defined emitters govern the creation of the particles themselves. Anyway, code might make it slightly easier to see so here is the underlying structure: Then, in the main loop, Graphics 800,600 While Not KeyDown(KEY_ESCAPE) Cls TModifier.UpdateAll() TEmitter.UpdateAll() Flip Wend Clearly though, this won't do anything at all! So, to make it do something useful. To start we need to add some modifiers and emitters. Lets start with making the particles able to draw and move. Lets also add an emitter that will emit particles randomly in every direction. Then a random emitter would have to be added to the main loop. It would become, Local em:TRandomEmitter = New TRandomEmitter em.x = 400 em.y = 300 em.rate = 5 While Not KeyDown(KEY_ESCAPE) Cls TModifier.UpdateAll() TEmitter.UpdateAll() Flip Wend To see how easy it is to add new modifiers let us make it so that the particles fade out. This requires four modifications: 1) The introduction of a data type to hold the alpha of the particles 2) The introduction of a type to adjust the alpha 3) Modification to the drawing type to draw with alpha 4) The addition of the fade type in the emitter The base types look like,
Type TAlpha Extends TData
Field alpha#
Method New()
name$ = "alpha"
alpha = 1.0
End Method
Function Create:TAlpha(alpha#)
Local p:TAlpha =New TAlpha
p.alpha = alpha
Return p
End Function
End Type
Type TFade Extends TModifier
Method Update(p:TParticle)
Local alpha:TAlpha = TAlpha(p.Get("alpha"))
alpha.alpha:-0.01
If alpha.alpha<0 Then p.alive = False
End Method
Method SetData(p:TParticle)
p.AddData(New TAlpha)
End Method
Method Lock()
End Method
Method Unlock()
End Method
End Type
and the updated draw type and emitter type look like,
Type TRandomEmitter Extends TEmitter
Global drawing:TDrawing = New TDrawing
Global mover:TMove = New TMove
Global culler:TCull = New TCull
Global fader:TFade = New TFade
Method Emit()
Local p:TParticle = New TParticle
p.AddData(TPosition.Create(x,y))
p.AddData(TVelocity.Create(Rnd(4)-2,Rnd(4)-2))
p.AddData(TColor.Create(Rand(255),Rand(255),Rand(255)))
p.AddData(New TAlpha)
fader.AddParticle(p)
drawing.AddParticle(p)
mover.AddParticle(p)
culler.AddParticle(p)
End Method
End Type
Type TDrawing Extends TModifier
Field blendmode
Method Update(p:TParticle)
Local pos:TPosition = TPosition(p.Get("position"))
Local col:TColor = TColor(p.Get("color"))
Local alpha:TAlpha = TAlpha(p.Get("alpha"))
If Not alpha = Null
SetAlpha alpha.alpha
EndIf
If Not col = Null
SetColor col.r,col.g,col.b
EndIf
DrawOval pos.x#-2,pos.y#-2,4,4
SetColor 255,255,255
SetAlpha 1
End Method
Method SetData(p:TParticle)
p.AddData(New TPosition)
End Method
Method Lock()
blendmode = GetBlend()
SetBlend ALPHABLEND
End Method
Method Unlock()
SetBlend blendmode
End Method
End Type
Here's all the code in one place ready to be run! Anyway, I hope someone finds this in some way useful and I'd love to hear comments/critiques on the design. |
| ||
| If anyone actually decides they might want to use this then post here and I'll write up some more formal documentation about the addition of new modifiers etc... The basic theory is that you should never have to touch any of the underlying code (that which is in the first box). |