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). |